Skip to content

Commit 0c1b43d

Browse files
committed
PWA: First implementation of offline mode
1 parent 3ef2522 commit 0c1b43d

File tree

11 files changed

+719
-590
lines changed

11 files changed

+719
-590
lines changed

client/model.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type User struct {
4141
DefaultHomePage string `json:"default_home_page"`
4242
CategoriesSortingOrder string `json:"categories_sorting_order"`
4343
MarkReadOnView bool `json:"mark_read_on_view"`
44+
CacheForOffline bool `json:"cache_for_offline"`
4445
MediaPlaybackRate float64 `json:"media_playback_rate"`
4546
}
4647

internal/database/migrations.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,4 +903,9 @@ var migrations = []func(tx *sql.Tx) error{
903903
_, err = tx.Exec(sql)
904904
return err
905905
},
906+
func(tx *sql.Tx) (err error) {
907+
sql := `ALTER TABLE users ADD COLUMN cache_for_offline boolean default 'f'`
908+
_, err = tx.Exec(sql)
909+
return err
910+
},
906911
}

internal/locale/translations/en_US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@
377377
"form.prefs.label.default_home_page": "Default home page",
378378
"form.prefs.label.categories_sorting_order": "Categories sorting",
379379
"form.prefs.label.mark_read_on_view": "Automatically mark entries as read when viewed",
380+
"form.prefs.label.cache_for_offline": "Cache entries for offline reading",
380381
"form.prefs.fieldset.application_settings": "Application Settings",
381382
"form.prefs.fieldset.authentication_settings": "Authentication Settings",
382383
"form.prefs.fieldset.reader_settings": "Reader Settings",

internal/model/user.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type User struct {
3636
CategoriesSortingOrder string `json:"categories_sorting_order"`
3737
MarkReadOnView bool `json:"mark_read_on_view"`
3838
MediaPlaybackRate float64 `json:"media_playback_rate"`
39+
CacheForOffline bool `json:"cache_for_offline"`
3940
}
4041

4142
// UserCreationRequest represents the request to create a user.
@@ -72,6 +73,7 @@ type UserModificationRequest struct {
7273
CategoriesSortingOrder *string `json:"categories_sorting_order"`
7374
MarkReadOnView *bool `json:"mark_read_on_view"`
7475
MediaPlaybackRate *float64 `json:"media_playback_rate"`
76+
CacheForOffline bool `json:"cache_for_offline"`
7577
}
7678

7779
// Patch updates the User object with the modification request.
@@ -167,6 +169,10 @@ func (u *UserModificationRequest) Patch(user *User) {
167169
if u.MediaPlaybackRate != nil {
168170
user.MediaPlaybackRate = *u.MediaPlaybackRate
169171
}
172+
173+
if u.CacheForOffline {
174+
user.CacheForOffline = u.CacheForOffline
175+
}
170176
}
171177

172178
// UseTimezone converts last login date to the given timezone.

internal/storage/user.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m
9292
default_home_page,
9393
categories_sorting_order,
9494
mark_read_on_view,
95-
media_playback_rate
95+
media_playback_rate,
96+
cache_for_offline
9697
`
9798

9899
tx, err := s.db.Begin()
@@ -132,6 +133,7 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m
132133
&user.CategoriesSortingOrder,
133134
&user.MarkReadOnView,
134135
&user.MediaPlaybackRate,
136+
&user.CacheForOffline,
135137
)
136138
if err != nil {
137139
tx.Rollback()
@@ -189,9 +191,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
189191
default_home_page=$20,
190192
categories_sorting_order=$21,
191193
mark_read_on_view=$22,
192-
media_playback_rate=$23
194+
media_playback_rate=$23,
195+
cache_for_offline=$24
193196
WHERE
194-
id=$24
197+
id=$25
195198
`
196199

