diff --git a/client/model.go b/client/model.go index 9ed8de47..f6c5c265 100644 --- a/client/model.go +++ b/client/model.go @@ -26,6 +26,7 @@ type User struct { Language string `json:"language"` Timezone string `json:"timezone"` EntryDirection string `json:"entry_sorting_direction"` + EntryOrder string `json:"entry_sorting_order"` Stylesheet string `json:"stylesheet"` GoogleID string `json:"google_id"` OpenIDConnectID string `json:"openid_connect_id"` @@ -59,6 +60,7 @@ type UserModificationRequest struct { Language *string `json:"language"` Timezone *string `json:"timezone"` EntryDirection *string `json:"entry_sorting_direction"` + EntryOrder *string `json:"entry_sorting_order"` Stylesheet *string `json:"stylesheet"` GoogleID *string `json:"google_id"` OpenIDConnectID *string `json:"openid_connect_id"` diff --git a/database/migrations.go b/database/migrations.go index 8b207c29..a5ac6583 100644 --- a/database/migrations.go +++ b/database/migrations.go @@ -17,7 +17,7 @@ var migrations = []func(tx *sql.Tx) error{ CREATE TABLE schema_version ( version text not null ); - + CREATE TABLE users ( id serial not null, username text not null unique, @@ -29,7 +29,7 @@ var migrations = []func(tx *sql.Tx) error{ last_login_at timestamp with time zone, primary key (id) ); - + CREATE TABLE sessions ( id serial not null, user_id int not null, @@ -41,7 +41,7 @@ var migrations = []func(tx *sql.Tx) error{ unique (user_id, token), foreign key (user_id) references users(id) on delete cascade ); - + CREATE TABLE categories ( id serial not null, user_id int not null, @@ -50,7 +50,7 @@ var migrations = []func(tx *sql.Tx) error{ unique (user_id, title), foreign key (user_id) references users(id) on delete cascade ); - + CREATE TABLE feeds ( id bigserial not null, user_id int not null, @@ -68,9 +68,9 @@ var migrations = []func(tx *sql.Tx) error{ foreign key (user_id) references users(id) on delete cascade, foreign key (category_id) references categories(id) on delete cascade ); - + CREATE TYPE entry_status as enum('unread', 'read', 'removed'); - + CREATE TABLE entries ( id bigserial not null, user_id int not null, @@ -87,9 +87,9 @@ var migrations = []func(tx *sql.Tx) error{ foreign key (user_id) references users(id) on delete cascade, foreign key (feed_id) references feeds(id) on delete cascade ); - + CREATE INDEX entries_feed_idx on entries using btree(feed_id); - + CREATE TABLE enclosures ( id bigserial not null, user_id int not null, @@ -101,7 +101,7 @@ var migrations = []func(tx *sql.Tx) error{ foreign key (user_id) references users(id) on delete cascade, foreign key (entry_id) references entries(id) on delete cascade ); - + CREATE TABLE icons ( id bigserial not null, hash text not null unique, @@ -109,14 +109,14 @@ var migrations = []func(tx *sql.Tx) error{ content bytea not null, primary key (id) ); - + CREATE TABLE feed_icons ( feed_id bigint not null, icon_id bigint not null, primary key(feed_id, icon_id), foreign key (feed_id) references feeds(id) on delete cascade, foreign key (icon_id) references icons(id) on delete cascade - ); + ); ` _, err = tx.Exec(sql) return err @@ -410,7 +410,7 @@ var migrations = []func(tx *sql.Tx) error{ }, func(tx *sql.Tx) (err error) { sql := ` - ALTER TABLE feeds + ALTER TABLE feeds ADD COLUMN blocklist_rules text not null default '', ADD COLUMN keeplist_rules text not null default '' ` @@ -555,4 +555,12 @@ var migrations = []func(tx *sql.Tx) error{ _, err = tx.Exec(sql) return err }, + func(tx *sql.Tx) (err error) { + sql := ` + CREATE TYPE entry_sorting_order AS enum('published_at', 'created_at'); + ALTER TABLE users ADD COLUMN entry_order entry_sorting_order default 'published_at'; + ` + _, err = tx.Exec(sql) + return err + }, } diff --git a/locale/translations/de_DE.json b/locale/translations/de_DE.json index 868893cd..ea44153a 100644 --- a/locale/translations/de_DE.json +++ b/locale/translations/de_DE.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Eigenständige", "form.prefs.select.minimal_ui": "Minimal", "form.prefs.select.browser": "Browser", + "form.prefs.select.publish_time": "Eintrag veröffentlichte Zeit", + "form.prefs.select.created_time": "Eintrag erstellt Zeit", "form.prefs.label.keyboard_shortcuts": "Tastaturkürzel aktivieren", "form.prefs.label.entry_swipe": "Wischgeste für Einträge auf dem Handy aktivieren", "form.prefs.label.show_reading_time": "Geschätzte Lesezeit für Artikel anzeigen", "form.prefs.label.custom_css": "Benutzerdefiniertes CSS", + "form.prefs.label.entry_order": "Eintrag Sortierspalte", "form.import.label.file": "OPML Datei", "form.import.label.url": "URL", "form.integration.fever_activate": "Fever API aktivieren", diff --git a/locale/translations/el_EL.json b/locale/translations/el_EL.json index 06df3494..dc93a6da 100644 --- a/locale/translations/el_EL.json +++ b/locale/translations/el_EL.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Μεμονωμένο", "form.prefs.select.minimal_ui": "Ελάχιστη", "form.prefs.select.browser": "Περιηγητής", + "form.prefs.select.publish_time": "Δημοσιευμένος χρόνος εισόδου", + "form.prefs.select.created_time": "Χρόνος δημιουργίας καταχώρησης", "form.prefs.label.keyboard_shortcuts": "Ενεργοποίηση συντομεύσεων πληκτρολογίου", "form.prefs.label.entry_swipe": "Ενεργοποιήστε τη χειρονομία σάρωσης στις καταχωρήσεις στο κινητό", "form.prefs.label.show_reading_time": "Εμφάνιση εκτιμώμενου χρόνου ανάγνωσης για άρθρα", "form.prefs.label.custom_css": "Προσαρμοσμένο CSS", + "form.prefs.label.entry_order": "Στήλη ταξινόμησης εισόδου", "form.import.label.file": "Αρχείο OPML", "form.import.label.url": "URL", "form.integration.fever_activate": "Ενεργοποιήστε το Fever API", diff --git a/locale/translations/en_US.json b/locale/translations/en_US.json index 3e6e3e48..2076c813 100644 --- a/locale/translations/en_US.json +++ b/locale/translations/en_US.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Standalone", "form.prefs.select.minimal_ui": "Minimal", "form.prefs.select.browser": "Browser", + "form.prefs.select.publish_time": "Entry published time", + "form.prefs.select.created_time": "Entry created time", "form.prefs.label.keyboard_shortcuts": "Enable keyboard shortcuts", "form.prefs.label.entry_swipe": "Enable swipe gesture on entries on mobile", "form.prefs.label.show_reading_time": "Show estimated reading time for articles", "form.prefs.label.custom_css": "Custom CSS", + "form.prefs.label.entry_order": "Entry Sorting Column", "form.import.label.file": "OPML file", "form.import.label.url": "URL", "form.integration.fever_activate": "Activate Fever API", diff --git a/locale/translations/es_ES.json b/locale/translations/es_ES.json index dbef106b..00aa4d55 100644 --- a/locale/translations/es_ES.json +++ b/locale/translations/es_ES.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Ser único", "form.prefs.select.minimal_ui": "Mínimo", "form.prefs.select.browser": "Navegador", + "form.prefs.select.publish_time": "Hora de publicación de la entrada", + "form.prefs.select.created_time": "Hora de creación de la entrada", "form.prefs.label.keyboard_shortcuts": "Habilitar atajos de teclado", "form.prefs.label.entry_swipe": "Habilitar el gesto de deslizar el dedo en las entradas en el móvil", "form.prefs.label.show_reading_time": "Mostrar el tiempo estimado de lectura de los artículos", "form.prefs.label.custom_css": "CSS personalizado", + "form.prefs.label.entry_order": "Columna de clasificación de entradas", "form.import.label.file": "Archivo OPML", "form.import.label.url": "URL", "form.integration.fever_activate": "Activar API de Fever", diff --git a/locale/translations/fr_FR.json b/locale/translations/fr_FR.json index e45ee9bb..1698da47 100644 --- a/locale/translations/fr_FR.json +++ b/locale/translations/fr_FR.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Autonome", "form.prefs.select.minimal_ui": "Minimal", "form.prefs.select.browser": "Navigateur", + "form.prefs.select.publish_time": "Heure de publication de l'entrée", + "form.prefs.select.created_time": "Heure de création de l'entrée", "form.prefs.label.keyboard_shortcuts": "Activer les raccourcis clavier", "form.prefs.label.entry_swipe": "Activer le geste de balayage sur les entrées sur mobile", "form.prefs.label.show_reading_time": "Afficher le temps de lecture estimé des articles", "form.prefs.label.custom_css": "CSS personnalisé", + "form.prefs.label.entry_order": "Colonne de tri des entrées", "form.import.label.file": "Fichier OPML", "form.import.label.url": "URL", "form.integration.fever_activate": "Activer l'API de Fever", diff --git a/locale/translations/it_IT.json b/locale/translations/it_IT.json index b50590ca..c92347a9 100644 --- a/locale/translations/it_IT.json +++ b/locale/translations/it_IT.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Autonoma", "form.prefs.select.minimal_ui": "Minimale", "form.prefs.select.browser": "Browser", + "form.prefs.select.publish_time": "Ora di pubblicazione dell'entrata", + "form.prefs.select.created_time": "Tempo di creazione dell'entrata", "form.prefs.label.keyboard_shortcuts": "Abilita le scorciatoie da tastiera", "form.prefs.label.entry_swipe": "Abilita il gesto di scorrimento sulle voci sul cellulare", "form.prefs.label.show_reading_time": "Mostra il tempo di lettura stimato per gli articoli", "form.prefs.label.custom_css": "CSS personalizzati", + "form.prefs.label.entry_order": "Colonna di ordinamento delle voci", "form.import.label.file": "File OPML", "form.import.label.url": "URL", "form.integration.fever_activate": "Abilita l'API di Fever", diff --git a/locale/translations/ja_JP.json b/locale/translations/ja_JP.json index 4d75a62a..cdb62d64 100644 --- a/locale/translations/ja_JP.json +++ b/locale/translations/ja_JP.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "スタンドアロン", "form.prefs.select.minimal_ui": "最小限", "form.prefs.select.browser": "ブラウザ", + "form.prefs.select.publish_time": "エントリー公開時間", + "form.prefs.select.created_time": "エントリー作成時間", "form.prefs.label.keyboard_shortcuts": "キーボード・ショートカットを有効にする", "form.prefs.label.entry_swipe": "モバイルのエントリでスワイプジェスチャーを有効にする", "form.prefs.label.show_reading_time": "記事の推定読書時間を表示する", "form.prefs.label.custom_css": "カスタムCSS", + "form.prefs.label.entry_order": "エントリーソートカラム", "form.import.label.file": "OPML ファイル", "form.import.label.url": "URL", "form.integration.fever_activate": "Fever API を有効にする", diff --git a/locale/translations/nl_NL.json b/locale/translations/nl_NL.json index 18a59238..8a9d23e7 100644 --- a/locale/translations/nl_NL.json +++ b/locale/translations/nl_NL.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Standalone", "form.prefs.select.minimal_ui": "Minimaal", "form.prefs.select.browser": "Browser", + "form.prefs.select.publish_time": "Tijd van binnenkomst", + "form.prefs.select.created_time": "Tijdstip van binnenkomst", "form.prefs.label.keyboard_shortcuts": "Schakel sneltoetsen in", "form.prefs.label.entry_swipe": "Schakel veegbewegingen in voor items op mobiel", "form.prefs.label.show_reading_time": "Toon geschatte leestijd voor artikelen", "form.prefs.label.custom_css": "Aangepaste CSS", + "form.prefs.label.entry_order": "Ingang Sorteerkolom", "form.import.label.file": "OPML-bestand", "form.import.label.url": "URL", "form.integration.fever_activate": "Activeer Fever API", diff --git a/locale/translations/pl_PL.json b/locale/translations/pl_PL.json index e51275c5..95134b74 100644 --- a/locale/translations/pl_PL.json +++ b/locale/translations/pl_PL.json @@ -300,7 +300,10 @@ "form.prefs.select.standalone": "Samodzielny", "form.prefs.select.minimal_ui": "Minimalny", "form.prefs.select.browser": "Przeglądarka", + "form.prefs.select.publish_time": "Czas publikacji wpisu", + "form.prefs.select.created_time": "Czas utworzenia wpisu", "form.prefs.label.custom_css": "Niestandardowy CSS", + "form.prefs.label.entry_order": "Kolumna sortowania wpisów", "form.import.label.file": "Plik OPML", "form.import.label.url": "URL", "form.integration.fever_activate": "Aktywuj Fever API", diff --git a/locale/translations/pt_BR.json b/locale/translations/pt_BR.json index 9c58d48c..6819e20e 100644 --- a/locale/translations/pt_BR.json +++ b/locale/translations/pt_BR.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Autônomo", "form.prefs.select.minimal_ui": "Mínimo", "form.prefs.select.browser": "Navegador", + "form.prefs.select.publish_time": "Entrada hora de publicação", + "form.prefs.select.created_time": "Entrada tempo criado", "form.prefs.label.keyboard_shortcuts": "Habilitar atalhos do teclado", "form.prefs.label.entry_swipe": "Ativar gesto de deslizar nas entradas no celular", "form.prefs.label.show_reading_time": "Mostrar tempo estimado de leitura de artigos", "form.prefs.label.custom_css": "CSS customizado", + "form.prefs.label.entry_order": "Coluna de Ordenação de Entrada", "form.import.label.file": "Arquivo OPML", "form.import.label.url": "URL", "form.integration.fever_activate": "Ativar API do Fever", diff --git a/locale/translations/ru_RU.json b/locale/translations/ru_RU.json index 2095f986..9e20f562 100644 --- a/locale/translations/ru_RU.json +++ b/locale/translations/ru_RU.json @@ -297,10 +297,13 @@ "form.prefs.select.standalone": "Автономный", "form.prefs.select.minimal_ui": "Минимальный", "form.prefs.select.browser": "Браузер", + "form.prefs.select.publish_time": "Время публикации заявки", + "form.prefs.select.created_time": "Время создания записи", "form.prefs.label.keyboard_shortcuts": "Включить сочетания клавиш", "form.prefs.label.entry_swipe": "Включить жест смахивания для записей на мобильном устройстве", "form.prefs.label.show_reading_time": "Показать примерное время чтения статей", "form.prefs.label.custom_css": "Пользовательские CSS", + "form.prefs.label.entry_order": "Колонка сортировки ввода", "form.import.label.file": "OPML файл", "form.import.label.url": "URL", "form.integration.fever_activate": "Активировать Fever API", diff --git a/locale/translations/tr_TR.json b/locale/translations/tr_TR.json index 18d1a538..86b89032 100644 --- a/locale/translations/tr_TR.json +++ b/locale/translations/tr_TR.json @@ -295,10 +295,13 @@ "form.prefs.select.standalone": "Bağımsız", "form.prefs.select.minimal_ui": "Minimal", "form.prefs.select.browser": "Tarayıcı", + "form.prefs.select.publish_time": "Giriş yayınlanma zamanı", + "form.prefs.select.created_time": "Girişin oluşturulma zamanı", "form.prefs.label.keyboard_shortcuts": "Klavye kısayollarını etkinleştir", "form.prefs.label.entry_swipe": "Mobil cihazlarda iletiler için kaydırma hareketlerini etkinleştir", "form.prefs.label.show_reading_time": "Makaleler için tahmini okuma süresini göster", "form.prefs.label.custom_css": "Özel CSS", + "form.prefs.label.entry_order": "Giriş Sıralama Sütunu", "form.import.label.file": "OPML dosyası", "form.import.label.url": "URL", "form.integration.fever_activate": "Fever API'yi Etkinleştir", diff --git a/locale/translations/zh_CN.json b/locale/translations/zh_CN.json index 9548fd86..4d5c0769 100644 --- a/locale/translations/zh_CN.json +++ b/locale/translations/zh_CN.json @@ -293,10 +293,13 @@ "form.prefs.select.standalone": "独立", "form.prefs.select.minimal_ui": "最小", "form.prefs.select.browser": "浏览器", + "form.prefs.select.publish_time": "参赛作品公布时间", + "form.prefs.select.created_time": "条目创建时间", "form.prefs.label.keyboard_shortcuts": "启用键盘快捷键", "form.prefs.label.entry_swipe": "在移动设备上启用滑动手势", "form.prefs.label.show_reading_time": "显示文章的预计阅读时间", "form.prefs.label.custom_css": "自定义 CSS", + "form.prefs.label.entry_order": "条目排序栏", "form.import.label.file": "OPML 文件", "form.import.label.url": "URL", "form.integration.fever_activate": "启用 Fever API", diff --git a/model/user.go b/model/user.go index 1163fedc..6ff7332a 100644 --- a/model/user.go +++ b/model/user.go @@ -20,6 +20,7 @@ type User struct { Language string `json:"language"` Timezone string `json:"timezone"` EntryDirection string `json:"entry_sorting_direction"` + EntryOrder string `json:"entry_sorting_order"` Stylesheet string `json:"stylesheet"` GoogleID string `json:"google_id"` OpenIDConnectID string `json:"openid_connect_id"` @@ -48,6 +49,7 @@ type UserModificationRequest struct { Language *string `json:"language"` Timezone *string `json:"timezone"` EntryDirection *string `json:"entry_sorting_direction"` + EntryOrder *string `json:"entry_sorting_order"` Stylesheet *string `json:"stylesheet"` GoogleID *string `json:"google_id"` OpenIDConnectID *string `json:"openid_connect_id"` @@ -89,6 +91,10 @@ func (u *UserModificationRequest) Patch(user *User) { user.EntryDirection = *u.EntryDirection } + if u.EntryOrder != nil { + user.EntryOrder = *u.EntryOrder + } + if u.Stylesheet != nil { user.Stylesheet = *u.Stylesheet } diff --git a/storage/user.go b/storage/user.go index 32e9162a..2195ddfc 100644 --- a/storage/user.go +++ b/storage/user.go @@ -84,7 +84,8 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m stylesheet, google_id, openid_connect_id, - display_mode + display_mode, + entry_order ` tx, err := s.db.Begin() @@ -116,6 +117,7 @@ func (s *Storage) CreateUser(userCreationRequest *model.UserCreationRequest) (*m &user.GoogleID, &user.OpenIDConnectID, &user.DisplayMode, + &user.EntryOrder, ) if err != nil { tx.Rollback() @@ -165,9 +167,10 @@ func (s *Storage) UpdateUser(user *model.User) error { stylesheet=$12, google_id=$13, openid_connect_id=$14, - display_mode=$15 + display_mode=$15, + entry_order=$16 WHERE - id=$16 + id=$17 ` _, err = s.db.Exec( @@ -187,6 +190,7 @@ func (s *Storage) UpdateUser(user *model.User) error { user.GoogleID, user.OpenIDConnectID, user.DisplayMode, + user.EntryOrder, user.ID, ) if err != nil { @@ -208,9 +212,10 @@ func (s *Storage) UpdateUser(user *model.User) error { stylesheet=$11, google_id=$12, openid_connect_id=$13, - display_mode=$14 + display_mode=$14, + entry_order=$15 WHERE - id=$15 + id=$16 ` _, err := s.db.Exec( @@ -229,6 +234,7 @@ func (s *Storage) UpdateUser(user *model.User) error { user.GoogleID, user.OpenIDConnectID, user.DisplayMode, + user.EntryOrder, user.ID, ) @@ -269,7 +275,8 @@ func (s *Storage) UserByID(userID int64) (*model.User, error) { stylesheet, google_id, openid_connect_id, - display_mode + display_mode, + entry_order FROM users WHERE @@ -297,7 +304,8 @@ func (s *Storage) UserByUsername(username string) (*model.User, error) { stylesheet, google_id, openid_connect_id, - display_mode + display_mode, + entry_order FROM users WHERE @@ -325,7 +333,8 @@ func (s *Storage) UserByField(field, value string) (*model.User, error) { stylesheet, google_id, openid_connect_id, - display_mode + display_mode, + entry_order FROM users WHERE @@ -360,7 +369,8 @@ func (s *Storage) UserByAPIKey(token string) (*model.User, error) { u.stylesheet, u.google_id, u.openid_connect_id, - u.display_mode + u.display_mode, + u.entry_order FROM users u LEFT JOIN @@ -390,6 +400,7 @@ func (s *Storage) fetchUser(query string, args ...interface{}) (*model.User, err &user.GoogleID, &user.OpenIDConnectID, &user.DisplayMode, + &user.EntryOrder, ) if err == sql.ErrNoRows { @@ -480,7 +491,8 @@ func (s *Storage) Users() (model.Users, error) { stylesheet, google_id, openid_connect_id, - display_mode + display_mode, + entry_order FROM users ORDER BY username ASC @@ -511,6 +523,7 @@ func (s *Storage) Users() (model.Users, error) { &user.GoogleID, &user.OpenIDConnectID, &user.DisplayMode, + &user.EntryOrder, ) if err != nil { diff --git a/template/templates/views/settings.html b/template/templates/views/settings.html index f8725f09..3826473c 100644 --- a/template/templates/views/settings.html +++ b/template/templates/views/settings.html @@ -57,6 +57,12 @@ + + + diff --git a/tests/user_test.go b/tests/user_test.go index a41949dd..de7668ec 100644 --- a/tests/user_test.go +++ b/tests/user_test.go @@ -401,6 +401,21 @@ func TestUpdateUserEntryDirectionWithInvalidValue(t *testing.T) { } } +func TestUpdateUserEntryOrderWithInvalidValue(t *testing.T) { + username := getRandomUsername() + client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) + user, err := client.CreateUser(username, testStandardPassword, false) + if err != nil { + t.Fatal(err) + } + + entryOrder := "invalid" + _, err = client.UpdateUser(user.ID, &miniflux.UserModificationRequest{EntryOrder: &entryOrder}) + if err == nil { + t.Fatal(`Updating a user EntryOrder with an invalid value should raise an error`) + } +} + func TestUpdateUserPasswordWithInvalidValue(t *testing.T) { username := getRandomUsername() client := miniflux.New(testBaseURL, testAdminUsername, testAdminPassword) diff --git a/ui/bookmark_entries.go b/ui/bookmark_entries.go index 2b8a31d8..ba3ff1ec 100644 --- a/ui/bookmark_entries.go +++ b/ui/bookmark_entries.go @@ -26,7 +26,7 @@ func (h *handler) showStarredPage(w http.ResponseWriter, r *http.Request) { builder := h.store.NewEntryQueryBuilder(user.ID) builder.WithoutStatus(model.EntryStatusRemoved) builder.WithStarred() - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) builder.WithOffset(offset) builder.WithLimit(user.EntriesPerPage) diff --git a/ui/category_entries.go b/ui/category_entries.go index 48a28939..c0889452 100644 --- a/ui/category_entries.go +++ b/ui/category_entries.go @@ -37,7 +37,7 @@ func (h *handler) showCategoryEntriesPage(w http.ResponseWriter, r *http.Request offset := request.QueryIntParam(r, "offset", 0) builder := h.store.NewEntryQueryBuilder(user.ID) builder.WithCategoryID(category.ID) - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) builder.WithStatus(model.EntryStatusUnread) builder.WithOffset(offset) diff --git a/ui/category_entries_all.go b/ui/category_entries_all.go index d6cc55f6..84478251 100644 --- a/ui/category_entries_all.go +++ b/ui/category_entries_all.go @@ -37,7 +37,7 @@ func (h *handler) showCategoryEntriesAllPage(w http.ResponseWriter, r *http.Requ offset := request.QueryIntParam(r, "offset", 0) builder := h.store.NewEntryQueryBuilder(user.ID) builder.WithCategoryID(category.ID) - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) builder.WithoutStatus(model.EntryStatusRemoved) builder.WithOffset(offset) diff --git a/ui/feed_entries.go b/ui/feed_entries.go index 04b56e53..fa975f78 100644 --- a/ui/feed_entries.go +++ b/ui/feed_entries.go @@ -38,7 +38,7 @@ func (h *handler) showFeedEntriesPage(w http.ResponseWriter, r *http.Request) { builder := h.store.NewEntryQueryBuilder(user.ID) builder.WithFeedID(feed.ID) builder.WithStatus(model.EntryStatusUnread) - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) builder.WithOffset(offset) builder.WithLimit(user.EntriesPerPage) diff --git a/ui/feed_entries_all.go b/ui/feed_entries_all.go index a5b1d7d5..0c42f8a0 100644 --- a/ui/feed_entries_all.go +++ b/ui/feed_entries_all.go @@ -38,7 +38,7 @@ func (h *handler) showFeedEntriesAllPage(w http.ResponseWriter, r *http.Request) builder := h.store.NewEntryQueryBuilder(user.ID) builder.WithFeedID(feed.ID) builder.WithoutStatus(model.EntryStatusRemoved) - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) builder.WithOffset(offset) builder.WithLimit(user.EntriesPerPage) diff --git a/ui/form/settings.go b/ui/form/settings.go index b1468285..4305ea91 100644 --- a/ui/form/settings.go +++ b/ui/form/settings.go @@ -21,6 +21,7 @@ type SettingsForm struct { Language string Timezone string EntryDirection string + EntryOrder string EntriesPerPage int KeyboardShortcuts bool ShowReadingTime bool @@ -36,6 +37,7 @@ func (s *SettingsForm) Merge(user *model.User) *model.User { user.Language = s.Language user.Timezone = s.Timezone user.EntryDirection = s.EntryDirection + user.EntryOrder = s.EntryOrder user.EntriesPerPage = s.EntriesPerPage user.KeyboardShortcuts = s.KeyboardShortcuts user.ShowReadingTime = s.ShowReadingTime @@ -84,6 +86,7 @@ func NewSettingsForm(r *http.Request) *SettingsForm { Language: r.FormValue("language"), Timezone: r.FormValue("timezone"), EntryDirection: r.FormValue("entry_direction"), + EntryOrder: r.FormValue("entry_order"), EntriesPerPage: int(entriesPerPage), KeyboardShortcuts: r.FormValue("keyboard_shortcuts") == "1", ShowReadingTime: r.FormValue("show_reading_time") == "1", diff --git a/ui/settings_show.go b/ui/settings_show.go index 442e021c..14a3c30d 100644 --- a/ui/settings_show.go +++ b/ui/settings_show.go @@ -32,6 +32,7 @@ func (h *handler) showSettingsPage(w http.ResponseWriter, r *http.Request) { Language: user.Language, Timezone: user.Timezone, EntryDirection: user.EntryDirection, + EntryOrder: user.EntryOrder, EntriesPerPage: user.EntriesPerPage, KeyboardShortcuts: user.KeyboardShortcuts, ShowReadingTime: user.ShowReadingTime, diff --git a/ui/shared_entries.go b/ui/shared_entries.go index 0ba9cb19..da84eeb2 100644 --- a/ui/shared_entries.go +++ b/ui/shared_entries.go @@ -9,7 +9,6 @@ import ( "miniflux.app/http/request" "miniflux.app/http/response/html" - "miniflux.app/model" "miniflux.app/ui/session" "miniflux.app/ui/view" ) @@ -23,7 +22,7 @@ func (h *handler) sharedEntries(w http.ResponseWriter, r *http.Request) { builder := h.store.NewEntryQueryBuilder(user.ID) builder.WithShareCodeNotEmpty() - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) entries, err := builder.GetEntries() diff --git a/ui/unread_entries.go b/ui/unread_entries.go index 43495095..1bf745af 100644 --- a/ui/unread_entries.go +++ b/ui/unread_entries.go @@ -49,7 +49,7 @@ func (h *handler) showUnreadPage(w http.ResponseWriter, r *http.Request) { m = timing.NewMetric("sql_fetch_unread_entries").Start() builder = h.store.NewEntryQueryBuilder(user.ID) builder.WithStatus(model.EntryStatusUnread) - builder.WithOrder(model.DefaultSortingOrder) + builder.WithOrder(user.EntryOrder) builder.WithDirection(user.EntryDirection) builder.WithOffset(offset) builder.WithLimit(user.EntriesPerPage)