diff --git a/internal/locale/translations/de_DE.json b/internal/locale/translations/de_DE.json index 9e61b3a6..58650850 100644 --- a/internal/locale/translations/de_DE.json +++ b/internal/locale/translations/de_DE.json @@ -35,6 +35,7 @@ "menu.about": "Über", "menu.export": "Exportieren", "menu.import": "Importieren", + "menu.search": "Suche", "menu.create_category": "Kategorie anlegen", "menu.mark_page_as_read": "Diese Seite als gelesen markieren", "menu.mark_all_as_read": "Alle als gelesen markieren", diff --git a/internal/locale/translations/el_EL.json b/internal/locale/translations/el_EL.json index 839f98ff..2351ee26 100644 --- a/internal/locale/translations/el_EL.json +++ b/internal/locale/translations/el_EL.json @@ -35,6 +35,7 @@ "menu.about": "Περί", "menu.export": "Εξαγωγή", "menu.import": "Εισαγωγή", + "menu.search": "Αναζήτηση", "menu.create_category": "Δημιουργήστε μια κατηγορία", "menu.mark_page_as_read": "Σημείωση αυτής της σελίδας ως αναγνωσμένη", "menu.mark_all_as_read": "Σημείωση όλων ως αναγνωσμένα", diff --git a/internal/locale/translations/en_US.json b/internal/locale/translations/en_US.json index 3981c48f..50a43b9f 100644 --- a/internal/locale/translations/en_US.json +++ b/internal/locale/translations/en_US.json @@ -35,6 +35,7 @@ "menu.about": "About", "menu.export": "Export", "menu.import": "Import", + "menu.search": "Search", "menu.create_category": "Create a category", "menu.mark_page_as_read": "Mark this page as read", "menu.mark_all_as_read": "Mark all as read", diff --git a/internal/locale/translations/es_ES.json b/internal/locale/translations/es_ES.json index 3b85599a..e08c8438 100644 --- a/internal/locale/translations/es_ES.json +++ b/internal/locale/translations/es_ES.json @@ -35,6 +35,7 @@ "menu.about": "Acerca de", "menu.export": "Exportar", "menu.import": "Importar", + "menu.search": "Buscar", "menu.create_category": "Crear una categoría", "menu.mark_page_as_read": "Marcar esta página como leída", "menu.mark_all_as_read": "Marcar todos como leídos", diff --git a/internal/locale/translations/fi_FI.json b/internal/locale/translations/fi_FI.json index 0f8b5b9e..9da193a3 100644 --- a/internal/locale/translations/fi_FI.json +++ b/internal/locale/translations/fi_FI.json @@ -35,6 +35,7 @@ "menu.about": "Tietoja", "menu.export": "Vie", "menu.import": "Tuo", + "menu.search": "Haku", "menu.create_category": "Luo kategoria", "menu.mark_page_as_read": "Merkitse tämä sivu luetuksi", "menu.mark_all_as_read": "Merkitse kaikki luetuksi", diff --git a/internal/locale/translations/fr_FR.json b/internal/locale/translations/fr_FR.json index f1b9ccf2..ca6c264b 100644 --- a/internal/locale/translations/fr_FR.json +++ b/internal/locale/translations/fr_FR.json @@ -35,6 +35,7 @@ "menu.about": "À propos", "menu.export": "Export", "menu.import": "Import", + "menu.search": "Recherche", "menu.create_category": "Créer une catégorie", "menu.mark_page_as_read": "Marquer cette page comme lu", "menu.mark_all_as_read": "Tout marquer comme lu", diff --git a/internal/locale/translations/hi_IN.json b/internal/locale/translations/hi_IN.json index a9f8fcd5..00c81287 100644 --- a/internal/locale/translations/hi_IN.json +++ b/internal/locale/translations/hi_IN.json @@ -35,6 +35,7 @@ "menu.about": "के बारे में", "menu.export": "निर्यात करे", "menu.import": "आयात करे", + "menu.search": "खोज", "menu.create_category": "श्रेणी बनाए", "menu.mark_page_as_read": "इस पृष्ठ को पढ़ा हुआ चिह्नित करें", "menu.mark_all_as_read": "सभी को पढ़ा हुआ मार्क करें", diff --git a/internal/locale/translations/id_ID.json b/internal/locale/translations/id_ID.json index 6453a541..70aa938a 100644 --- a/internal/locale/translations/id_ID.json +++ b/internal/locale/translations/id_ID.json @@ -35,6 +35,7 @@ "menu.about": "Tentang", "menu.export": "Ekspor", "menu.import": "Impor", + "menu.search": "Cari", "menu.create_category": "Buat kategori", "menu.mark_page_as_read": "Tandai halaman ini sebagai telah dibaca", "menu.mark_all_as_read": "Tandai semua sebagai telah dibaca", diff --git a/internal/locale/translations/it_IT.json b/internal/locale/translations/it_IT.json index 551ce5c1..ac1ce3c5 100644 --- a/internal/locale/translations/it_IT.json +++ b/internal/locale/translations/it_IT.json @@ -35,6 +35,7 @@ "menu.about": "Informazioni", "menu.export": "Esporta", "menu.import": "Importa", + "menu.search": "Cerca", "menu.create_category": "Aggiungi una categoria", "menu.mark_page_as_read": "Segna questa pagina come letta", "menu.mark_all_as_read": "Segna tutti gli articoli come letti", diff --git a/internal/locale/translations/ja_JP.json b/internal/locale/translations/ja_JP.json index 54bcb3ea..5363d89a 100644 --- a/internal/locale/translations/ja_JP.json +++ b/internal/locale/translations/ja_JP.json @@ -35,6 +35,7 @@ "menu.about": "ソフトウェア情報", "menu.export": "エクスポート", "menu.import": "インポート", + "menu.search": "検索", "menu.create_category": "カテゴリを作成", "menu.mark_page_as_read": "このページを既読にする", "menu.mark_all_as_read": "すべて既読にする", diff --git a/internal/locale/translations/nl_NL.json b/internal/locale/translations/nl_NL.json index 897d58f0..5b5b57db 100644 --- a/internal/locale/translations/nl_NL.json +++ b/internal/locale/translations/nl_NL.json @@ -35,6 +35,7 @@ "menu.about": "Over", "menu.export": "Exporteren", "menu.import": "Importeren", + "menu.search": "Zoeken", "menu.create_category": "Categorie toevoegen", "menu.mark_page_as_read": "Markeer deze pagina als gelezen", "menu.mark_all_as_read": "Markeer alle items als gelezen", diff --git a/internal/locale/translations/pl_PL.json b/internal/locale/translations/pl_PL.json index 511ff7dc..3a7ad74d 100644 --- a/internal/locale/translations/pl_PL.json +++ b/internal/locale/translations/pl_PL.json @@ -35,6 +35,7 @@ "menu.about": "O stronie", "menu.export": "Eksportuj", "menu.import": "Importuj", + "menu.search": "Szukaj", "menu.create_category": "Utwórz kategorię", "menu.mark_page_as_read": "Oznacz jako przeczytane", "menu.mark_all_as_read": "Oznacz wszystko jako przeczytane", diff --git a/internal/locale/translations/pt_BR.json b/internal/locale/translations/pt_BR.json index ee1e4cd3..1e1c1b9b 100644 --- a/internal/locale/translations/pt_BR.json +++ b/internal/locale/translations/pt_BR.json @@ -35,6 +35,7 @@ "menu.about": "Sobre", "menu.export": "Exportar", "menu.import": "Importar", + "menu.search": "Buscar", "menu.create_category": "Criar uma categoria", "menu.mark_page_as_read": "Marcar essa página como lida", "menu.mark_all_as_read": "Marcar todos como lido", diff --git a/internal/locale/translations/ru_RU.json b/internal/locale/translations/ru_RU.json index a6770ed5..2c55537e 100644 --- a/internal/locale/translations/ru_RU.json +++ b/internal/locale/translations/ru_RU.json @@ -35,6 +35,7 @@ "menu.about": "О приложении", "menu.export": "Экспорт", "menu.import": "Импорт", + "menu.search": "Поиск", "menu.create_category": "Создать категорию", "menu.mark_page_as_read": "Отметить эту страницу прочитанной", "menu.mark_all_as_read": "Отметить всё как прочитанное", diff --git a/internal/locale/translations/tr_TR.json b/internal/locale/translations/tr_TR.json index 75db1237..3d8c8add 100644 --- a/internal/locale/translations/tr_TR.json +++ b/internal/locale/translations/tr_TR.json @@ -35,6 +35,7 @@ "menu.about": "Hakkında", "menu.export": "Dışarı Aktar", "menu.import": "İçeri Aktar", + "menu.search": "Ara", "menu.create_category": "Kategori oluştur", "menu.mark_page_as_read": "Bu sayfayı okundu olarak işaretle", "menu.mark_all_as_read": "Tümünü okundu olarak işaretle", diff --git a/internal/locale/translations/uk_UA.json b/internal/locale/translations/uk_UA.json index 7f324817..6bf94b09 100644 --- a/internal/locale/translations/uk_UA.json +++ b/internal/locale/translations/uk_UA.json @@ -35,6 +35,7 @@ "menu.about": "Про додаток", "menu.export": "Експорт", "menu.import": "Імпорт", + "menu.search": "Пошук", "menu.create_category": "Створити категорію", "menu.mark_page_as_read": "Відмітити цю сторінку як прочитане", "menu.mark_all_as_read": "Відмітити все як прочитане", diff --git a/internal/locale/translations/zh_CN.json b/internal/locale/translations/zh_CN.json index 13ac7ca1..1d7d2e32 100644 --- a/internal/locale/translations/zh_CN.json +++ b/internal/locale/translations/zh_CN.json @@ -35,6 +35,7 @@ "menu.about": "关于", "menu.export": "导出", "menu.import": "导入", + "menu.search": "搜索", "menu.create_category": "新建分类", "menu.mark_page_as_read": "标记为已读", "menu.mark_all_as_read": "全部标为已读", diff --git a/internal/locale/translations/zh_TW.json b/internal/locale/translations/zh_TW.json index 4d2e034a..8f748c01 100644 --- a/internal/locale/translations/zh_TW.json +++ b/internal/locale/translations/zh_TW.json @@ -35,6 +35,7 @@ "menu.about": "關於", "menu.export": "匯出", "menu.import": "匯入", + "menu.search": "搜尋", "menu.create_category": "新建分類", "menu.mark_page_as_read": "將此頁面標記為已讀", "menu.mark_all_as_read": "全部標為已讀", diff --git a/internal/template/templates/common/layout.html b/internal/template/templates/common/layout.html index 5aaf0343..d1786fc6 100644 --- a/internal/template/templates/common/layout.html +++ b/internal/template/templates/common/layout.html @@ -60,7 +60,6 @@ {{ if .user }}{{ if not .user.KeyboardShortcuts }}data-disable-keyboard-shortcuts="true"{{ end }}{{ end }}> {{ if .user }} - {{ t "skip_to_content" }}
- -
- - {{ t "search.label" }} - - -
- - -
-
-
{{ end }} {{ if .flashMessage }} diff --git a/internal/template/templates/views/search.html b/internal/template/templates/views/search.html new file mode 100644 index 00000000..c4e07774 --- /dev/null +++ b/internal/template/templates/views/search.html @@ -0,0 +1,57 @@ +{{ define "title"}}{{ t "page.search.title" }} ({{ .total }}){{ end }} + +{{ define "page_header"}} + +{{ end }} + +{{ define "content"}} + +
+ + +
+
+ +{{ if $.searchQuery }} + {{ if not .entries }} + + {{ else }} +
+ {{ template "pagination" .pagination }} +
+
+ {{ range .entries }} +
+
+

