Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PWA: First implementation of offline mode #2704

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
PWA: First implementation of offline mode
BhasherBEL committed Jan 2, 2025
commit 55d8ddfa4ed8eed7e546a6e6a05e8c0448a41435
1 change: 1 addition & 0 deletions client/model.go
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ type User struct {
DefaultHomePage string `json:"default_home_page"`
CategoriesSortingOrder string `json:"categories_sorting_order"`
MarkReadOnView bool `json:"mark_read_on_view"`
CacheForOffline bool `json:"cache_for_offline"`
MediaPlaybackRate float64 `json:"media_playback_rate"`
BlockFilterEntryRules string `json:"block_filter_entry_rules"`
KeepFilterEntryRules string `json:"keep_filter_entry_rules"`
5 changes: 5 additions & 0 deletions internal/database/migrations.go
Original file line number Diff line number Diff line change
@@ -969,4 +969,9 @@ var migrations = []func(tx *sql.Tx, driver string) error{
_, err = tx.Exec(sql)
return err
},
func(tx *sql.Tx, _ string) (err error) {
sql := `ALTER TABLE users ADD COLUMN cache_for_offline boolean default 'f'`
_, err = tx.Exec(sql)
return err
},
}
1,121 changes: 537 additions & 584 deletions internal/locale/translations/en_US.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions internal/model/user.go
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ type User struct {
MediaPlaybackRate float64 `json:"media_playback_rate"`
BlockFilterEntryRules string `json:"block_filter_entry_rules"`
KeepFilterEntryRules string `json:"keep_filter_entry_rules"`
CacheForOffline bool `json:"cache_for_offline"`
}

// UserCreationRequest represents the request to create a user.
@@ -82,6 +83,7 @@ type UserModificationRequest struct {
MediaPlaybackRate *float64 `json:"media_playback_rate"`
BlockFilterEntryRules *string `json:"block_filter_entry_rules"`
KeepFilterEntryRules *string `json:"keep_filter_entry_rules"`
CacheForOffline *bool `json:"cache_for_offline"`
}

// Patch updates the User object with the modification request.
@@ -197,6 +199,9 @@ func (u *UserModificationRequest) Patch(user *User) {
if u.KeepFilterEntryRules != nil {
user.KeepFilterEntryRules = *u.KeepFilterEntryRules
}
if u.CacheForOffline != nil {
user.CacheForOffline = *u.CacheForOffline
}
}

// UseTimezone converts last login date to the given timezone.
34 changes: 24 additions & 10 deletions internal/storage/user.go
Original file line number Diff line number Diff line change
@@ -96,7 +96,8 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m
mark_read_on_view,
media_playback_rate,
block_filter_entry_rules,
keep_filter_entry_rules
keep_filter_entry_rules,
cache_for_offline
`

tx, err := s.db.Begin()
@@ -140,6 +141,7 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m
&user.MediaPlaybackRate,
&user.BlockFilterEntryRules,
&user.KeepFilterEntryRules,
&user.CacheForOffline,
)
if err != nil {
tx.Rollback()
@@ -204,9 +206,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
mark_read_on_media_player_completion=$25,
media_playback_rate=$26,
block_filter_entry_rules=$27,
keep_filter_entry_rules=$28
keep_filter_entry_rules=$28,
cache_for_offline=$29
WHERE
id=$29
id=$30
`