197200
_, err = s.db.Exec(
@@ -219,6 +222,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
219222
user.CategoriesSortingOrder,
220223
user.MarkReadOnView,
221224
user.MediaPlaybackRate,
225+
user.CacheForOffline,
222226
user.ID,
223227
)
224228
if err != nil {
@@ -248,9 +252,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
248252
default_home_page=$19,
249253
categories_sorting_order=$20,
250254
mark_read_on_view=$21,
251-
media_playback_rate=$22
255+
media_playback_rate=$22,
256+
cache_for_offline=$23
252257
WHERE
253-
id=$23
258+
id=$24
254259
`
255260

256261
_, err := s.db.Exec(
@@ -277,6 +282,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
277282
user.CategoriesSortingOrder,
278283
user.MarkReadOnView,
279284
user.MediaPlaybackRate,
285+
user.CacheForOffline,
280286
user.ID,
281287
)
282288

@@ -325,7 +331,8 @@ func (s *Storage) UserByID(userID int64) (*model.User, error) {
325331
default_home_page,
326332
categories_sorting_order,
327333
mark_read_on_view,
328-
media_playback_rate
334+
media_playback_rate,
335+
cache_for_offline
329336
FROM
330337
users
331338
WHERE
@@ -361,7 +368,8 @@ func (s *Storage) UserByUsername(username string) (*model.User, error) {
361368
default_home_page,
362369
categories_sorting_order,
363370
mark_read_on_view,
364-
media_playback_rate
371+
media_playback_rate,
372+
cache_for_offline
365373
FROM
366374
users
367375
WHERE
@@ -397,7 +405,8 @@ func (s *Storage) UserByField(field, value string) (*model.User, error) {
397405
default_home_page,
398406
categories_sorting_order,
399407
mark_read_on_view,
400-
media_playback_rate
408+
media_playback_rate,
409+
cache_for_offline
401410
FROM
402411
users
403412
WHERE
@@ -440,7 +449,8 @@ func (s *Storage) UserByAPIKey(token string) (*model.User, error) {
440449
u.default_home_page,
441450
u.categories_sorting_order,
442451
u.mark_read_on_view,
443-
media_playback_rate
452+
media_playback_rate,
453+
u.cache_for_offline
444454
FROM
445455
users u
446456
LEFT JOIN
@@ -478,6 +488,7 @@ func (s *Storage) fetchUser(query string, args ...interface{}) (*model.User, err
478488
&user.CategoriesSortingOrder,
479489
&user.MarkReadOnView,
480490
&user.MediaPlaybackRate,
491+
&user.CacheForOffline,
481492
)
482493

483494
if err == sql.ErrNoRows {
@@ -586,7 +597,8 @@ func (s *Storage) Users() (model.Users, error) {
586597
default_home_page,
587598
categories_sorting_order,
588599
mark_read_on_view,
589-
media_playback_rate
600+
media_playback_rate,
601+
cache_for_offline
590602
FROM
591603
users
592604
ORDER BY username ASC
@@ -625,6 +637,7 @@ func (s *Storage) Users() (model.Users, error) {
625637
&user.CategoriesSortingOrder,
626638
&user.MarkReadOnView,
627639
&user.MediaPlaybackRate,
640+
&user.CacheForOffline,
628641
)
629642

630643
if err != nil {

internal/template/templates/views/settings.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ <h1 id="page-header-title">{{ t "page.settings.title" }}</h1>
114114
<label><input type="checkbox" name="show_reading_time" value="1" {{ if .form.ShowReadingTime }}checked{{ end }}> {{ t "form.prefs.label.show_reading_time" }}</label>
115115

116116
<label><input type="checkbox" name="mark_read_on_view" value="1" {{ if .form.MarkReadOnView }}checked{{ end }}> {{ t "form.prefs.label.mark_read_on_view" }}</label>
117+
<label><input type="checkbox" name="cache_for_offline" value="1" {{ if .form.CacheForOffline }}checked{{ end }}> {{ t "form.prefs.label.cache_for_offline" }}</label>
117118

118119
<div class="buttons">
119120
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>

internal/ui/form/settings.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type SettingsForm struct {
3434
CategoriesSortingOrder string
3535
MarkReadOnView bool
3636
MediaPlaybackRate float64
37+
CacheForOffline bool
3738
}
3839

3940
// Merge updates the fields of the given user.
@@ -57,6 +58,7 @@ func (s *SettingsForm) Merge(user *model.User) *model.User {
5758
user.CategoriesSortingOrder = s.CategoriesSortingOrder
5859
user.MarkReadOnView = s.MarkReadOnView
5960
user.MediaPlaybackRate = s.MediaPlaybackRate
61+
user.CacheForOffline = s.CacheForOffline
6062

6163
if s.Password != "" {
6264
user.Password = s.Password
@@ -133,5 +135,6 @@ func NewSettingsForm(r *http.Request) *SettingsForm {
133135
CategoriesSortingOrder: r.FormValue("categories_sorting_order"),
134136
MarkReadOnView: r.FormValue("mark_read_on_view") == "1",
135137
MediaPlaybackRate: mediaPlaybackRate,
138+
CacheForOffline: r.FormValue("cache_for_offline") == "1",
136139
}
137140
}

internal/ui/settings_show.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func (h *handler) showSettingsPage(w http.ResponseWriter, r *http.Request) {
4242
CategoriesSortingOrder: user.CategoriesSortingOrder,
4343
MarkReadOnView: user.MarkReadOnView,
4444
MediaPlaybackRate: user.MediaPlaybackRate,
45+
CacheForOffline: user.CacheForOffline,
4546
}
4647

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

0 commit comments

Comments
 (0)