+ + {{ if ne .Feed.Icon.IconID 0 }} + {{ .Feed.Title }} + {{ else }} + {{ .Feed.Title }} + {{ end }} + {{ .Title }} + +

+ + + {{ .Feed.Category.Title }} + + +
+ {{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }} +
+ {{ end }} +
+
+ {{ template "pagination" .pagination }} +
+ {{ end }} +{{ end }} +{{ end }} diff --git a/internal/template/templates/views/search_entries.html b/internal/template/templates/views/search_entries.html deleted file mode 100644 index e9081c24..00000000 --- a/internal/template/templates/views/search_entries.html +++ /dev/null @@ -1,49 +0,0 @@ -{{ define "title"}}{{ t "page.search.title" }} ({{ .total }}){{ end }} - -{{ define "page_header"}} - -{{ end }} - -{{ define "content"}} -{{ if not .entries }} - -{{ else }} -
- {{ template "pagination" .pagination }} -
-
- {{ range .entries }} -
-
-

- - {{ if ne .Feed.Icon.IconID 0 }} - {{ .Feed.Title }} - {{ else }} - {{ .Feed.Title }} - {{ end }} - {{ .Title }} - -

- - - {{ .Feed.Category.Title }} - - -
- {{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }} -
- {{ end }} -
-
- {{ template "pagination" .pagination }} -
-{{ end }} - -{{ end }} diff --git a/internal/ui/search_entries.go b/internal/ui/search.go similarity index 60% rename from internal/ui/search_entries.go rename to internal/ui/search.go index 68df5c9b..d426411f 100644 --- a/internal/ui/search_entries.go +++ b/internal/ui/search.go @@ -14,7 +14,7 @@ import ( "miniflux.app/v2/internal/ui/view" ) -func (h *handler) showSearchEntriesPage(w http.ResponseWriter, r *http.Request) { +func (h *handler) showSearchPage(w http.ResponseWriter, r *http.Request) { user, err := h.store.UserByID(request.UserID(r)) if err != nil { html.ServerError(w, r, err) @@ -23,32 +23,38 @@ func (h *handler) showSearchEntriesPage(w http.ResponseWriter, r *http.Request) searchQuery := request.QueryStringParam(r, "q", "") offset := request.QueryIntParam(r, "offset", 0) - builder := h.store.NewEntryQueryBuilder(user.ID) - builder.WithSearchQuery(searchQuery) - builder.WithoutStatus(model.EntryStatusRemoved) - builder.WithOffset(offset) - builder.WithLimit(user.EntriesPerPage) - entries, err := builder.GetEntries() - if err != nil { - html.ServerError(w, r, err) - return - } + var entries model.Entries + var entriesCount int - count, err := builder.CountEntries() - if err != nil { - html.ServerError(w, r, err) - return + if searchQuery != "" { + builder := h.store.NewEntryQueryBuilder(user.ID) + builder.WithSearchQuery(searchQuery) + builder.WithoutStatus(model.EntryStatusRemoved) + builder.WithOffset(offset) + builder.WithLimit(user.EntriesPerPage) + + entries, err = builder.GetEntries() + if err != nil { + html.ServerError(w, r, err) + return + } + + entriesCount, err = builder.CountEntries() + if err != nil { + html.ServerError(w, r, err) + return + } } sess := session.New(h.store, request.SessionID(r)) view := view.New(h.tpl, r, sess) - pagination := getPagination(route.Path(h.router, "searchEntries"), count, offset, user.EntriesPerPage) + pagination := getPagination(route.Path(h.router, "search"), entriesCount, offset, user.EntriesPerPage) pagination.SearchQuery = searchQuery view.Set("searchQuery", searchQuery) view.Set("entries", entries) - view.Set("total", count) + view.Set("total", entriesCount) view.Set("pagination", pagination) view.Set("menu", "search") view.Set("user", user) @@ -56,5 +62,5 @@ func (h *handler) showSearchEntriesPage(w http.ResponseWriter, r *http.Request) view.Set("countErrorFeeds", h.store.CountUserFeedsWithErrors(user.ID)) view.Set("hasSaveEntry", h.store.HasSaveEntry(user.ID)) - html.OK(w, r, view.Render("search_entries")) + html.OK(w, r, view.Render("search")) } diff --git a/internal/ui/static/css/common.css b/internal/ui/static/css/common.css index 731c19c9..c3d79f59 100644 --- a/internal/ui/static/css/common.css +++ b/internal/ui/static/css/common.css @@ -29,8 +29,8 @@ h1, h2, h3 { } main { - padding-left: 5px; - padding-right: 5px; + padding-left: 3px; + padding-right: 3px; margin-bottom: 30px; } @@ -51,36 +51,36 @@ a:hover { } .sr-only { - border: 0 !important; - clip: rect(1px, 1px, 1px, 1px) !important; - -webkit-clip-path: inset(50%) !important; - clip-path: inset(50%) !important; - height: 1px !important; - overflow: hidden !important; - margin: -1px !important; - padding: 0 !important; - position: absolute !important; - width: 1px !important; - white-space: nowrap !important; + border: 0 !important; + clip: rect(1px, 1px, 1px, 1px) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + overflow: hidden !important; + margin: -1px !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; } .skip-to-content-link { - --padding-size: 8px; - --border-size: 1px; + --padding-size: 8px; + --border-size: 1px; - background-color: var(--category-background-color); - color: var(--category-color); - border: var(--border-size) solid var(--category-border-color); - border-radius: 5px; - inset-inline-start: 50%; - padding: var(--padding-size); - position: absolute; - transition: translate 0.3s; - translate: -50% calc(-100% - calc(var(--padding-size) * 2) - calc(var(--border-size) * 2)); + background-color: var(--category-background-color); + color: var(--category-color); + border: var(--border-size) solid var(--category-border-color); + border-radius: 5px; + inset-inline-start: 50%; + padding: var(--padding-size); + position: absolute; + transition: translate 0.3s; + translate: -50% calc(-100% - calc(var(--padding-size) * 2) - calc(var(--border-size) * 2)); } .skip-to-content-link:focus { - translate: -50% 0; + translate: -50% 0; } /* Header and main menu */ @@ -145,7 +145,7 @@ a:hover { /* Page header and footer*/ .page-header { - padding-inline: 5px; + padding-inline: 3px; margin-bottom: 25px; } @@ -226,44 +226,6 @@ a:hover { color: var(--logo-hover-color-span); } -/* Search form */ -.search { - text-align: center; - margin-top: 10px; - margin-right: 5px; -} - -.search-summary-icon { - padding: 5px; - inline-size: 24px; - block-size: 24px; - translate: 0 -3px; -} - -.search-details { - - &[open] .search-summary-icon { - rotate: 180deg; - } -} - -.search-summary { - list-style: none; - display: flex; - justify-content: center; - inline-size: fit-content; - margin-inline: auto; -} - -.search-summary::marker, /* Latest Chrome, Edge, Firefox */ -.search-summary::-webkit-details-marker /* Safari */ { - display: none; -} - -.search-toggle-switch { - display: none; -} - /* PWA prompt */ #prompt-home-screen { display: none; @@ -318,26 +280,33 @@ a:hover { 100% {visibility: hidden; opacity: 0; z-index: 0} } +/* Hide the logo when there is not enough space to display menus when using languages more verbose than English */ +@media (min-width: 625px) and (max-width: 830px) { + .logo { + display: none; + } +} + +@media (min-width: 830px) { + .logo { + padding-right: 8px; + } +} + @media (min-width: 620px) { body { margin: auto; - max-width: 750px; + max-width: 820px; } .header { - margin-bottom: 0; - } - - .logo { - text-align: left; - float: left; - margin-right: 15px; + padding-left: 3px; } .header li { - display: inline; + display: inline-block; padding: 0; - padding-right: 15px; + padding-right: 12px; line-height: normal; border: none; font-size: 1.0em; @@ -365,32 +334,6 @@ a:hover { display: inline; padding-right: 15px; } - - /* Search form */ - .search { - text-align: right; - display: block; - } - - .search details > summary { - margin-inline: auto 0; - } - - .search-toggle-switch { - display: block; - } - - .search-form { - display: none; - } - - .search-toggle-switch.has-search-query { - display: none; - } - - .search-form.has-search-query { - display: block; - } } /* Tables */ diff --git a/internal/ui/static/js/app.js b/internal/ui/static/js/app.js index 99145d49..599119a2 100644 --- a/internal/ui/static/js/app.js +++ b/internal/ui/static/js/app.js @@ -121,19 +121,6 @@ function handleSubmitButtons() { }); } -// Set cursor focus to the search input. -function setFocusToSearchInput(event) { - event.preventDefault(); - event.stopPropagation(); - const toggleSearchButton = document.querySelector(".search details") - if (!toggleSearchButton.getAttribute("open")) { - toggleSearchButton.setAttribute("open", "") - const searchInputElement = document.getElementById("search-input"); - searchInputElement.focus(); - searchInputElement.value = ""; - } -} - // Show modal dialog with the list of keyboard shortcuts. function showKeyboardShortcuts() { let template = document.getElementById("keyboard-shortcuts"); diff --git a/internal/ui/static/js/bootstrap.js b/internal/ui/static/js/bootstrap.js index cd11008e..fcc4d648 100644 --- a/internal/ui/static/js/bootstrap.js +++ b/internal/ui/static/js/bootstrap.js @@ -35,7 +35,7 @@ document.addEventListener("DOMContentLoaded", () => { keyboardHandler.on("?", () => showKeyboardShortcuts()); keyboardHandler.on("+", () => goToAddSubscription()); keyboardHandler.on("#", () => unsubscribeFromFeed()); - keyboardHandler.on("/", (e) => setFocusToSearchInput(e)); + keyboardHandler.on("/", () => goToPage("search")); keyboardHandler.on("a", () => { let enclosureElement = document.querySelector('.entry-enclosures'); if (enclosureElement) { diff --git a/internal/ui/static/js/keyboard_handler.js b/internal/ui/static/js/keyboard_handler.js index 3459db5d..55b72964 100644 --- a/internal/ui/static/js/keyboard_handler.js +++ b/internal/ui/static/js/keyboard_handler.js @@ -17,8 +17,7 @@ class KeyboardHandler { return; } - if (key != "Enter") - { + if (key != "Enter") { event.preventDefault(); } diff --git a/internal/ui/ui.go b/internal/ui/ui.go index 0393d33b..6d8e729c 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -57,7 +57,7 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) { uiRouter.HandleFunc("/starred/entry/{entryID}", handler.showStarredEntryPage).Name("starredEntry").Methods(http.MethodGet) // Search pages. - uiRouter.HandleFunc("/search", handler.showSearchEntriesPage).Name("searchEntries").Methods(http.MethodGet) + uiRouter.HandleFunc("/search", handler.showSearchPage).Name("search").Methods(http.MethodGet) uiRouter.HandleFunc("/search/entry/{entryID}", handler.showSearchEntryPage).Name("searchEntry").Methods(http.MethodGet) // Feed listing pages.