_, err = s.db.Exec(
@@ -239,6 +242,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
user.MediaPlaybackRate,
user.BlockFilterEntryRules,
user.KeepFilterEntryRules,
user.CacheForOffline,
user.ID,
)
if err != nil {
@@ -273,9 +277,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
mark_read_on_media_player_completion=$24,
media_playback_rate=$25,
block_filter_entry_rules=$26,
keep_filter_entry_rules=$27
keep_filter_entry_rules=$27,
cache_for_offline=$28
WHERE
id=$28
id=$29
`

_, err := s.db.Exec(
@@ -307,6 +312,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
user.MediaPlaybackRate,
user.BlockFilterEntryRules,
user.KeepFilterEntryRules,
user.CacheForOffline,
user.ID,
)

@@ -360,7 +366,8 @@ func (s *Storage) UserByID(userID int64) (*model.User, error) {
mark_read_on_media_player_completion,
media_playback_rate,
block_filter_entry_rules,
keep_filter_entry_rules
keep_filter_entry_rules,
cache_for_offline
FROM
users
WHERE
@@ -401,7 +408,8 @@ func (s *Storage) UserByUsername(username string) (*model.User, error) {
mark_read_on_media_player_completion,
media_playback_rate,
block_filter_entry_rules,
keep_filter_entry_rules
keep_filter_entry_rules,
cache_for_offline
FROM
users
WHERE
@@ -442,7 +450,8 @@ func (s *Storage) UserByField(field, value string) (*model.User, error) {
mark_read_on_media_player_completion,
media_playback_rate,
block_filter_entry_rules,
keep_filter_entry_rules
keep_filter_entry_rules,
cache_for_offline
FROM
users
WHERE
@@ -490,7 +499,8 @@ func (s *Storage) UserByAPIKey(token string) (*model.User, error) {
u.mark_read_on_media_player_completion,
media_playback_rate,
u.block_filter_entry_rules,
u.keep_filter_entry_rules
u.keep_filter_entry_rules,
u.cache_for_offline
FROM
users u
LEFT JOIN
@@ -533,6 +543,7 @@ func (s *Storage) fetchUser(query string, args ...interface{}) (*model.User, err
&user.MediaPlaybackRate,
&user.BlockFilterEntryRules,
&user.KeepFilterEntryRules,
&user.CacheForOffline,
)

if err == sql.ErrNoRows {
@@ -646,7 +657,9 @@ func (s *Storage) Users() (model.Users, error) {
mark_read_on_media_player_completion,
media_playback_rate,
block_filter_entry_rules,
keep_filter_entry_rules
keep_filter_entry_rules,
media_playback_rate,
cache_for_offline
FROM
users
ORDER BY username ASC
@@ -690,6 +703,7 @@ func (s *Storage) Users() (model.Users, error) {
&user.MediaPlaybackRate,
&user.BlockFilterEntryRules,
&user.KeepFilterEntryRules,
&user.CacheForOffline,
)

if err != nil {
1 change: 1 addition & 0 deletions internal/template/templates/views/settings.html
Original file line number Diff line number Diff line change
@@ -123,6 +123,7 @@ <h1 id="page-header-title">{{ t "page.settings.title" }}</h1>
{{ if eq .form.MarkReadBehavior .const.MarkAsReadOnViewButWaitForPlayerCompletion }}checked{{end}}> {{ t "form.prefs.label.mark_read_on_view_or_media_completion" }}</label>
<label><input type="radio" name="mark_read_behavior" value="{{ .const.MarkAsReadOnlyOnPlayerCompletion }}"
{{ if eq .form.MarkReadBehavior .const.MarkAsReadOnlyOnPlayerCompletion }}checked{{end}} > {{ t "form.prefs.label.mark_read_on_media_completion" }}</label>
<label><input type="checkbox" name="cache_for_offline" value="1" {{ if .form.CacheForOffline }}checked{{ end }}> {{ t "form.prefs.label.cache_for_offline" }}</label>

<div class="buttons">
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>
4 changes: 4 additions & 0 deletions internal/ui/form/settings.go
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ type SettingsForm struct {
MediaPlaybackRate float64
BlockFilterEntryRules string
KeepFilterEntryRules string
CacheForOffline bool
}

// MarkAsReadBehavior returns the MarkReadBehavior from the given MarkReadOnView and MarkReadOnMediaPlayerCompletion values.
@@ -119,6 +120,8 @@ func (s *SettingsForm) Merge(user *model.User) *model.User {
user.MarkReadOnView = MarkReadOnView
user.MarkReadOnMediaPlayerCompletion = MarkReadOnMediaPlayerCompletion

user.CacheForOffline = s.CacheForOffline

if s.Password != "" {
user.Password = s.Password
}
@@ -205,5 +208,6 @@ func NewSettingsForm(r *http.Request) *SettingsForm {
MediaPlaybackRate: mediaPlaybackRate,
BlockFilterEntryRules: r.FormValue("block_filter_entry_rules"),
KeepFilterEntryRules: r.FormValue("keep_filter_entry_rules"),
CacheForOffline: r.FormValue("cache_for_offline") == "1",
}
}
1 change: 1 addition & 0 deletions internal/ui/settings_show.go
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ func (h *handler) showSettingsPage(w http.ResponseWriter, r *http.Request) {
MediaPlaybackRate: user.MediaPlaybackRate,
BlockFilterEntryRules: user.BlockFilterEntryRules,
KeepFilterEntryRules: user.KeepFilterEntryRules,
CacheForOffline: user.CacheForOffline,
}

timezones, err := h.store.Timezones()
Loading