Move search form to a dedicated page
This commit is contained in:
parent
1b5edfc00a
commit
abdd5876a1
27 changed files with 148 additions and 199 deletions
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Über",
|
"menu.about": "Über",
|
||||||
"menu.export": "Exportieren",
|
"menu.export": "Exportieren",
|
||||||
"menu.import": "Importieren",
|
"menu.import": "Importieren",
|
||||||
|
"menu.search": "Suche",
|
||||||
"menu.create_category": "Kategorie anlegen",
|
"menu.create_category": "Kategorie anlegen",
|
||||||
"menu.mark_page_as_read": "Diese Seite als gelesen markieren",
|
"menu.mark_page_as_read": "Diese Seite als gelesen markieren",
|
||||||
"menu.mark_all_as_read": "Alle als gelesen markieren",
|
"menu.mark_all_as_read": "Alle als gelesen markieren",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Περί",
|
"menu.about": "Περί",
|
||||||
"menu.export": "Εξαγωγή",
|
"menu.export": "Εξαγωγή",
|
||||||
"menu.import": "Εισαγωγή",
|
"menu.import": "Εισαγωγή",
|
||||||
|
"menu.search": "Αναζήτηση",
|
||||||
"menu.create_category": "Δημιουργήστε μια κατηγορία",
|
"menu.create_category": "Δημιουργήστε μια κατηγορία",
|
||||||
"menu.mark_page_as_read": "Σημείωση αυτής της σελίδας ως αναγνωσμένη",
|
"menu.mark_page_as_read": "Σημείωση αυτής της σελίδας ως αναγνωσμένη",
|
||||||
"menu.mark_all_as_read": "Σημείωση όλων ως αναγνωσμένα",
|
"menu.mark_all_as_read": "Σημείωση όλων ως αναγνωσμένα",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "About",
|
"menu.about": "About",
|
||||||
"menu.export": "Export",
|
"menu.export": "Export",
|
||||||
"menu.import": "Import",
|
"menu.import": "Import",
|
||||||
|
"menu.search": "Search",
|
||||||
"menu.create_category": "Create a category",
|
"menu.create_category": "Create a category",
|
||||||
"menu.mark_page_as_read": "Mark this page as read",
|
"menu.mark_page_as_read": "Mark this page as read",
|
||||||
"menu.mark_all_as_read": "Mark all as read",
|
"menu.mark_all_as_read": "Mark all as read",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Acerca de",
|
"menu.about": "Acerca de",
|
||||||
"menu.export": "Exportar",
|
"menu.export": "Exportar",
|
||||||
"menu.import": "Importar",
|
"menu.import": "Importar",
|
||||||
|
"menu.search": "Buscar",
|
||||||
"menu.create_category": "Crear una categoría",
|
"menu.create_category": "Crear una categoría",
|
||||||
"menu.mark_page_as_read": "Marcar esta página como leída",
|
"menu.mark_page_as_read": "Marcar esta página como leída",
|
||||||
"menu.mark_all_as_read": "Marcar todos como leídos",
|
"menu.mark_all_as_read": "Marcar todos como leídos",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Tietoja",
|
"menu.about": "Tietoja",
|
||||||
"menu.export": "Vie",
|
"menu.export": "Vie",
|
||||||
"menu.import": "Tuo",
|
"menu.import": "Tuo",
|
||||||
|
"menu.search": "Haku",
|
||||||
"menu.create_category": "Luo kategoria",
|
"menu.create_category": "Luo kategoria",
|
||||||
"menu.mark_page_as_read": "Merkitse tämä sivu luetuksi",
|
"menu.mark_page_as_read": "Merkitse tämä sivu luetuksi",
|
||||||
"menu.mark_all_as_read": "Merkitse kaikki luetuksi",
|
"menu.mark_all_as_read": "Merkitse kaikki luetuksi",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "À propos",
|
"menu.about": "À propos",
|
||||||
"menu.export": "Export",
|
"menu.export": "Export",
|
||||||
"menu.import": "Import",
|
"menu.import": "Import",
|
||||||
|
"menu.search": "Recherche",
|
||||||
"menu.create_category": "Créer une catégorie",
|
"menu.create_category": "Créer une catégorie",
|
||||||
"menu.mark_page_as_read": "Marquer cette page comme lu",
|
"menu.mark_page_as_read": "Marquer cette page comme lu",
|
||||||
"menu.mark_all_as_read": "Tout marquer comme lu",
|
"menu.mark_all_as_read": "Tout marquer comme lu",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "के बारे में",
|
"menu.about": "के बारे में",
|
||||||
"menu.export": "निर्यात करे",
|
"menu.export": "निर्यात करे",
|
||||||
"menu.import": "आयात करे",
|
"menu.import": "आयात करे",
|
||||||
|
"menu.search": "खोज",
|
||||||
"menu.create_category": "श्रेणी बनाए",
|
"menu.create_category": "श्रेणी बनाए",
|
||||||
"menu.mark_page_as_read": "इस पृष्ठ को पढ़ा हुआ चिह्नित करें",
|
"menu.mark_page_as_read": "इस पृष्ठ को पढ़ा हुआ चिह्नित करें",
|
||||||
"menu.mark_all_as_read": "सभी को पढ़ा हुआ मार्क करें",
|
"menu.mark_all_as_read": "सभी को पढ़ा हुआ मार्क करें",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Tentang",
|
"menu.about": "Tentang",
|
||||||
"menu.export": "Ekspor",
|
"menu.export": "Ekspor",
|
||||||
"menu.import": "Impor",
|
"menu.import": "Impor",
|
||||||
|
"menu.search": "Cari",
|
||||||
"menu.create_category": "Buat kategori",
|
"menu.create_category": "Buat kategori",
|
||||||
"menu.mark_page_as_read": "Tandai halaman ini sebagai telah dibaca",
|
"menu.mark_page_as_read": "Tandai halaman ini sebagai telah dibaca",
|
||||||
"menu.mark_all_as_read": "Tandai semua sebagai telah dibaca",
|
"menu.mark_all_as_read": "Tandai semua sebagai telah dibaca",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Informazioni",
|
"menu.about": "Informazioni",
|
||||||
"menu.export": "Esporta",
|
"menu.export": "Esporta",
|
||||||
"menu.import": "Importa",
|
"menu.import": "Importa",
|
||||||
|
"menu.search": "Cerca",
|
||||||
"menu.create_category": "Aggiungi una categoria",
|
"menu.create_category": "Aggiungi una categoria",
|
||||||
"menu.mark_page_as_read": "Segna questa pagina come letta",
|
"menu.mark_page_as_read": "Segna questa pagina come letta",
|
||||||
"menu.mark_all_as_read": "Segna tutti gli articoli come letti",
|
"menu.mark_all_as_read": "Segna tutti gli articoli come letti",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "ソフトウェア情報",
|
"menu.about": "ソフトウェア情報",
|
||||||
"menu.export": "エクスポート",
|
"menu.export": "エクスポート",
|
||||||
"menu.import": "インポート",
|
"menu.import": "インポート",
|
||||||
|
"menu.search": "検索",
|
||||||
"menu.create_category": "カテゴリを作成",
|
"menu.create_category": "カテゴリを作成",
|
||||||
"menu.mark_page_as_read": "このページを既読にする",
|
"menu.mark_page_as_read": "このページを既読にする",
|
||||||
"menu.mark_all_as_read": "すべて既読にする",
|
"menu.mark_all_as_read": "すべて既読にする",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Over",
|
"menu.about": "Over",
|
||||||
"menu.export": "Exporteren",
|
"menu.export": "Exporteren",
|
||||||
"menu.import": "Importeren",
|
"menu.import": "Importeren",
|
||||||
|
"menu.search": "Zoeken",
|
||||||
"menu.create_category": "Categorie toevoegen",
|
"menu.create_category": "Categorie toevoegen",
|
||||||
"menu.mark_page_as_read": "Markeer deze pagina als gelezen",
|
"menu.mark_page_as_read": "Markeer deze pagina als gelezen",
|
||||||
"menu.mark_all_as_read": "Markeer alle items als gelezen",
|
"menu.mark_all_as_read": "Markeer alle items als gelezen",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "O stronie",
|
"menu.about": "O stronie",
|
||||||
"menu.export": "Eksportuj",
|
"menu.export": "Eksportuj",
|
||||||
"menu.import": "Importuj",
|
"menu.import": "Importuj",
|
||||||
|
"menu.search": "Szukaj",
|
||||||
"menu.create_category": "Utwórz kategorię",
|
"menu.create_category": "Utwórz kategorię",
|
||||||
"menu.mark_page_as_read": "Oznacz jako przeczytane",
|
"menu.mark_page_as_read": "Oznacz jako przeczytane",
|
||||||
"menu.mark_all_as_read": "Oznacz wszystko jako przeczytane",
|
"menu.mark_all_as_read": "Oznacz wszystko jako przeczytane",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Sobre",
|
"menu.about": "Sobre",
|
||||||
"menu.export": "Exportar",
|
"menu.export": "Exportar",
|
||||||
"menu.import": "Importar",
|
"menu.import": "Importar",
|
||||||
|
"menu.search": "Buscar",
|
||||||
"menu.create_category": "Criar uma categoria",
|
"menu.create_category": "Criar uma categoria",
|
||||||
"menu.mark_page_as_read": "Marcar essa página como lida",
|
"menu.mark_page_as_read": "Marcar essa página como lida",
|
||||||
"menu.mark_all_as_read": "Marcar todos como lido",
|
"menu.mark_all_as_read": "Marcar todos como lido",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "О приложении",
|
"menu.about": "О приложении",
|
||||||
"menu.export": "Экспорт",
|
"menu.export": "Экспорт",
|
||||||
"menu.import": "Импорт",
|
"menu.import": "Импорт",
|
||||||
|
"menu.search": "Поиск",
|
||||||
"menu.create_category": "Создать категорию",
|
"menu.create_category": "Создать категорию",
|
||||||
"menu.mark_page_as_read": "Отметить эту страницу прочитанной",
|
"menu.mark_page_as_read": "Отметить эту страницу прочитанной",
|
||||||
"menu.mark_all_as_read": "Отметить всё как прочитанное",
|
"menu.mark_all_as_read": "Отметить всё как прочитанное",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Hakkında",
|
"menu.about": "Hakkında",
|
||||||
"menu.export": "Dışarı Aktar",
|
"menu.export": "Dışarı Aktar",
|
||||||
"menu.import": "İçeri Aktar",
|
"menu.import": "İçeri Aktar",
|
||||||
|
"menu.search": "Ara",
|
||||||
"menu.create_category": "Kategori oluştur",
|
"menu.create_category": "Kategori oluştur",
|
||||||
"menu.mark_page_as_read": "Bu sayfayı okundu olarak işaretle",
|
"menu.mark_page_as_read": "Bu sayfayı okundu olarak işaretle",
|
||||||
"menu.mark_all_as_read": "Tümünü okundu olarak işaretle",
|
"menu.mark_all_as_read": "Tümünü okundu olarak işaretle",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "Про додаток",
|
"menu.about": "Про додаток",
|
||||||
"menu.export": "Експорт",
|
"menu.export": "Експорт",
|
||||||
"menu.import": "Імпорт",
|
"menu.import": "Імпорт",
|
||||||
|
"menu.search": "Пошук",
|
||||||
"menu.create_category": "Створити категорію",
|
"menu.create_category": "Створити категорію",
|
||||||
"menu.mark_page_as_read": "Відмітити цю сторінку як прочитане",
|
"menu.mark_page_as_read": "Відмітити цю сторінку як прочитане",
|
||||||
"menu.mark_all_as_read": "Відмітити все як прочитане",
|
"menu.mark_all_as_read": "Відмітити все як прочитане",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "关于",
|
"menu.about": "关于",
|
||||||
"menu.export": "导出",
|
"menu.export": "导出",
|
||||||
"menu.import": "导入",
|
"menu.import": "导入",
|
||||||
|
"menu.search": "搜索",
|
||||||
"menu.create_category": "新建分类",
|
"menu.create_category": "新建分类",
|
||||||
"menu.mark_page_as_read": "标记为已读",
|
"menu.mark_page_as_read": "标记为已读",
|
||||||
"menu.mark_all_as_read": "全部标为已读",
|
"menu.mark_all_as_read": "全部标为已读",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"menu.about": "關於",
|
"menu.about": "關於",
|
||||||
"menu.export": "匯出",
|
"menu.export": "匯出",
|
||||||
"menu.import": "匯入",
|
"menu.import": "匯入",
|
||||||
|
"menu.search": "搜尋",
|
||||||
"menu.create_category": "新建分類",
|
"menu.create_category": "新建分類",
|
||||||
"menu.mark_page_as_read": "將此頁面標記為已讀",
|
"menu.mark_page_as_read": "將此頁面標記為已讀",
|
||||||
"menu.mark_all_as_read": "全部標為已讀",
|
"menu.mark_all_as_read": "全部標為已讀",
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
{{ if .user }}{{ if not .user.KeyboardShortcuts }}data-disable-keyboard-shortcuts="true"{{ end }}{{ end }}>
|
{{ if .user }}{{ if not .user.KeyboardShortcuts }}data-disable-keyboard-shortcuts="true"{{ end }}{{ end }}>
|
||||||
|
|
||||||
{{ if .user }}
|
{{ if .user }}
|
||||||
|
|
||||||
<a class="skip-to-content-link" href="#main">{{ t "skip_to_content" }}</a>
|
<a class="skip-to-content-link" href="#main">{{ t "skip_to_content" }}</a>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<nav>
|
<nav>
|
||||||
|
@ -105,6 +104,9 @@
|
||||||
<li {{ if eq .menu "categories" }}class="active"{{ end }} title="{{ t "tooltip.keyboard_shortcuts" "g c" }}">
|
<li {{ if eq .menu "categories" }}class="active"{{ end }} title="{{ t "tooltip.keyboard_shortcuts" "g c" }}">
|
||||||
<a href="{{ route "categories" }}" data-page="categories">{{ t "menu.categories" }}</a>
|
<a href="{{ route "categories" }}" data-page="categories">{{ t "menu.categories" }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li {{ if eq .menu "search" }}class="active"{{ end }} title="{{ t "tooltip.keyboard_shortcuts" "/" }}">
|
||||||
|
<a href="{{ route "search" }}" data-page="search">{{ t "menu.search" }}</a>
|
||||||
|
</li>
|
||||||
<li {{ if eq .menu "settings" }}class="active"{{ end }} title="{{ t "tooltip.keyboard_shortcuts" "g s" }}">
|
<li {{ if eq .menu "settings" }}class="active"{{ end }} title="{{ t "tooltip.keyboard_shortcuts" "g s" }}">
|
||||||
<a href="{{ route "settings" }}" data-page="settings">{{ t "menu.settings" }}</a>
|
<a href="{{ route "settings" }}" data-page="settings">{{ t "menu.settings" }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -115,20 +117,6 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<search role="search" class="search">
|
|
||||||
<details class="search-details" {{ if $.searchQuery }}open{{ end }}>
|
|
||||||
<summary class="search-summary">
|
|
||||||
<span>{{ t "search.label" }}</span>
|
|
||||||
<svg class="bi bi-chevron-down search-summary-icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
|
|
||||||
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708"/>
|
|
||||||
</svg>
|
|
||||||
</summary>
|
|
||||||
<form action="{{ route "searchEntries" }}" aria-labelledby="search-input-label">
|
|
||||||
<input type="search" name="q" id="search-input" aria-label="{{ t "search.label" }}" placeholder="{{ t "search.placeholder" }}" {{ if $.searchQuery }}value="{{ .searchQuery }}"{{ end }} required>
|
|
||||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.loading" }}">{{ t "search.submit" }}</button>
|
|
||||||
</form>
|
|
||||||
</details>
|
|
||||||
</search>
|
|
||||||
</header>
|
</header>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if .flashMessage }}
|
{{ if .flashMessage }}
|
||||||
|
|
57
internal/template/templates/views/search.html
Normal file
57
internal/template/templates/views/search.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{{ define "title"}}{{ t "page.search.title" }} ({{ .total }}){{ end }}
|
||||||
|
|
||||||
|
{{ define "page_header"}}
|
||||||
|
<section class="page-header" aria-labelledby="page-header-title">
|
||||||
|
<h1 id="page-header-title">{{ t "page.search.title" }} ({{ .total }})</h1>
|
||||||
|
</section>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "content"}}
|
||||||
|
<search role="search">
|
||||||
|
<form action="{{ route "search" }}" aria-labelledby="search-input-label">
|
||||||
|
<input type="search" name="q" id="search-input" aria-label="{{ t "search.label" }}" placeholder="{{ t "search.placeholder" }}" {{ if $.searchQuery }}value="{{ .searchQuery }}"{{ else }}autofocus{{ end }} required>
|
||||||
|
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.loading" }}">{{ t "search.submit" }}</button>
|
||||||
|
</form>
|
||||||
|
</search>
|
||||||
|
|
||||||
|
{{ if $.searchQuery }}
|
||||||
|
{{ if not .entries }}
|
||||||
|
<p role="alert" class="alert alert-info">{{ t "alert.no_search_result" }}</p>
|
||||||
|
{{ else }}
|
||||||
|
<div class="pagination-top">
|
||||||
|
{{ template "pagination" .pagination }}
|
||||||
|
</div>
|
||||||
|
<div class="items">
|
||||||
|
{{ range .entries }}
|
||||||
|
<article
|
||||||
|
class="item entry-item {{ if $.user.EntrySwipe }}entry-swipe{{ end }} item-status-{{ .Status }}"
|
||||||
|
data-id="{{ .ID }}"
|
||||||
|
aria-labelledby="entry-title-{{ .ID }}"
|
||||||
|
>
|
||||||
|
<header class="item-header" dir="auto">
|
||||||
|
<h2 id="entry-title-{{ .ID }}" class="item-title">
|
||||||
|
<a href="{{ route "searchEntry" "entryID" .ID }}?q={{ $.searchQuery }}">
|
||||||
|
{{ if ne .Feed.Icon.IconID 0 }}
|
||||||
|
<img src="{{ route "icon" "iconID" .Feed.Icon.IconID }}" width="16" height="16" loading="lazy" alt="{{ .Feed.Title }}">
|
||||||
|
{{ else }}
|
||||||
|
<span class="sr-only">{{ .Feed.Title }}</span>
|
||||||
|
{{ end }}
|
||||||
|
{{ .Title }}
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
<span class="category">
|
||||||
|
<a href="{{ route "categoryEntries" "categoryID" .Feed.Category.ID }}">
|
||||||
|
{{ .Feed.Category.Title }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</header>
|
||||||
|
{{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }}
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div class="pagination-bottom">
|
||||||
|
{{ template "pagination" .pagination }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
|
@ -1,49 +0,0 @@
|
||||||
{{ define "title"}}{{ t "page.search.title" }} ({{ .total }}){{ end }}
|
|
||||||
|
|
||||||
{{ define "page_header"}}
|
|
||||||
<section class="page-header" aria-labelledby="page-header-title">
|
|
||||||
<h1 id="page-header-title">{{ t "page.search.title" }} ({{ .total }})</h1>
|
|
||||||
</section>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "content"}}
|
|
||||||
{{ if not .entries }}
|
|
||||||
<p role="alert" class="alert alert-info">{{ t "alert.no_search_result" }}</p>
|
|
||||||
{{ else }}
|
|
||||||
<div class="pagination-top">
|
|
||||||
{{ template "pagination" .pagination }}
|
|
||||||
</div>
|
|
||||||
<div class="items">
|
|
||||||
{{ range .entries }}
|
|
||||||
<article
|
|
||||||
class="item entry-item {{ if $.user.EntrySwipe }}entry-swipe{{ end }} item-status-{{ .Status }}"
|
|
||||||
data-id="{{ .ID }}"
|
|
||||||
aria-labelledby="entry-title-{{ .ID }}"
|
|
||||||
>
|
|
||||||
<header class="item-header" dir="auto">
|
|
||||||
<h2 id="entry-title-{{ .ID }}" class="item-title">
|
|
||||||
<a href="{{ route "searchEntry" "entryID" .ID }}?q={{ $.searchQuery }}">
|
|
||||||
{{ if ne .Feed.Icon.IconID 0 }}
|
|
||||||
<img src="{{ route "icon" "iconID" .Feed.Icon.IconID }}" width="16" height="16" loading="lazy" alt="{{ .Feed.Title }}">
|
|
||||||
{{ else }}
|
|
||||||
<span class="sr-only">{{ .Feed.Title }}</span>
|
|
||||||
{{ end }}
|
|
||||||
{{ .Title }}
|
|
||||||
</a>
|
|
||||||
</h2>
|
|
||||||
<span class="category">
|
|
||||||
<a href="{{ route "categoryEntries" "categoryID" .Feed.Category.ID }}">
|
|
||||||
{{ .Feed.Category.Title }}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</header>
|
|
||||||
{{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }}
|
|
||||||
</article>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
<div class="pagination-bottom">
|
|
||||||
{{ template "pagination" .pagination }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"miniflux.app/v2/internal/ui/view"
|
"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))
|
user, err := h.store.UserByID(request.UserID(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
html.ServerError(w, r, err)
|
html.ServerError(w, r, err)
|
||||||
|
@ -23,32 +23,38 @@ func (h *handler) showSearchEntriesPage(w http.ResponseWriter, r *http.Request)
|
||||||
|
|
||||||
searchQuery := request.QueryStringParam(r, "q", "")
|
searchQuery := request.QueryStringParam(r, "q", "")
|
||||||
offset := request.QueryIntParam(r, "offset", 0)
|
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()
|
var entries model.Entries
|
||||||
if err != nil {
|
var entriesCount int
|
||||||
html.ServerError(w, r, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
count, err := builder.CountEntries()
|
if searchQuery != "" {
|
||||||
if err != nil {
|
builder := h.store.NewEntryQueryBuilder(user.ID)
|
||||||
html.ServerError(w, r, err)
|
builder.WithSearchQuery(searchQuery)
|
||||||
return
|
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))
|
sess := session.New(h.store, request.SessionID(r))
|
||||||
view := view.New(h.tpl, r, sess)
|
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
|
pagination.SearchQuery = searchQuery
|
||||||
|
|
||||||
view.Set("searchQuery", searchQuery)
|
view.Set("searchQuery", searchQuery)
|
||||||
view.Set("entries", entries)
|
view.Set("entries", entries)
|
||||||
view.Set("total", count)
|
view.Set("total", entriesCount)
|
||||||
view.Set("pagination", pagination)
|
view.Set("pagination", pagination)
|
||||||
view.Set("menu", "search")
|
view.Set("menu", "search")
|
||||||
view.Set("user", user)
|
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("countErrorFeeds", h.store.CountUserFeedsWithErrors(user.ID))
|
||||||
view.Set("hasSaveEntry", h.store.HasSaveEntry(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"))
|
||||||
}
|
}
|
|
@ -29,8 +29,8 @@ h1, h2, h3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
padding-left: 5px;
|
padding-left: 3px;
|
||||||
padding-right: 5px;
|
padding-right: 3px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,36 +51,36 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sr-only {
|
.sr-only {
|
||||||
border: 0 !important;
|
border: 0 !important;
|
||||||
clip: rect(1px, 1px, 1px, 1px) !important;
|
clip: rect(1px, 1px, 1px, 1px) !important;
|
||||||
-webkit-clip-path: inset(50%) !important;
|
-webkit-clip-path: inset(50%) !important;
|
||||||
clip-path: inset(50%) !important;
|
clip-path: inset(50%) !important;
|
||||||
height: 1px !important;
|
height: 1px !important;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
margin: -1px !important;
|
margin: -1px !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
width: 1px !important;
|
width: 1px !important;
|
||||||
white-space: nowrap !important;
|
white-space: nowrap !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skip-to-content-link {
|
.skip-to-content-link {
|
||||||
--padding-size: 8px;
|
--padding-size: 8px;
|
||||||
--border-size: 1px;
|
--border-size: 1px;
|
||||||
|
|
||||||
background-color: var(--category-background-color);
|
background-color: var(--category-background-color);
|
||||||
color: var(--category-color);
|
color: var(--category-color);
|
||||||
border: var(--border-size) solid var(--category-border-color);
|
border: var(--border-size) solid var(--category-border-color);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
inset-inline-start: 50%;
|
inset-inline-start: 50%;
|
||||||
padding: var(--padding-size);
|
padding: var(--padding-size);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transition: translate 0.3s;
|
transition: translate 0.3s;
|
||||||
translate: -50% calc(-100% - calc(var(--padding-size) * 2) - calc(var(--border-size) * 2));
|
translate: -50% calc(-100% - calc(var(--padding-size) * 2) - calc(var(--border-size) * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
.skip-to-content-link:focus {
|
.skip-to-content-link:focus {
|
||||||
translate: -50% 0;
|
translate: -50% 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header and main menu */
|
/* Header and main menu */
|
||||||
|
@ -145,7 +145,7 @@ a:hover {
|
||||||
|
|
||||||
/* Page header and footer*/
|
/* Page header and footer*/
|
||||||
.page-header {
|
.page-header {
|
||||||
padding-inline: 5px;
|
padding-inline: 3px;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,44 +226,6 @@ a:hover {
|
||||||
color: var(--logo-hover-color-span);
|
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 */
|
/* PWA prompt */
|
||||||
#prompt-home-screen {
|
#prompt-home-screen {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -318,26 +280,33 @@ a:hover {
|
||||||
100% {visibility: hidden; opacity: 0; z-index: 0}
|
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) {
|
@media (min-width: 620px) {
|
||||||
body {
|
body {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 750px;
|
max-width: 820px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
margin-bottom: 0;
|
padding-left: 3px;
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
text-align: left;
|
|
||||||
float: left;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header li {
|
.header li {
|
||||||
display: inline;
|
display: inline-block;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-right: 15px;
|
padding-right: 12px;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 1.0em;
|
font-size: 1.0em;
|
||||||
|
@ -365,32 +334,6 @@ a:hover {
|
||||||
display: inline;
|
display: inline;
|
||||||
padding-right: 15px;
|
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 */
|
/* Tables */
|
||||||
|
|
|
@ -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.
|
// Show modal dialog with the list of keyboard shortcuts.
|
||||||
function showKeyboardShortcuts() {
|
function showKeyboardShortcuts() {
|
||||||
let template = document.getElementById("keyboard-shortcuts");
|
let template = document.getElementById("keyboard-shortcuts");
|
||||||
|
|
2
internal/ui/static/js/bootstrap.js
vendored
2
internal/ui/static/js/bootstrap.js
vendored
|
@ -35,7 +35,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
keyboardHandler.on("?", () => showKeyboardShortcuts());
|
keyboardHandler.on("?", () => showKeyboardShortcuts());
|
||||||
keyboardHandler.on("+", () => goToAddSubscription());
|
keyboardHandler.on("+", () => goToAddSubscription());
|
||||||
keyboardHandler.on("#", () => unsubscribeFromFeed());
|
keyboardHandler.on("#", () => unsubscribeFromFeed());
|
||||||
keyboardHandler.on("/", (e) => setFocusToSearchInput(e));
|
keyboardHandler.on("/", () => goToPage("search"));
|
||||||
keyboardHandler.on("a", () => {
|
keyboardHandler.on("a", () => {
|
||||||
let enclosureElement = document.querySelector('.entry-enclosures');
|
let enclosureElement = document.querySelector('.entry-enclosures');
|
||||||
if (enclosureElement) {
|
if (enclosureElement) {
|
||||||
|
|
|
@ -17,8 +17,7 @@ class KeyboardHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key != "Enter")
|
if (key != "Enter") {
|
||||||
{
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
uiRouter.HandleFunc("/starred/entry/{entryID}", handler.showStarredEntryPage).Name("starredEntry").Methods(http.MethodGet)
|
||||||
|
|
||||||
// Search pages.
|
// 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)
|
uiRouter.HandleFunc("/search/entry/{entryID}", handler.showSearchEntryPage).Name("searchEntry").Methods(http.MethodGet)
|
||||||
|
|
||||||
// Feed listing pages.
|
// Feed listing pages.
|
||||||
|
|
Loading…
Reference in a new issue