Add user setting for marking entry as read on view
This commit is contained in:
parent
6046a74a64
commit
356d32c6fe
35 changed files with 84 additions and 29 deletions
|
@ -40,6 +40,7 @@ type User struct {
|
||||||
CJKReadingSpeed int `json:"cjk_reading_speed"`
|
CJKReadingSpeed int `json:"cjk_reading_speed"`
|
||||||
DefaultHomePage string `json:"default_home_page"`
|
DefaultHomePage string `json:"default_home_page"`
|
||||||
CategoriesSortingOrder string `json:"categories_sorting_order"`
|
CategoriesSortingOrder string `json:"categories_sorting_order"`
|
||||||
|
MarkReadOnView bool `json:"mark_read_on_view"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u User) String() string {
|
func (u User) String() string {
|
||||||
|
@ -78,6 +79,7 @@ type UserModificationRequest struct {
|
||||||
CJKReadingSpeed *int `json:"cjk_reading_speed"`
|
CJKReadingSpeed *int `json:"cjk_reading_speed"`
|
||||||
DefaultHomePage *string `json:"default_home_page"`
|
DefaultHomePage *string `json:"default_home_page"`
|
||||||
CategoriesSortingOrder *string `json:"categories_sorting_order"`
|
CategoriesSortingOrder *string `json:"categories_sorting_order"`
|
||||||
|
MarkReadOnView *bool `json:"mark_read_on_view"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Users represents a list of users.
|
// Users represents a list of users.
|
||||||
|
|
|
@ -702,4 +702,9 @@ var migrations = []func(tx *sql.Tx) error{
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
func(tx *sql.Tx) (err error) {
|
||||||
|
sql := `ALTER TABLE users ADD COLUMN mark_read_on_view boolean default 't'`
|
||||||
|
_, err = tx.Exec(sql)
|
||||||
|
return err
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Eintrag Sortierspalte",
|
"form.prefs.label.entry_order": "Eintrag Sortierspalte",
|
||||||
"form.prefs.label.default_home_page": "Standard Startseite",
|
"form.prefs.label.default_home_page": "Standard Startseite",
|
||||||
"form.prefs.label.categories_sorting_order": "Kategorien sortieren",
|
"form.prefs.label.categories_sorting_order": "Kategorien sortieren",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Einträge automatisch als gelesen markieren, wenn sie angezeigt werden",
|
||||||
"form.import.label.file": "OPML Datei",
|
"form.import.label.file": "OPML Datei",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Fever API aktivieren",
|
"form.integration.fever_activate": "Fever API aktivieren",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Στήλη ταξινόμησης εισόδου",
|
"form.prefs.label.entry_order": "Στήλη ταξινόμησης εισόδου",
|
||||||
"form.prefs.label.default_home_page": "Προεπιλεγμένη αρχική σελίδα",
|
"form.prefs.label.default_home_page": "Προεπιλεγμένη αρχική σελίδα",
|
||||||
"form.prefs.label.categories_sorting_order": "Ταξινόμηση κατηγοριών",
|
"form.prefs.label.categories_sorting_order": "Ταξινόμηση κατηγοριών",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Αυτόματη επισήμανση καταχωρήσεων ως αναγνωσμένων κατά την προβολή",
|
||||||
"form.import.label.file": "Αρχείο OPML",
|
"form.import.label.file": "Αρχείο OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Ενεργοποιήστε το Fever API",
|
"form.integration.fever_activate": "Ενεργοποιήστε το Fever API",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Entry sorting column",
|
"form.prefs.label.entry_order": "Entry sorting column",
|
||||||
"form.prefs.label.default_home_page": "Default home page",
|
"form.prefs.label.default_home_page": "Default home page",
|
||||||
"form.prefs.label.categories_sorting_order": "Categories sorting",
|
"form.prefs.label.categories_sorting_order": "Categories sorting",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Automatically mark entries as read when viewed",
|
||||||
"form.import.label.file": "OPML file",
|
"form.import.label.file": "OPML file",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Activate Fever API",
|
"form.integration.fever_activate": "Activate Fever API",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Columna de clasificación de artículos",
|
"form.prefs.label.entry_order": "Columna de clasificación de artículos",
|
||||||
"form.prefs.label.default_home_page": "Página de inicio por defecto",
|
"form.prefs.label.default_home_page": "Página de inicio por defecto",
|
||||||
"form.prefs.label.categories_sorting_order": "Clasificación por categorías",
|
"form.prefs.label.categories_sorting_order": "Clasificación por categorías",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Marcar automáticamente las entradas como leídas cuando se vean",
|
||||||
"form.import.label.file": "Archivo OPML",
|
"form.import.label.file": "Archivo OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Activar API de Fever",
|
"form.integration.fever_activate": "Activar API de Fever",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Lajittele sarakkeen mukaan",
|
"form.prefs.label.entry_order": "Lajittele sarakkeen mukaan",
|
||||||
"form.prefs.label.default_home_page": "Oletusarvoinen etusivu",
|
"form.prefs.label.default_home_page": "Oletusarvoinen etusivu",
|
||||||
"form.prefs.label.categories_sorting_order": "Kategorioiden lajittelu",
|
"form.prefs.label.categories_sorting_order": "Kategorioiden lajittelu",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Merkitse kohdat automaattisesti luetuiksi, kun niitä tarkastellaan",
|
||||||
"form.import.label.file": "OPML-tiedosto",
|
"form.import.label.file": "OPML-tiedosto",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Ota Fever API käyttöön",
|
"form.integration.fever_activate": "Ota Fever API käyttöön",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Colonne de tri des entrées",
|
"form.prefs.label.entry_order": "Colonne de tri des entrées",
|
||||||
"form.prefs.label.default_home_page": "Page d'accueil par défaut",
|
"form.prefs.label.default_home_page": "Page d'accueil par défaut",
|
||||||
"form.prefs.label.categories_sorting_order": "Colonne de tri des catégories",
|
"form.prefs.label.categories_sorting_order": "Colonne de tri des catégories",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Marquer automatiquement les entrées comme lues lorsqu'elles sont consultées",
|
||||||
"form.import.label.file": "Fichier OPML",
|
"form.import.label.file": "Fichier OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Activer l'API de Fever",
|
"form.integration.fever_activate": "Activer l'API de Fever",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "प्रवेश छँटाई कॉलम",
|
"form.prefs.label.entry_order": "प्रवेश छँटाई कॉलम",
|
||||||
"form.prefs.label.default_home_page": "डिफ़ॉल्ट होमपेज़",
|
"form.prefs.label.default_home_page": "डिफ़ॉल्ट होमपेज़",
|
||||||
"form.prefs.label.categories_sorting_order": "श्रेणियाँ छँटाई",
|
"form.prefs.label.categories_sorting_order": "श्रेणियाँ छँटाई",
|
||||||
|
"form.prefs.label.mark_read_on_view": "देखे जाने पर स्वचालित रूप से प्रविष्टियों को पढ़ने के रूप में चिह्नित करें",
|
||||||
"form.import.label.file": "ओपीएमएल फ़ाइल",
|
"form.import.label.file": "ओपीएमएल फ़ाइल",
|
||||||
"form.import.label.url": "यूआरएल",
|
"form.import.label.url": "यूआरएल",
|
||||||
"form.integration.fever_activate": "फीवर एपीआई सक्रिय करें",
|
"form.integration.fever_activate": "फीवर एपीआई सक्रिय करें",
|
||||||
|
|
|
@ -319,6 +319,7 @@
|
||||||
"form.prefs.label.entry_order": "Pengurutan Kolom Entri",
|
"form.prefs.label.entry_order": "Pengurutan Kolom Entri",
|
||||||
"form.prefs.label.default_home_page": "Beranda Baku",
|
"form.prefs.label.default_home_page": "Beranda Baku",
|
||||||
"form.prefs.label.categories_sorting_order": "Pengurutan Kategori",
|
"form.prefs.label.categories_sorting_order": "Pengurutan Kategori",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Secara otomatis menandai entri sebagai telah dibaca saat dilihat",
|
||||||
"form.import.label.file": "Berkas OPML",
|
"form.import.label.file": "Berkas OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Aktifkan API Fever",
|
"form.integration.fever_activate": "Aktifkan API Fever",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Colonna di ordinamento delle voci",
|
"form.prefs.label.entry_order": "Colonna di ordinamento delle voci",
|
||||||
"form.prefs.label.default_home_page": "Pagina iniziale predefinita",
|
"form.prefs.label.default_home_page": "Pagina iniziale predefinita",
|
||||||
"form.prefs.label.categories_sorting_order": "Ordinamento delle categorie",
|
"form.prefs.label.categories_sorting_order": "Ordinamento delle categorie",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Contrassegna automaticamente le voci come lette quando visualizzate",
|
||||||
"form.import.label.file": "File OPML",
|
"form.import.label.file": "File OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Abilita l'API di Fever",
|
"form.integration.fever_activate": "Abilita l'API di Fever",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "記事の表示順の基準",
|
"form.prefs.label.entry_order": "記事の表示順の基準",
|
||||||
"form.prefs.label.default_home_page": "デフォルトのトップページ",
|
"form.prefs.label.default_home_page": "デフォルトのトップページ",
|
||||||
"form.prefs.label.categories_sorting_order": "カテゴリの表示順",
|
"form.prefs.label.categories_sorting_order": "カテゴリの表示順",
|
||||||
|
"form.prefs.label.mark_read_on_view": "表示時にエントリを自動的に既読としてマークします",
|
||||||
"form.import.label.file": "OPML ファイル",
|
"form.import.label.file": "OPML ファイル",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Fever API を有効にする",
|
"form.integration.fever_activate": "Fever API を有効にする",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Ingang Sorteerkolom",
|
"form.prefs.label.entry_order": "Ingang Sorteerkolom",
|
||||||
"form.prefs.label.default_home_page": "Standaard startpagina",
|
"form.prefs.label.default_home_page": "Standaard startpagina",
|
||||||
"form.prefs.label.categories_sorting_order": "Categorieën sorteren",
|
"form.prefs.label.categories_sorting_order": "Categorieën sorteren",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Items automatisch markeren als gelezen wanneer ze worden bekeken",
|
||||||
"form.import.label.file": "OPML-bestand",
|
"form.import.label.file": "OPML-bestand",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Activeer Fever API",
|
"form.integration.fever_activate": "Activeer Fever API",
|
||||||
|
|
|
@ -324,6 +324,7 @@
|
||||||
"form.prefs.label.entry_order": "Kolumna sortowania wpisów",
|
"form.prefs.label.entry_order": "Kolumna sortowania wpisów",
|
||||||
"form.prefs.label.default_home_page": "Domyślna strona główna",
|
"form.prefs.label.default_home_page": "Domyślna strona główna",
|
||||||
"form.prefs.label.categories_sorting_order": "Sortowanie kategorii",
|
"form.prefs.label.categories_sorting_order": "Sortowanie kategorii",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Automatycznie oznaczaj wpisy jako przeczytane podczas przeglądania",
|
||||||
"form.import.label.file": "Plik OPML",
|
"form.import.label.file": "Plik OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Aktywuj Fever API",
|
"form.integration.fever_activate": "Aktywuj Fever API",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Coluna de Ordenação de Entrada",
|
"form.prefs.label.entry_order": "Coluna de Ordenação de Entrada",
|
||||||
"form.prefs.label.default_home_page": "Página inicial predefinida",
|
"form.prefs.label.default_home_page": "Página inicial predefinida",
|
||||||
"form.prefs.label.categories_sorting_order": "Classificação das categorias",
|
"form.prefs.label.categories_sorting_order": "Classificação das categorias",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Marcar automaticamente as entradas como lidas quando visualizadas",
|
||||||
"form.import.label.file": "Arquivo OPML",
|
"form.import.label.file": "Arquivo OPML",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Ativar API do Fever",
|
"form.integration.fever_activate": "Ativar API do Fever",
|
||||||
|
|
|
@ -324,6 +324,7 @@
|
||||||
"form.prefs.label.entry_order": "Столбец сортировки статей",
|
"form.prefs.label.entry_order": "Столбец сортировки статей",
|
||||||
"form.prefs.label.default_home_page": "Домашняя страница по умолчанию",
|
"form.prefs.label.default_home_page": "Домашняя страница по умолчанию",
|
||||||
"form.prefs.label.categories_sorting_order": "Сортировка категорий",
|
"form.prefs.label.categories_sorting_order": "Сортировка категорий",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Автоматически отмечать записи как прочитанные при просмотре",
|
||||||
"form.import.label.file": "OPML файл",
|
"form.import.label.file": "OPML файл",
|
||||||
"form.import.label.url": "Ссылка",
|
"form.import.label.url": "Ссылка",
|
||||||
"form.integration.fever_activate": "Активировать Fever API",
|
"form.integration.fever_activate": "Активировать Fever API",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "Giriş Sıralama Sütunu",
|
"form.prefs.label.entry_order": "Giriş Sıralama Sütunu",
|
||||||
"form.prefs.label.default_home_page": "Varsayılan ana sayfa",
|
"form.prefs.label.default_home_page": "Varsayılan ana sayfa",
|
||||||
"form.prefs.label.categories_sorting_order": "Kategoriler sıralama",
|
"form.prefs.label.categories_sorting_order": "Kategoriler sıralama",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Girişleri görüntülendiğinde otomatik olarak okundu olarak işaretle",
|
||||||
"form.import.label.file": "OPML dosyası",
|
"form.import.label.file": "OPML dosyası",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "Fever API'yi Etkinleştir",
|
"form.integration.fever_activate": "Fever API'yi Etkinleştir",
|
||||||
|
|
|
@ -321,6 +321,7 @@
|
||||||
"form.prefs.label.entry_order": "Стовпець сортування записів",
|
"form.prefs.label.entry_order": "Стовпець сортування записів",
|
||||||
"form.prefs.label.default_home_page": "Домашня сторінка за умовчанням",
|
"form.prefs.label.default_home_page": "Домашня сторінка за умовчанням",
|
||||||
"form.prefs.label.categories_sorting_order": "Сортування за категоріями",
|
"form.prefs.label.categories_sorting_order": "Сортування за категоріями",
|
||||||
|
"form.prefs.label.mark_read_on_view": "Автоматично позначати записи як прочитані під час перегляду",
|
||||||
"form.import.label.file": "Файл OPML",
|
"form.import.label.file": "Файл OPML",
|
||||||
"form.import.label.url": "URL-адреса",
|
"form.import.label.url": "URL-адреса",
|
||||||
"form.integration.fever_activate": "Увімкнути API Fever",
|
"form.integration.fever_activate": "Увімкнути API Fever",
|
||||||
|
|
|
@ -320,6 +320,7 @@
|
||||||
"form.prefs.label.entry_order": "文章排序依据",
|
"form.prefs.label.entry_order": "文章排序依据",
|
||||||
"form.prefs.label.default_home_page": "默认主页",
|
"form.prefs.label.default_home_page": "默认主页",
|
||||||
"form.prefs.label.categories_sorting_order": "分类排序",
|
"form.prefs.label.categories_sorting_order": "分类排序",
|
||||||
|
"form.prefs.label.mark_read_on_view": "查看时自动将条目标记为已读",
|
||||||
"form.import.label.file": "OPML 文件",
|
"form.import.label.file": "OPML 文件",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "启用 Fever API",
|
"form.integration.fever_activate": "启用 Fever API",
|
||||||
|
|
|
@ -322,6 +322,7 @@
|
||||||
"form.prefs.label.entry_order": "文章排序依據",
|
"form.prefs.label.entry_order": "文章排序依據",
|
||||||
"form.prefs.label.default_home_page": "默認主頁",
|
"form.prefs.label.default_home_page": "默認主頁",
|
||||||
"form.prefs.label.categories_sorting_order": "分類排序",
|
"form.prefs.label.categories_sorting_order": "分類排序",
|
||||||
|
"form.prefs.label.mark_read_on_view": "查看時自動將條目標記為已讀",
|
||||||
"form.import.label.file": "OPML 檔案",
|
"form.import.label.file": "OPML 檔案",
|
||||||
"form.import.label.url": "URL",
|
"form.import.label.url": "URL",
|
||||||
"form.integration.fever_activate": "啟用 Fever API",
|
"form.integration.fever_activate": "啟用 Fever API",
|
||||||
|
|
|
@ -34,6 +34,7 @@ type User struct {
|
||||||
CJKReadingSpeed int `json:"cjk_reading_speed"`
|
CJKReadingSpeed int `json:"cjk_reading_speed"`
|
||||||
DefaultHomePage string `json:"default_home_page"`
|
DefaultHomePage string `json:"default_home_page"`
|
||||||
CategoriesSortingOrder string `json:"categories_sorting_order"`
|
CategoriesSortingOrder string `json:"categories_sorting_order"`
|
||||||
|
MarkReadOnView bool `json:"mark_read_on_view"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserCreationRequest represents the request to create a user.
|
// UserCreationRequest represents the request to create a user.
|
||||||
|
@ -68,6 +69,7 @@ type UserModificationRequest struct {
|
||||||
CJKReadingSpeed *int `json:"cjk_reading_speed"`
|
CJKReadingSpeed *int `json:"cjk_reading_speed"`
|
||||||
DefaultHomePage *string `json:"default_home_page"`
|
DefaultHomePage *string `json:"default_home_page"`
|
||||||
CategoriesSortingOrder *string `json:"categories_sorting_order"`
|
CategoriesSortingOrder *string `json:"categories_sorting_order"`
|
||||||
|
MarkReadOnView *bool `json:"mark_read_on_view"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch updates the User object with the modification request.
|
// Patch updates the User object with the modification request.
|
||||||
|
@ -155,6 +157,10 @@ func (u *UserModificationRequest) Patch(user *User) {
|
||||||
if u.CategoriesSortingOrder != nil {
|
if u.CategoriesSortingOrder != nil {
|
||||||
user.CategoriesSortingOrder = *u.CategoriesSortingOrder
|
user.CategoriesSortingOrder = *u.CategoriesSortingOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if u.MarkReadOnView != nil {
|
||||||
|
user.MarkReadOnView = *u.MarkReadOnView
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UseTimezone converts last login date to the given timezone.
|
// UseTimezone converts last login date to the given timezone.
|
||||||
|
|
|
@ -86,10 +86,11 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m
|
||||||
openid_connect_id,
|
openid_connect_id,
|
||||||
display_mode,
|
display_mode,
|
||||||
entry_order,
|
entry_order,
|
||||||
default_reading_speed,
|
default_reading_speed,
|
||||||
cjk_reading_speed,
|
cjk_reading_speed,
|
||||||
default_home_page,
|
default_home_page,
|
||||||
categories_sorting_order
|
categories_sorting_order,
|
||||||
|
mark_read_on_view
|
||||||
`
|
`
|
||||||
|
|
||||||
tx, err := s.db.Begin()
|
tx, err := s.db.Begin()
|
||||||
|
@ -127,6 +128,7 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m
|
||||||
&user.CJKReadingSpeed,
|
&user.CJKReadingSpeed,
|
||||||
&user.DefaultHomePage,
|
&user.DefaultHomePage,
|
||||||
&user.CategoriesSortingOrder,
|
&user.CategoriesSortingOrder,
|
||||||
|
&user.MarkReadOnView,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
@ -182,9 +184,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
||||||
default_reading_speed=$18,
|
default_reading_speed=$18,
|
||||||
cjk_reading_speed=$19,
|
cjk_reading_speed=$19,
|
||||||
default_home_page=$20,
|
default_home_page=$20,
|
||||||
categories_sorting_order=$21
|
categories_sorting_order=$21,
|
||||||
|
mark_read_on_view=$22
|
||||||
WHERE
|
WHERE
|
||||||
id=$22
|
id=$23
|
||||||
`
|
`
|
||||||
|
|
||||||
_, err = s.db.Exec(
|
_, err = s.db.Exec(
|
||||||
|
@ -210,6 +213,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
||||||
user.CJKReadingSpeed,
|
user.CJKReadingSpeed,
|
||||||
user.DefaultHomePage,
|
user.DefaultHomePage,
|
||||||
user.CategoriesSortingOrder,
|
user.CategoriesSortingOrder,
|
||||||
|
user.MarkReadOnView,
|
||||||
user.ID,
|
user.ID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -237,9 +241,10 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
||||||
default_reading_speed=$17,
|
default_reading_speed=$17,
|
||||||
cjk_reading_speed=$18,
|
cjk_reading_speed=$18,
|
||||||
default_home_page=$19,
|
default_home_page=$19,
|
||||||
categories_sorting_order=$20
|
categories_sorting_order=$20,
|
||||||
|
mark_read_on_view=$21
|
||||||
WHERE
|
WHERE
|
||||||
id=$21
|
id=$22
|
||||||
`
|
`
|
||||||
|
|
||||||
_, err := s.db.Exec(
|
_, err := s.db.Exec(
|
||||||
|
@ -264,6 +269,7 @@ func (s *Storage) UpdateUser(user *model.User) error {
|
||||||
user.CJKReadingSpeed,
|
user.CJKReadingSpeed,
|
||||||
user.DefaultHomePage,
|
user.DefaultHomePage,
|
||||||
user.CategoriesSortingOrder,
|
user.CategoriesSortingOrder,
|
||||||
|
user.MarkReadOnView,
|
||||||
user.ID,
|
user.ID,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -310,7 +316,8 @@ func (s *Storage) UserByID(userID int64) (*model.User, error) {
|
||||||
default_reading_speed,
|
default_reading_speed,
|
||||||
cjk_reading_speed,
|
cjk_reading_speed,
|
||||||
default_home_page,
|
default_home_page,
|
||||||
categories_sorting_order
|
categories_sorting_order,
|
||||||
|
mark_read_on_view
|
||||||
FROM
|
FROM
|
||||||
users
|
users
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -344,7 +351,8 @@ func (s *Storage) UserByUsername(username string) (*model.User, error) {
|
||||||
default_reading_speed,
|
default_reading_speed,
|
||||||
cjk_reading_speed,
|
cjk_reading_speed,
|
||||||
default_home_page,
|
default_home_page,
|
||||||
categories_sorting_order
|
categories_sorting_order,
|
||||||
|
mark_read_on_view
|
||||||
FROM
|
FROM
|
||||||
users
|
users
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -378,7 +386,8 @@ func (s *Storage) UserByField(field, value string) (*model.User, error) {
|
||||||
default_reading_speed,
|
default_reading_speed,
|
||||||
cjk_reading_speed,
|
cjk_reading_speed,
|
||||||
default_home_page,
|
default_home_page,
|
||||||
categories_sorting_order
|
categories_sorting_order,
|
||||||
|
mark_read_on_view
|
||||||
FROM
|
FROM
|
||||||
users
|
users
|
||||||
WHERE
|
WHERE
|
||||||
|
@ -419,7 +428,8 @@ func (s *Storage) UserByAPIKey(token string) (*model.User, error) {
|
||||||
u.default_reading_speed,
|
u.default_reading_speed,
|
||||||
u.cjk_reading_speed,
|
u.cjk_reading_speed,
|
||||||
u.default_home_page,
|
u.default_home_page,
|
||||||
u.categories_sorting_order
|
u.categories_sorting_order,
|
||||||
|
u.mark_read_on_view
|
||||||
FROM
|
FROM
|
||||||
users u
|
users u
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
|
@ -455,6 +465,7 @@ func (s *Storage) fetchUser(query string, args ...interface{}) (*model.User, err
|
||||||
&user.CJKReadingSpeed,
|
&user.CJKReadingSpeed,
|
||||||
&user.DefaultHomePage,
|
&user.DefaultHomePage,
|
||||||
&user.CategoriesSortingOrder,
|
&user.CategoriesSortingOrder,
|
||||||
|
&user.MarkReadOnView,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -551,7 +562,8 @@ func (s *Storage) Users() (model.Users, error) {
|
||||||
default_reading_speed,
|
default_reading_speed,
|
||||||
cjk_reading_speed,
|
cjk_reading_speed,
|
||||||
default_home_page,
|
default_home_page,
|
||||||
categories_sorting_order
|
categories_sorting_order,
|
||||||
|
mark_read_on_view
|
||||||
FROM
|
FROM
|
||||||
users
|
users
|
||||||
ORDER BY username ASC
|
ORDER BY username ASC
|
||||||
|
@ -588,6 +600,7 @@ func (s *Storage) Users() (model.Users, error) {
|
||||||
&user.CJKReadingSpeed,
|
&user.CJKReadingSpeed,
|
||||||
&user.DefaultHomePage,
|
&user.DefaultHomePage,
|
||||||
&user.CategoriesSortingOrder,
|
&user.CategoriesSortingOrder,
|
||||||
|
&user.MarkReadOnView,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<div class="item-meta">
|
<div class="item-meta">
|
||||||
<ul class="item-meta-info">
|
<ul class="item-meta-info">
|
||||||
<li class="item-meta-info-site-url" dir="auto">
|
<li class="item-meta-info-site-url" dir="auto">
|
||||||
<a href="{{ .SiteURL | safeURL }}" title="{{ .SiteURL }}" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer" data-original-link="true">{{ domain .SiteURL }}</a>
|
<a href="{{ .SiteURL | safeURL }}" title="{{ .SiteURL }}" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer" data-original-link="{{ $.user.MarkReadOnView }}">{{ domain .SiteURL }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="item-meta-info-checked-at">
|
<li class="item-meta-info-checked-at">
|
||||||
{{ t "page.feeds.last_check" }} <time datetime="{{ isodate .CheckedAt }}" title="{{ isodate .CheckedAt }}">{{ elapsed $.user.Timezone .CheckedAt }}</time>
|
{{ t "page.feeds.last_check" }} <time datetime="{{ isodate .CheckedAt }}" title="{{ isodate .CheckedAt }}">{{ elapsed $.user.Timezone .CheckedAt }}</time>
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
data-original-link="true">{{ icon "external-link" }}<span class="icon-label">{{ t "entry.external_link.label" }}</span></a>
|
data-original-link="{{ .user.MarkReadOnView }}">{{ icon "external-link" }}<span class="icon-label">{{ t "entry.external_link.label" }}</span></a>
|
||||||
</li>
|
</li>
|
||||||
{{ if .entry.CommentsURL }}
|
{{ if .entry.CommentsURL }}
|
||||||
<li class="item-meta-icons-comments">
|
<li class="item-meta-icons-comments">
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
data-original-link="true">{{ icon "external-link" }}<span class="icon-label">{{ t "entry.external_link.label" }}</span></a>
|
data-original-link="{{ .user.MarkReadOnView }}">{{ icon "external-link" }}<span class="icon-label">{{ t "entry.external_link.label" }}</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#"
|
<a href="#"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{{ define "content"}}
|
{{ define "content"}}
|
||||||
<section class="page-header">
|
<section class="page-header">
|
||||||
<h1 dir="auto">
|
<h1 dir="auto">
|
||||||
<a href="{{ .feed.SiteURL | safeURL }}" title="{{ .feed.SiteURL }}" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer" data-original-link="true">{{ .feed.Title }}</a>
|
<a href="{{ .feed.SiteURL | safeURL }}" title="{{ .feed.SiteURL }}" target="_blank" rel="noopener noreferrer" referrerpolicy="no-referrer" data-original-link="{{ .user.MarkReadOnView }}">{{ .feed.Title }}</a>
|
||||||
({{ .total }})
|
({{ .total }})
|
||||||
</h1>
|
</h1>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -99,6 +99,8 @@
|
||||||
|
|
||||||
<label><input type="checkbox" name="show_reading_time" value="1" {{ if .form.ShowReadingTime }}checked{{ end }}> {{ t "form.prefs.label.show_reading_time" }}</label>
|
<label><input type="checkbox" name="show_reading_time" value="1" {{ if .form.ShowReadingTime }}checked{{ end }}> {{ t "form.prefs.label.show_reading_time" }}</label>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
<label for="form-cjk-reading-speed">{{ t "form.prefs.label.cjk_reading_speed" }}</label>
|
<label for="form-cjk-reading-speed">{{ t "form.prefs.label.cjk_reading_speed" }}</label>
|
||||||
<input type="number" name="cjk_reading_speed" id="form-cjk-reading-speed" value="{{ .form.CJKReadingSpeed }}" min="1">
|
<input type="number" name="cjk_reading_speed" id="form-cjk-reading-speed" value="{{ .form.CJKReadingSpeed }}" min="1">
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (h *handler) showStarredEntryPage(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Status == model.EntryStatusUnread {
|
if user.MarkReadOnView && entry.Status == model.EntryStatusUnread {
|
||||||
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
html.ServerError(w, r, err)
|
html.ServerError(w, r, err)
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (h *handler) showCategoryEntryPage(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Status == model.EntryStatusUnread {
|
if user.MarkReadOnView && entry.Status == model.EntryStatusUnread {
|
||||||
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
html.ServerError(w, r, err)
|
html.ServerError(w, r, err)
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (h *handler) showFeedEntryPage(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Status == model.EntryStatusUnread {
|
if user.MarkReadOnView && entry.Status == model.EntryStatusUnread {
|
||||||
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
html.ServerError(w, r, err)
|
html.ServerError(w, r, err)
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (h *handler) showSearchEntryPage(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.Status == model.EntryStatusUnread {
|
if user.MarkReadOnView && entry.Status == model.EntryStatusUnread {
|
||||||
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
html.ServerError(w, r, err)
|
html.ServerError(w, r, err)
|
||||||
|
|
|
@ -66,13 +66,18 @@ func (h *handler) showUnreadEntryPage(w http.ResponseWriter, r *http.Request) {
|
||||||
prevEntryRoute = route.Path(h.router, "unreadEntry", "entryID", prevEntry.ID)
|
prevEntryRoute = route.Path(h.router, "unreadEntry", "entryID", prevEntry.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always mark the entry as read after fetching the pagination.
|
if user.MarkReadOnView {
|
||||||
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
entry.Status = model.EntryStatusRead
|
||||||
if err != nil {
|
}
|
||||||
html.ServerError(w, r, err)
|
|
||||||
return
|
// Restore entry read status if needed after fetching the pagination.
|
||||||
|
if entry.Status == model.EntryStatusRead {
|
||||||
|
err = h.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
|
||||||
|
if err != nil {
|
||||||
|
html.ServerError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
entry.Status = model.EntryStatusRead
|
|
||||||
|
|
||||||
sess := session.New(h.store, request.SessionID(r))
|
sess := session.New(h.store, request.SessionID(r))
|
||||||
view := view.New(h.tpl, r, sess)
|
view := view.New(h.tpl, r, sess)
|
||||||
|
|
|
@ -32,6 +32,7 @@ type SettingsForm struct {
|
||||||
CJKReadingSpeed int
|
CJKReadingSpeed int
|
||||||
DefaultHomePage string
|
DefaultHomePage string
|
||||||
CategoriesSortingOrder string
|
CategoriesSortingOrder string
|
||||||
|
MarkReadOnView bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge updates the fields of the given user.
|
// Merge updates the fields of the given user.
|
||||||
|
@ -53,6 +54,7 @@ func (s *SettingsForm) Merge(user *model.User) *model.User {
|
||||||
user.DefaultReadingSpeed = s.DefaultReadingSpeed
|
user.DefaultReadingSpeed = s.DefaultReadingSpeed
|
||||||
user.DefaultHomePage = s.DefaultHomePage
|
user.DefaultHomePage = s.DefaultHomePage
|
||||||
user.CategoriesSortingOrder = s.CategoriesSortingOrder
|
user.CategoriesSortingOrder = s.CategoriesSortingOrder
|
||||||
|
user.MarkReadOnView = s.MarkReadOnView
|
||||||
|
|
||||||
if s.Password != "" {
|
if s.Password != "" {
|
||||||
user.Password = s.Password
|
user.Password = s.Password
|
||||||
|
@ -119,5 +121,6 @@ func NewSettingsForm(r *http.Request) *SettingsForm {
|
||||||
CJKReadingSpeed: int(cjkReadingSpeed),
|
CJKReadingSpeed: int(cjkReadingSpeed),
|
||||||
DefaultHomePage: r.FormValue("default_home_page"),
|
DefaultHomePage: r.FormValue("default_home_page"),
|
||||||
CategoriesSortingOrder: r.FormValue("categories_sorting_order"),
|
CategoriesSortingOrder: r.FormValue("categories_sorting_order"),
|
||||||
|
MarkReadOnView: r.FormValue("mark_read_on_view") == "1",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ func (h *handler) showSettingsPage(w http.ResponseWriter, r *http.Request) {
|
||||||
CJKReadingSpeed: user.CJKReadingSpeed,
|
CJKReadingSpeed: user.CJKReadingSpeed,
|
||||||
DefaultHomePage: user.DefaultHomePage,
|
DefaultHomePage: user.DefaultHomePage,
|
||||||
CategoriesSortingOrder: user.CategoriesSortingOrder,
|
CategoriesSortingOrder: user.CategoriesSortingOrder,
|
||||||
|
MarkReadOnView: user.MarkReadOnView,
|
||||||
}
|
}
|
||||||
|
|
||||||
timezones, err := h.store.Timezones()
|
timezones, err := h.store.Timezones()
|
||||||
|
|
4
ui/static/js/bootstrap.js
vendored
4
ui/static/js/bootstrap.js
vendored
|
@ -69,10 +69,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
request.execute();
|
request.execute();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
onClick("a[data-original-link]", (event) => {
|
onClick("a[data-original-link='true']", (event) => {
|
||||||
handleEntryStatus("next", event.target, true);
|
handleEntryStatus("next", event.target, true);
|
||||||
}, true);
|
}, true);
|
||||||
onAuxClick("a[data-original-link]", (event) => {
|
onAuxClick("a[data-original-link='true']", (event) => {
|
||||||
if (event.button == 1) {
|
if (event.button == 1) {
|
||||||
handleEntryStatus("next", event.target, true);
|
handleEntryStatus("next", event.target, true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue