From d03e000bd1b05bc2266e1c66f2649804f8f7fd83 Mon Sep 17 00:00:00 2001 From: mrdrogdrog Date: Thu, 21 May 2020 22:01:23 +0200 Subject: [PATCH] Feature/history toolbar (#44) Add the history bar --- package.json | 2 + public/locales/ar.json | 16 +-- public/locales/ca.json | 16 +-- public/locales/cs.json | 16 +-- public/locales/da.json | 16 +-- public/locales/de.json | 16 +-- public/locales/el.json | 16 +-- public/locales/en.json | 23 ++-- public/locales/eo.json | 16 +-- public/locales/es.json | 16 +-- public/locales/fr.json | 16 +-- public/locales/hi.json | 16 +-- public/locales/hr.json | 16 +-- public/locales/id.json | 16 +-- public/locales/it.json | 16 +-- public/locales/ja.json | 16 +-- public/locales/ko.json | 16 +-- public/locales/nl.json | 16 +-- public/locales/pl.json | 16 +-- public/locales/pt.json | 16 +-- public/locales/ru.json | 16 +-- public/locales/sk.json | 16 +-- public/locales/sr.json | 16 +-- public/locales/sv.json | 16 +-- public/locales/tr.json | 16 +-- public/locales/uk.json | 16 +-- public/locales/vi.json | 16 +-- public/locales/zh-CN.json | 16 +-- public/locales/zh-TW.json | 16 +-- src/components/icon-button/icon-button.scss | 20 +++ src/components/icon-button/icon-button.tsx | 24 ++++ .../landing/layout/style/index.scss | 1 + .../pages/history/common/close-button.tsx | 19 ++- .../pages/history/common/pin-button.tsx | 20 +-- .../history/history-card/history-card.tsx | 9 +- .../history-content/history-content.tsx | 3 +- .../history-table/history-table-row.tsx | 4 +- .../history/history-table/history-table.tsx | 7 +- .../history-toolbar/history-toolbar.tsx | 128 ++++++++++++++++++ .../history-toolbar/typeahead-hacks.scss | 11 ++ .../landing/pages/history/history.tsx | 34 +++-- .../social-link-button.scss} | 29 ++-- .../social-link-button.tsx} | 10 +- .../pages/login/auth/via-one-click.tsx | 6 +- src/components/sort-button/sort-button.tsx | 47 +++++++ src/initializers/fontAwesome.ts | 8 +- src/utils/historyUtils.ts | 53 ++++++-- yarn.lock | 94 ++++++++++++- 48 files changed, 681 insertions(+), 303 deletions(-) create mode 100644 src/components/icon-button/icon-button.scss create mode 100644 src/components/icon-button/icon-button.tsx create mode 100644 src/components/landing/pages/history/history-toolbar/history-toolbar.tsx create mode 100644 src/components/landing/pages/history/history-toolbar/typeahead-hacks.scss rename src/components/landing/pages/login/auth/{icon-button/icon-button.scss => social-link-button/social-link-button.scss} (68%) rename src/components/landing/pages/login/auth/{icon-button/icon-button.tsx => social-link-button/social-link-button.tsx} (55%) create mode 100644 src/components/sort-button/sort-button.tsx diff --git a/package.json b/package.json index 4dd04ab9d..040871128 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@types/node-sass": "^4.11.0", "@types/react": "^16.9.34", "@types/react-bootstrap": "^1.0.1", + "@types/react-bootstrap-typeahead": "^3.4.6", "@types/react-dom": "^16.9.0", "@types/react-redux": "^7.1.8", "@types/react-router": "^5.1.7", @@ -27,6 +28,7 @@ "node-sass": "^4.14.1", "react": "^16.13.1", "react-bootstrap": "^1.0.1", + "react-bootstrap-typeahead": "^5.0.0-rc.1", "react-dom": "^16.13.1", "react-i18next": "^11.4.0", "react-redux": "^7.2.0", diff --git a/public/locales/ar.json b/public/locales/ar.json index b7f967438..fbed2b271 100644 --- a/public/locales/ar.json +++ b/public/locales/ar.json @@ -15,16 +15,16 @@ "or": "أو", "signOut": "خروج", "exploreFeatures": "استكشف جميع الميزات", - "Select tags...": "اختر كلمات مفتاحية...", - "Search keyword...": "البحث عن كلمة مفتاحية...", - "Sort by title": "الترتيب حسب العنوان", + "selectTags": "اختر كلمات مفتاحية...", + "searchKeywords": "البحث عن كلمة مفتاحية...", + "sortByTitle": "الترتيب حسب العنوان", "Title": "العنوان", - "Sort by time": "فرز حسب الوقت", + "sortByLastVisited": "فرز حسب الوقت", "Time": "الزمن", - "Export history": "تصدير التاريخ", - "Import history": "استيراد التاريخ", - "Clear history": "مسح التاريخ", - "Refresh history": "حدث التاريخ", + "exportHistory": "تصدير التاريخ", + "importHistory": "استيراد التاريخ", + "clearHistory": "مسح التاريخ", + "refreshHistory": "حدث التاريخ", "noHistory": "ليس هناك سِجِل", "Import from browser": "استيراد من المتصفح", "releases": "إصدارات", diff --git a/public/locales/ca.json b/public/locales/ca.json index a0bc835ff..127db5fa1 100644 --- a/public/locales/ca.json +++ b/public/locales/ca.json @@ -15,16 +15,16 @@ "or": "o", "signOut": "Sortir", "exploreFeatures": "Explorar totes les funcions", - "Select tags...": "Seleccionar etiquetes...", - "Search keyword...": "Buscar paraules clau...", - "Sort by title": "Ordenar per títol", + "selectTags": "Seleccionar etiquetes...", + "searchKeywords": "Buscar paraules clau...", + "sortByTitle": "Ordenar per títol", "Title": "Títol", - "Sort by time": "Ordenar per hora", + "sortByLastVisited": "Ordenar per hora", "Time": "Tiempo", - "Export history": "Exportar historial", - "Import history": "Importar historial", - "Clear history": "Borrar historial", - "Refresh history": "Actualitzar historial", + "exportHistory": "Exportar historial", + "importHistory": "Importar historial", + "clearHistory": "Borrar historial", + "refreshHistory": "Actualitzar historial", "noHistory": "Cap historial", "Import from browser": "Importar del navegador", "releases": "Versions", diff --git a/public/locales/cs.json b/public/locales/cs.json index 9993af1c5..22245b20c 100644 --- a/public/locales/cs.json +++ b/public/locales/cs.json @@ -15,16 +15,16 @@ "or": "nebo", "signOut": "Odhlásit", "exploreFeatures": "Prozkoumat všechny funkce", - "Select tags...": "Zvolit štítky…", - "Search keyword...": "Vyhledat klíčové slovo …", - "Sort by title": "Seřadit podle názvu", + "selectTags": "Zvolit štítky…", + "searchKeywords": "Vyhledat klíčové slovo …", + "sortByTitle": "Seřadit podle názvu", "Title": "Název", - "Sort by time": "Seřadit podle času", + "sortByLastVisited": "Seřadit podle času", "Time": "Čas", - "Export history": "Exportovat historii", - "Import history": "Importovat historii", - "Clear history": "Odstranit historii", - "Refresh history": "Aktualizovat historii", + "exportHistory": "Exportovat historii", + "importHistory": "Importovat historii", + "clearHistory": "Odstranit historii", + "refreshHistory": "Aktualizovat historii", "noHistory": "Žádná historie", "Import from browser": "Importovat z prohlížeče", "releases": "Vydání", diff --git a/public/locales/da.json b/public/locales/da.json index 0f79ee827..9fffb1f2f 100644 --- a/public/locales/da.json +++ b/public/locales/da.json @@ -15,16 +15,16 @@ "or": "eller", "signOut": " Log Ud", "exploreFeatures": "Udforsk alle features", - "Select tags...": "Vælg tags...", - "Search keyword...": "Søg nøgleord...", - "Sort by title": "Sortér titler", + "selectTags": "Vælg tags...", + "searchKeywords": "Søg nøgleord...", + "sortByTitle": "Sortér titler", "Title": "Titel", - "Sort by time": "Sortér kronologisk", + "sortByLastVisited": "Sortér kronologisk", "Time": "Tid", - "Export history": "Eksportér historik", - "Import history": "Importér historik", - "Clear history": "Ryd hsitorik", - "Refresh history": "Genindlæs historik", + "exportHistory": "Eksportér historik", + "importHistory": "Importér historik", + "clearHistory": "Ryd hsitorik", + "refreshHistory": "Genindlæs historik", "noHistory": "Ingen historik", "Import from browser": "Importér fra browser", "releases": "Releases", diff --git a/public/locales/de.json b/public/locales/de.json index 58f2e4094..f9899e4df 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -15,16 +15,16 @@ "or": "oder", "signOut": "Ausloggen", "exploreFeatures": "Alle Funktionen", - "Select tags...": "Tags auswählen ...", - "Search keyword...": "Suche nach Stichwort ...", - "Sort by title": "Nach Titel sortieren", + "selectTags": "Tags auswählen ...", + "searchKeywords": "Suche nach Stichwort ...", + "sortByTitle": "Nach Titel sortieren", "Title": "Titel", - "Sort by time": "Nach Uhrzeit sortieren", + "sortByLastVisited": "Nach Uhrzeit sortieren", "Time": "Uhrzeit", - "Export history": "Verlauf exportieren", - "Import history": "Verlauf importieren", - "Clear history": "Verlauf löschen", - "Refresh history": "Verlauf aktualisieren", + "exportHistory": "Verlauf exportieren", + "importHistory": "Verlauf importieren", + "clearHistory": "Verlauf löschen", + "refreshHistory": "Verlauf aktualisieren", "noHistory": "Kein Verlauf", "Import from browser": "Vom Browser importieren", "releases": "Versionen", diff --git a/public/locales/el.json b/public/locales/el.json index e6c28ceda..b38e50f93 100644 --- a/public/locales/el.json +++ b/public/locales/el.json @@ -15,16 +15,16 @@ "or": "ή", "signOut": "Αποσύνδεση", "exploreFeatures": "Ανακαλύψτε όλες τις λειτουργίες", - "Select tags...": "Επιλέξτε ετικέτα...", - "Search keyword...": "Αναζήτηση λέξης-κλειδί...", - "Sort by title": "Ταξινόμηση κατά τίτλο", + "selectTags": "Επιλέξτε ετικέτα...", + "searchKeywords": "Αναζήτηση λέξης-κλειδί...", + "sortByTitle": "Ταξινόμηση κατά τίτλο", "Title": "Τίτλος", - "Sort by time": "Ταξινόμηση κατά ώρα", + "sortByLastVisited": "Ταξινόμηση κατά ώρα", "Time": "Ώρα", - "Export history": "Εξαγωγή ιστορίας", - "Import history": "Εισαγωγή ιστορίας", - "Clear history": "Καθαρισμός Ιστορίας", - "Refresh history": "Ανανέωση ιστορίας", + "exportHistory": "Εξαγωγή ιστορίας", + "importHistory": "Εισαγωγή ιστορίας", + "clearHistory": "Καθαρισμός Ιστορίας", + "refreshHistory": "Ανανέωση ιστορίας", "noHistory": "Δεν υπάρχει ιστορία", "Import from browser": "Εισαγωγή απο τον περιηγητή", "releases": "Κυκλοφορίες", diff --git a/public/locales/en.json b/public/locales/en.json index 60df87efd..b744948a5 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -15,16 +15,17 @@ "or": "or", "signOut": "Sign Out", "exploreFeatures": "Explore all features", - "Select tags...": "Select tags…", - "Search keyword...": "Search keyword…", - "Sort by title": "Sort by title", - "Title": "Title", - "Sort by time": "Sort by time", - "Time": "Time", - "Export history": "Export history", - "Import history": "Import history", - "Clear history": "Clear history", - "Refresh history": "Refresh history", + "selectTags": "Select tags…", + "searchKeywords": "Search keyword…", + "sortByTitle": "Sort by title", + "title": "Title", + "lastVisit": "Last Visit", + "actions": "Actions", + "sortByLastVisited": "Sort by time", + "exportHistory": "Export history", + "importHistory": "Import history", + "clearHistory": "Clear history", + "refreshHistory": "Refresh history", "noHistory": "No history", "Import from browser": "Import from browser", "releases": "Releases", @@ -124,5 +125,7 @@ "email": "Email", "password": "Password", "username": "Username", + "cards": "Cards", + "table": "Table", "errorOpenIdLogin": "Invalid OpenID provided" } diff --git a/public/locales/eo.json b/public/locales/eo.json index a768afe82..84e0aac83 100644 --- a/public/locales/eo.json +++ b/public/locales/eo.json @@ -15,16 +15,16 @@ "or": "aŭ", "signOut": "Elsalutu", "exploreFeatures": "Esploru ĉiujn eblecojn", - "Select tags...": "Elektu etikedojn..", - "Search keyword...": "Serĉu ĉefvorton...", - "Sort by title": "Ordigu laŭ titolo", + "selectTags": "Elektu etikedojn..", + "searchKeywords": "Serĉu ĉefvorton...", + "sortByTitle": "Ordigu laŭ titolo", "Title": "Titolo", - "Sort by time": "Ordigu laŭ tempo", + "sortByLastVisited": "Ordigu laŭ tempo", "Time": "Tempo", - "Export history": "Elportu historion", - "Import history": "Alportu historion", - "Clear history": "Malplenigu historion", - "Refresh history": "Refreŝigu historion", + "exportHistory": "Elportu historion", + "importHistory": "Alportu historion", + "clearHistory": "Malplenigu historion", + "refreshHistory": "Refreŝigu historion", "noHistory": "Neniu historio", "Import from browser": "Alportu de retumilo", "releases": "Eldonoj", diff --git a/public/locales/es.json b/public/locales/es.json index 7ad270795..46780353a 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -15,16 +15,16 @@ "or": "o", "signOut": "Salir", "exploreFeatures": "Explorar todas las funciones", - "Select tags...": "Seleccionar etiquetas...", - "Search keyword...": "Buscar palabras clave...", - "Sort by title": "Ordenar por título", + "selectTags": "Seleccionar etiquetas...", + "searchKeywords": "Buscar palabras clave...", + "sortByTitle": "Ordenar por título", "Title": "Título", - "Sort by time": "Ordenar por fecha", + "sortByLastVisited": "Ordenar por fecha", "Time": "Tiempo", - "Export history": "Exportar historial", - "Import history": "Importar historial", - "Clear history": "Borrar historial", - "Refresh history": "Actualizar historial", + "exportHistory": "Exportar historial", + "importHistory": "Importar historial", + "clearHistory": "Borrar historial", + "refreshHistory": "Actualizar historial", "noHistory": "Ningún historial", "Import from browser": "Importar del navegador", "releases": "Versiones", diff --git a/public/locales/fr.json b/public/locales/fr.json index edc49848d..8ff1d8e36 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -15,16 +15,16 @@ "or": "ou", "signOut": "Se déconnecter", "exploreFeatures": "Explorer toutes les fonctionnalités", - "Select tags...": "Sélectionner les tags...", - "Search keyword...": "Chercher un mot-clef...", - "Sort by title": "Trier par titre", + "selectTags": "Sélectionner les tags...", + "searchKeywords": "Chercher un mot-clef...", + "sortByTitle": "Trier par titre", "Title": "Titre", - "Sort by time": "Trier par date", + "sortByLastVisited": "Trier par date", "Time": "Date", - "Export history": "Exporter l'historique", - "Import history": "Importer l'historique", - "Clear history": "Effacer l'historique", - "Refresh history": "Actualiser l'historique", + "exportHistory": "Exporter l'historique", + "importHistory": "Importer l'historique", + "clearHistory": "Effacer l'historique", + "refreshHistory": "Actualiser l'historique", "noHistory": "Pas d'historique", "Import from browser": "Importer depuis le navigateur", "releases": "Versions", diff --git a/public/locales/hi.json b/public/locales/hi.json index 367a7d83e..d9de09cf2 100644 --- a/public/locales/hi.json +++ b/public/locales/hi.json @@ -15,16 +15,16 @@ "or": "या", "signOut": "साइन आउट", "exploreFeatures": "सभी सुविधाओं का अन्वेषण करें", - "Select tags...": "टैग का चयन करें ...", - "Search keyword...": "मुख्य शब्द ढूंडो...", - "Sort by title": "शीर्षक द्वारा क्रमबद्ध करें", + "selectTags": "टैग का चयन करें ...", + "searchKeywords": "मुख्य शब्द ढूंडो...", + "sortByTitle": "शीर्षक द्वारा क्रमबद्ध करें", "Title": "शीर्षक", - "Sort by time": "समय के अनुसार क्रमबद्ध करें", + "sortByLastVisited": "समय के अनुसार क्रमबद्ध करें", "Time": "समय", - "Export history": "इतिहास को निर्यात करें", - "Import history": "इतिहास को आयात करें", - "Clear history": "इतिहास मिटा दें", - "Refresh history": "इतिहास ताज़ा करे", + "exportHistory": "इतिहास को निर्यात करें", + "importHistory": "इतिहास को आयात करें", + "clearHistory": "इतिहास मिटा दें", + "refreshHistory": "इतिहास ताज़ा करे", "noHistory": "इतिहास न रखें", "Import from browser": "ब्राउज़र से आयात", "releases": "विज्ञप्ति", diff --git a/public/locales/hr.json b/public/locales/hr.json index 908a46c38..8fa29f374 100644 --- a/public/locales/hr.json +++ b/public/locales/hr.json @@ -15,16 +15,16 @@ "or": "ili", "signOut": "Odjavi se", "exploreFeatures": "Istraži sve značajke", - "Select tags...": "Odaberi oznake...", - "Search keyword...": "Pretraži ključnu riječ...", - "Sort by title": "Sortiraj po naslovu", + "selectTags": "Odaberi oznake...", + "searchKeywords": "Pretraži ključnu riječ...", + "sortByTitle": "Sortiraj po naslovu", "Title": "Naslov", - "Sort by time": "Sortiraj po vremenu", + "sortByLastVisited": "Sortiraj po vremenu", "Time": "Vrijeme", - "Export history": "Izvezi povijest", - "Import history": "Uvezi povijest", - "Clear history": "Očisti povijest", - "Refresh history": "Osvježi povijest", + "exportHistory": "Izvezi povijest", + "importHistory": "Uvezi povijest", + "clearHistory": "Očisti povijest", + "refreshHistory": "Osvježi povijest", "noHistory": "Nema povijesti", "Import from browser": "Uvezi iz preglednika", "releases": "Izdanja", diff --git a/public/locales/id.json b/public/locales/id.json index 4c3ced340..a8e7ff61d 100644 --- a/public/locales/id.json +++ b/public/locales/id.json @@ -15,16 +15,16 @@ "or": "atau", "signOut": "Keluar", "exploreFeatures": "Jelajahi semua fitur", - "Select tags...": "Pilih tanda...", - "Search keyword...": "Cari berdasarkan kata kunci...", - "Sort by title": "Urutkan berdasarkan judul", + "selectTags": "Pilih tanda...", + "searchKeywords": "Cari berdasarkan kata kunci...", + "sortByTitle": "Urutkan berdasarkan judul", "Title": "Judul", - "Sort by time": "Urutkan berdasarkan waktu", + "sortByLastVisited": "Urutkan berdasarkan waktu", "Time": "Waktu", - "Export history": "Ekspor Riwayat", - "Import history": "Impor Riwayat", - "Clear history": "Bersihkan Riwayat", - "Refresh history": "Muat-ulang Riwayat", + "exportHistory": "Ekspor Riwayat", + "importHistory": "Impor Riwayat", + "clearHistory": "Bersihkan Riwayat", + "refreshHistory": "Muat-ulang Riwayat", "noHistory": "Tidak ada riwayat", "Import from browser": "Impor dari browser", "releases": "Penerbitan", diff --git a/public/locales/it.json b/public/locales/it.json index 5fe8b398b..0af31296c 100644 --- a/public/locales/it.json +++ b/public/locales/it.json @@ -15,16 +15,16 @@ "or": "o", "signOut": "Disconettiti", "exploreFeatures": "Esplora tutte le funzioni", - "Select tags...": "Seleziona tag...", - "Search keyword...": "Cerca...", - "Sort by title": "Ordina per titolo", + "selectTags": "Seleziona tag...", + "searchKeywords": "Cerca...", + "sortByTitle": "Ordina per titolo", "Title": "Titolo", - "Sort by time": "Ordina per data", + "sortByLastVisited": "Ordina per data", "Time": "Data", - "Export history": "Esporta cronologia", - "Import history": "Importa cronologia", - "Clear history": "Cancella cronologia", - "Refresh history": "Aggiorna cronologia", + "exportHistory": "Esporta cronologia", + "importHistory": "Importa cronologia", + "clearHistory": "Cancella cronologia", + "refreshHistory": "Aggiorna cronologia", "noHistory": "Nessuna cronologia", "Import from browser": "Importa da browser", "releases": "Versioni", diff --git a/public/locales/ja.json b/public/locales/ja.json index 4bb6f26bd..1457fc8e1 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -15,16 +15,16 @@ "or": "または", "signOut": "サインアウト", "exploreFeatures": "すべての機能をチェック", - "Select tags...": "タグで検索", - "Search keyword...": "キーワードで検索", - "Sort by title": "タイトル順でソート", + "selectTags": "タグで検索", + "searchKeywords": "キーワードで検索", + "sortByTitle": "タイトル順でソート", "Title": "タイトル", - "Sort by time": "日時順でソート", + "sortByLastVisited": "日時順でソート", "Time": "日時", - "Export history": "履歴をエクスポート", - "Import history": "履歴をインポート", - "Clear history": "履歴をクリア", - "Refresh history": "履歴を更新", + "exportHistory": "履歴をエクスポート", + "importHistory": "履歴をインポート", + "clearHistory": "履歴をクリア", + "refreshHistory": "履歴を更新", "noHistory": "履歴はありません", "Import from browser": "ブラウザからインポート", "releases": "リリース", diff --git a/public/locales/ko.json b/public/locales/ko.json index 7acbcc150..9fba70fc8 100644 --- a/public/locales/ko.json +++ b/public/locales/ko.json @@ -15,16 +15,16 @@ "or": "또는", "signOut": "로그아웃", "exploreFeatures": "모든 기능 둘러보기", - "Select tags...": "태그 선택하기", - "Search keyword...": "키워드 검색하기", - "Sort by title": "제목 기준 정렬", + "selectTags": "태그 선택하기", + "searchKeywords": "키워드 검색하기", + "sortByTitle": "제목 기준 정렬", "Title": "제목", - "Sort by time": "시간 기준 정렬", + "sortByLastVisited": "시간 기준 정렬", "Time": "시간", - "Export history": "기록 내보내기", - "Import history": "기록 불러오기", - "Clear history": "기록 초기화", - "Refresh history": "기록 새로고침", + "exportHistory": "기록 내보내기", + "importHistory": "기록 불러오기", + "clearHistory": "기록 초기화", + "refreshHistory": "기록 새로고침", "noHistory": "기록 없음", "Import from browser": "브라우저에서 불러오기", "releases": "릴리즈", diff --git a/public/locales/nl.json b/public/locales/nl.json index e5bc1f358..62b5abb9a 100644 --- a/public/locales/nl.json +++ b/public/locales/nl.json @@ -15,16 +15,16 @@ "or": "of", "signOut": "Uitloggen", "exploreFeatures": "Ontdek alle features", - "Select tags...": "Selecteer tags...", - "Search keyword...": "Zoeken op keyword...", - "Sort by title": "Sorteren op titel", + "selectTags": "Selecteer tags...", + "searchKeywords": "Zoeken op keyword...", + "sortByTitle": "Sorteren op titel", "Title": "Titel", - "Sort by time": "Sorteren op tijd", + "sortByLastVisited": "Sorteren op tijd", "Time": "Tijd", - "Export history": "Exporteer geschiedenis", - "Import history": "Importeer geschiedenis", - "Clear history": "Verwijder geschiedenis", - "Refresh history": "Ververs geschiedenis", + "exportHistory": "Exporteer geschiedenis", + "importHistory": "Importeer geschiedenis", + "clearHistory": "Verwijder geschiedenis", + "refreshHistory": "Ververs geschiedenis", "noHistory": "Geen geschidenis gevonden", "Import from browser": "Importeer van browser", "releases": "Versies", diff --git a/public/locales/pl.json b/public/locales/pl.json index 7d83ad4cf..791247ab1 100644 --- a/public/locales/pl.json +++ b/public/locales/pl.json @@ -15,16 +15,16 @@ "or": "lub", "signOut": "Wyloguj się", "exploreFeatures": "Przeglądaj wszystkie funkcje", - "Select tags...": "Wybierz tagi...", - "Search keyword...": "Znajdź kluczowe słowo...", - "Sort by title": "Sortuj według tytułu", + "selectTags": "Wybierz tagi...", + "searchKeywords": "Znajdź kluczowe słowo...", + "sortByTitle": "Sortuj według tytułu", "Title": "Tytuł", - "Sort by time": "Sortuj według czasu", + "sortByLastVisited": "Sortuj według czasu", "Time": "Czas", - "Export history": "Eksportuj historię", - "Import history": "Importuj historię", - "Clear history": "Wyczyść historię", - "Refresh history": "Odśwież historię", + "exportHistory": "Eksportuj historię", + "importHistory": "Importuj historię", + "clearHistory": "Wyczyść historię", + "refreshHistory": "Odśwież historię", "noHistory": "Brak historii", "Import from browser": "Importuj z przeglądarki", "releases": "Wydania", diff --git a/public/locales/pt.json b/public/locales/pt.json index 8bb357cc1..d97a15eb3 100644 --- a/public/locales/pt.json +++ b/public/locales/pt.json @@ -15,16 +15,16 @@ "or": "ou", "signOut": "Sair", "exploreFeatures": "Explore todas as funções", - "Select tags...": "Selecionar etiquetas...", - "Search keyword...": "Buscar palavra-chave...", - "Sort by title": "Ordenar por título", + "selectTags": "Selecionar etiquetas...", + "searchKeywords": "Buscar palavra-chave...", + "sortByTitle": "Ordenar por título", "Title": "Título", - "Sort by time": "Ordenar por hora", + "sortByLastVisited": "Ordenar por hora", "Time": "Hora", - "Export history": "Exportar histórico", - "Import history": "Importar histórico", - "Clear history": "Apagar histórico", - "Refresh history": "Atualizar histórico", + "exportHistory": "Exportar histórico", + "importHistory": "Importar histórico", + "clearHistory": "Apagar histórico", + "refreshHistory": "Atualizar histórico", "noHistory": "Nenhum histórico", "Import from browser": "Importar do navegador", "releases": "Lançamentos", diff --git a/public/locales/ru.json b/public/locales/ru.json index 5c3f0b854..ae2d8c7bc 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -15,16 +15,16 @@ "or": "или", "signOut": "Выйти", "exploreFeatures": "Изучите все возможности", - "Select tags...": "Выберите теги...", - "Search keyword...": "Поиск...", - "Sort by title": "Сортировка по заголовку", + "selectTags": "Выберите теги...", + "searchKeywords": "Поиск...", + "sortByTitle": "Сортировка по заголовку", "Title": "Заголовок", - "Sort by time": "Сортировка по времени", + "sortByLastVisited": "Сортировка по времени", "Time": "Время", - "Export history": "Экспорт истории", - "Import history": "Импорт истории", - "Clear history": "Очистить историю", - "Refresh history": "Обновить историю", + "exportHistory": "Экспорт истории", + "importHistory": "Импорт истории", + "clearHistory": "Очистить историю", + "refreshHistory": "Обновить историю", "noHistory": "Нет истории", "Import from browser": "Импорт из браузера", "releases": "Релизы", diff --git a/public/locales/sk.json b/public/locales/sk.json index 3afff194a..d54e9f3b8 100644 --- a/public/locales/sk.json +++ b/public/locales/sk.json @@ -15,16 +15,16 @@ "or": "alebo", "signOut": "Odhlásiť sa", "exploreFeatures": "Preskúmať všetky funkcie", - "Select tags...": "Zvoliť štítky…", - "Search keyword...": "Vyhľadať klúčové slovo …", - "Sort by title": "Zoradiť podľa názvu", + "selectTags": "Zvoliť štítky…", + "searchKeywords": "Vyhľadať klúčové slovo …", + "sortByTitle": "Zoradiť podľa názvu", "Title": "Názov", - "Sort by time": "Zoradiť podľa času", + "sortByLastVisited": "Zoradiť podľa času", "Time": "Čas", - "Export history": "Exportovať históriu", - "Import history": "Importovať históriu", - "Clear history": "Odstrániť históriu", - "Refresh history": "Aktualizovať históriu", + "exportHistory": "Exportovať históriu", + "importHistory": "Importovať históriu", + "clearHistory": "Odstrániť históriu", + "refreshHistory": "Aktualizovať históriu", "noHistory": "Žiadna história", "Import from browser": "Importovať z prehliadača", "releases": "Vydania", diff --git a/public/locales/sr.json b/public/locales/sr.json index 4c409fef6..9ab343728 100644 --- a/public/locales/sr.json +++ b/public/locales/sr.json @@ -15,16 +15,16 @@ "or": "или", "signOut": "Одјави се", "exploreFeatures": "Истражи све могућности", - "Select tags...": "Одабери тагове...", - "Search keyword...": "Претрага по кључној речи...", - "Sort by title": "Редослед по наслову", + "selectTags": "Одабери тагове...", + "searchKeywords": "Претрага по кључној речи...", + "sortByTitle": "Редослед по наслову", "Title": "Наслов", - "Sort by time": "Редослед по времену", + "sortByLastVisited": "Редослед по времену", "Time": "време", - "Export history": "Извези историјат", - "Import history": "Увези историјат", - "Clear history": "Очисти историју", - "Refresh history": "Освежи историју", + "exportHistory": "Извези историјат", + "importHistory": "Увези историјат", + "clearHistory": "Очисти историју", + "refreshHistory": "Освежи историју", "noHistory": "Нема историје", "Import from browser": "Увези из прегледача", "releases": "Издања", diff --git a/public/locales/sv.json b/public/locales/sv.json index 4ce285763..ab63a23e1 100644 --- a/public/locales/sv.json +++ b/public/locales/sv.json @@ -15,16 +15,16 @@ "or": "eller", "signOut": "Logga ut", "exploreFeatures": "Upptäck alla funktioner", - "Select tags...": "Välj taggar...", - "Search keyword...": "Sök nyckelord...", - "Sort by title": "Sortera titlar", + "selectTags": "Välj taggar...", + "searchKeywords": "Sök nyckelord...", + "sortByTitle": "Sortera titlar", "Title": "Titel", - "Sort by time": "Sortera kronologiskt", + "sortByLastVisited": "Sortera kronologiskt", "Time": "Tid", - "Export history": "Exporthistorik", - "Import history": "Importhistorik", - "Clear history": "Rensa historik", - "Refresh history": "Uppdatera historik", + "exportHistory": "Exporthistorik", + "importHistory": "Importhistorik", + "clearHistory": "Rensa historik", + "refreshHistory": "Uppdatera historik", "noHistory": "Ingen historik", "Import from browser": "Importera från webbläsare", "releases": "Lanseringar", diff --git a/public/locales/tr.json b/public/locales/tr.json index be610eabb..9448a3ec8 100644 --- a/public/locales/tr.json +++ b/public/locales/tr.json @@ -15,16 +15,16 @@ "or": "veya", "signOut": "Çıkış Yap", "exploreFeatures": "Özellikleri keşfet", - "Select tags...": "Etiketleri seçin...", - "Search keyword...": "Anahtar kelimeleri arayın...", - "Sort by title": "Başlığa göre sırala", + "selectTags": "Etiketleri seçin...", + "searchKeywords": "Anahtar kelimeleri arayın...", + "sortByTitle": "Başlığa göre sırala", "Title": "Başlık", - "Sort by time": "Zamana göre sırala", + "sortByLastVisited": "Zamana göre sırala", "Time": "Zaman", - "Export history": "Geçmişe dışa aktar", - "Import history": "Geçmişi içe aktar", - "Clear history": "Geçmişi temizle", - "Refresh history": "Geçmişi yenile", + "exportHistory": "Geçmişe dışa aktar", + "importHistory": "Geçmişi içe aktar", + "clearHistory": "Geçmişi temizle", + "refreshHistory": "Geçmişi yenile", "noHistory": "Geçmiş yok", "Import from browser": "Tarayıcıdan içe aktar", "releases": "Sürümler", diff --git a/public/locales/uk.json b/public/locales/uk.json index eaf5b38eb..ad0cedc7e 100644 --- a/public/locales/uk.json +++ b/public/locales/uk.json @@ -15,16 +15,16 @@ "or": "або", "signOut": "Вийти", "exploreFeatures": "Дослідити всі можливості", - "Select tags...": "Вибрати теги...", - "Search keyword...": "Пошук...", - "Sort by title": "Сортувати по заголовку", + "selectTags": "Вибрати теги...", + "searchKeywords": "Пошук...", + "sortByTitle": "Сортувати по заголовку", "Title": "Заголовок", - "Sort by time": "Сортувати по часу", + "sortByLastVisited": "Сортувати по часу", "Time": "Час", - "Export history": "Еспортувати історію", - "Import history": "Імпортувати історію", - "Clear history": "Очистити історію", - "Refresh history": "Оновити історію", + "exportHistory": "Еспортувати історію", + "importHistory": "Імпортувати історію", + "clearHistory": "Очистити історію", + "refreshHistory": "Оновити історію", "noHistory": "Історія відсутня", "Import from browser": "Імпортувати з браузера", "releases": "Релізи", diff --git a/public/locales/vi.json b/public/locales/vi.json index d67013670..3053e75f4 100644 --- a/public/locales/vi.json +++ b/public/locales/vi.json @@ -15,16 +15,16 @@ "or": "hoặc", "signOut": "Đăng xuất", "exploreFeatures": "Khám phá tất cả tính năng", - "Select tags...": "Chọn tag", - "Search keyword...": "Tìm kiếm", - "Sort by title": "Sắp xếp theo tiêu đề", + "selectTags": "Chọn tag", + "searchKeywords": "Tìm kiếm", + "sortByTitle": "Sắp xếp theo tiêu đề", "Title": "Tiêu đề", - "Sort by time": "Sắp xếp theo thời gian", + "sortByLastVisited": "Sắp xếp theo thời gian", "Time": "Thời gian", - "Export history": "Xuất lịch sử", - "Import history": "Nhập lịch sử", - "Clear history": "Xóa lịch sử", - "Refresh history": "Làm mới lịch sử", + "exportHistory": "Xuất lịch sử", + "importHistory": "Nhập lịch sử", + "clearHistory": "Xóa lịch sử", + "refreshHistory": "Làm mới lịch sử", "noHistory": "Không có lịch sử", "Import from browser": "Nhập từ trình duyệt", "releases": "Xuất bản", diff --git a/public/locales/zh-CN.json b/public/locales/zh-CN.json index a8605fa24..c5a25e4bd 100644 --- a/public/locales/zh-CN.json +++ b/public/locales/zh-CN.json @@ -15,16 +15,16 @@ "or": "或", "signOut": "登出", "exploreFeatures": "探索所有功能", - "Select tags...": "选择标签...", - "Search keyword...": "搜索关键字...", - "Sort by title": "按标题排序", + "selectTags": "选择标签...", + "searchKeywords": "搜索关键字...", + "sortByTitle": "按标题排序", "Title": "标题", - "Sort by time": "按时间排序", + "sortByLastVisited": "按时间排序", "Time": "时间", - "Export history": "导出历史", - "Import history": "导入历史", - "Clear history": "清空历史", - "Refresh history": "刷新历史", + "exportHistory": "导出历史", + "importHistory": "导入历史", + "clearHistory": "清空历史", + "refreshHistory": "刷新历史", "noHistory": "无历史记录", "Import from browser": "从浏览器导入", "releases": "版本", diff --git a/public/locales/zh-TW.json b/public/locales/zh-TW.json index d74e8424f..a1039a13d 100644 --- a/public/locales/zh-TW.json +++ b/public/locales/zh-TW.json @@ -15,16 +15,16 @@ "or": "或", "signOut": "登出", "exploreFeatures": "探索所有功能", - "Select tags...": "選擇標籤...", - "Search keyword...": "搜尋關鍵字...", - "Sort by title": "用標題排序", + "selectTags": "選擇標籤...", + "searchKeywords": "搜尋關鍵字...", + "sortByTitle": "用標題排序", "Title": "標題", - "Sort by time": "用時間排序", + "sortByLastVisited": "用時間排序", "Time": "時間", - "Export history": "匯出紀錄", - "Import history": "匯入紀錄", - "Clear history": "清空紀錄", - "Refresh history": "更新紀錄", + "exportHistory": "匯出紀錄", + "importHistory": "匯入紀錄", + "clearHistory": "清空紀錄", + "refreshHistory": "更新紀錄", "noHistory": "沒有紀錄", "Import from browser": "從瀏覽器匯入", "releases": "版本", diff --git a/src/components/icon-button/icon-button.scss b/src/components/icon-button/icon-button.scss new file mode 100644 index 000000000..342fcf307 --- /dev/null +++ b/src/components/icon-button/icon-button.scss @@ -0,0 +1,20 @@ +.btn-icon { + padding: 0.375rem 0.375rem; + border-right: 1px solid rgba(0, 0, 0, 0.2); + display: flex; + + .icon-part { + padding: 0.375rem 0.375rem; + border-right: 1px solid rgba(0, 0, 0, 0.2); + display: flex; + + .social-icon { + font-size: 1.5em; + } + } + + .text-part { + padding: 0.375rem 0.75rem; + } +} + diff --git a/src/components/icon-button/icon-button.tsx b/src/components/icon-button/icon-button.tsx new file mode 100644 index 000000000..fde6e01f8 --- /dev/null +++ b/src/components/icon-button/icon-button.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; +import "./icon-button.scss"; +import {IconProp} from "@fortawesome/fontawesome-svg-core"; +import {Button, ButtonProps} from "react-bootstrap"; + +export interface SocialButtonProps extends ButtonProps { + icon: IconProp + onClick?: () => void +} + +export const IconButton: React.FC = ({icon, children, variant, onClick}) => { + return ( + + ) +} diff --git a/src/components/landing/layout/style/index.scss b/src/components/landing/layout/style/index.scss index b6f0e017b..ee5504ec1 100644 --- a/src/components/landing/layout/style/index.scss +++ b/src/components/landing/layout/style/index.scss @@ -1,4 +1,5 @@ @import "../../../../../node_modules/bootstrap/scss/bootstrap"; +@import '../../../../../node_modules/react-bootstrap-typeahead/css/Typeahead'; @import "font-pack"; //@import "cover.scss"; diff --git a/src/components/landing/pages/history/common/close-button.tsx b/src/components/landing/pages/history/common/close-button.tsx index 9f84b2b66..d7643494c 100644 --- a/src/components/landing/pages/history/common/close-button.tsx +++ b/src/components/landing/pages/history/common/close-button.tsx @@ -1,14 +1,21 @@ import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import React from "react"; import "./close-button.scss" +import {Button} from "react-bootstrap"; -const CloseButton: React.FC = () => { +export interface CloseButtonProps { + isDark: boolean; +} + +const CloseButton: React.FC = ({isDark}) => { return ( - + ); } -export { CloseButton } +export {CloseButton} diff --git a/src/components/landing/pages/history/common/pin-button.tsx b/src/components/landing/pages/history/common/pin-button.tsx index 8bdc22b93..6f1d036dd 100644 --- a/src/components/landing/pages/history/common/pin-button.tsx +++ b/src/components/landing/pages/history/common/pin-button.tsx @@ -1,20 +1,22 @@ import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import React from "react"; import "./pin-button.scss" +import {Button} from "react-bootstrap"; export interface PinButtonProps { - pin: boolean; + isPinned: boolean; onPinClick: () => void; + isDark: boolean; } -const PinButton: React.FC = ({pin, onPinClick}) => { +export const PinButton: React.FC = ({isPinned, onPinClick, isDark}) => { return ( - + ); } - -export { PinButton } diff --git a/src/components/landing/pages/history/history-card/history-card.tsx b/src/components/landing/pages/history/history-card/history-card.tsx index 33b385674..19d4f5342 100644 --- a/src/components/landing/pages/history/history-card/history-card.tsx +++ b/src/components/landing/pages/history/history-card/history-card.tsx @@ -13,12 +13,12 @@ export const HistoryCard: React.FC = ({entry, onPinClick}) => return (
-
- { +
+ { onPinClick(entry.id) }}/> {entry.title} - +
@@ -26,7 +26,8 @@ export const HistoryCard: React.FC = ({entry, onPinClick}) => {formatHistoryDate(entry.lastVisited)}
{ - entry.tags.map((tag) => {tag}) + entry.tags.map((tag) => {tag}) }
diff --git a/src/components/landing/pages/history/history-content/history-content.tsx b/src/components/landing/pages/history/history-content/history-content.tsx index 10edf1203..bd1493c44 100644 --- a/src/components/landing/pages/history/history-content/history-content.tsx +++ b/src/components/landing/pages/history/history-content/history-content.tsx @@ -1,9 +1,10 @@ import React from "react"; -import {HistoryEntry, pinClick, ViewStateEnum} from "../history"; +import {HistoryEntry, pinClick} from "../history"; import {HistoryTable} from "../history-table/history-table"; import {Alert} from "react-bootstrap"; import {Trans} from "react-i18next"; import {HistoryCardList} from "../history-card/history-card-list"; +import {ViewStateEnum} from "../history-toolbar/history-toolbar"; export interface HistoryContentProps { viewState: ViewStateEnum diff --git a/src/components/landing/pages/history/history-table/history-table-row.tsx b/src/components/landing/pages/history/history-table/history-table-row.tsx index ca9b72283..389953ceb 100644 --- a/src/components/landing/pages/history/history-table/history-table-row.tsx +++ b/src/components/landing/pages/history/history-table/history-table-row.tsx @@ -12,11 +12,11 @@ export const HistoryTableRow: React.FC = ({entry, onPinClick} {entry.title} {formatHistoryDate(entry.lastVisited)} - { + { onPinClick(entry.id) }}/>   - + ) diff --git a/src/components/landing/pages/history/history-table/history-table.tsx b/src/components/landing/pages/history/history-table/history-table.tsx index 780e4941a..a193e2d98 100644 --- a/src/components/landing/pages/history/history-table/history-table.tsx +++ b/src/components/landing/pages/history/history-table/history-table.tsx @@ -2,15 +2,16 @@ import React from "react"; import {Table} from "react-bootstrap" import {HistoryTableRow} from "./history-table-row"; import {HistoryEntriesProps} from "../history-content/history-content"; +import {Trans} from "react-i18next"; const HistoryTable: React.FC = ({entries, onPinClick}) => { return ( - - - + + + diff --git a/src/components/landing/pages/history/history-toolbar/history-toolbar.tsx b/src/components/landing/pages/history/history-toolbar/history-toolbar.tsx new file mode 100644 index 000000000..e2b8c4b7d --- /dev/null +++ b/src/components/landing/pages/history/history-toolbar/history-toolbar.tsx @@ -0,0 +1,128 @@ +import {Button, Form, FormControl, InputGroup, ToggleButton, ToggleButtonGroup} from "react-bootstrap"; +import React, {ChangeEvent, useEffect, useState} from "react"; +import {Trans, useTranslation} from "react-i18next"; +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; +import {SortButton, SortModeEnum} from "../../../../sort-button/sort-button"; +import {Typeahead} from 'react-bootstrap-typeahead'; +import "./typeahead-hacks.scss"; + +export type HistoryToolbarChange = (settings: HistoryToolbarState) => void; + +export interface HistoryToolbarState { + viewState: ViewStateEnum + titleSortDirection: SortModeEnum + lastVisitedSortDirection: SortModeEnum + keywordSearch: string + selectedTags: string[] +} + +export enum ViewStateEnum { + card, + table +} + +export interface HistoryToolbarProps { + onSettingsChange: HistoryToolbarChange + tags: string[] +} + +export const initState: HistoryToolbarState = { + viewState: ViewStateEnum.card, + titleSortDirection: SortModeEnum.no, + lastVisitedSortDirection: SortModeEnum.no, + keywordSearch: "", + selectedTags: [] +} + +export const HistoryToolbar: React.FC = ({onSettingsChange, tags}) => { + + const [t] = useTranslation() + const [state, setState] = useState(initState); + + const titleSortChanged = (direction: SortModeEnum) => { + setState(prevState => ({ + ...prevState, + titleSortDirection: direction, + lastVisitedSortDirection: SortModeEnum.no + })) + } + + const lastVisitedSortChanged = (direction: SortModeEnum) => { + setState(prevState => ({ + ...prevState, + lastVisitedSortDirection: direction, + titleSortDirection: SortModeEnum.no + })) + } + + const keywordSearchChanged = (event: ChangeEvent) => { + setState(prevState => ({...prevState, keywordSearch: event.currentTarget.value})); + } + + const toggleViewChanged = (newViewState: ViewStateEnum) => { + setState((prevState) => ({...prevState, viewState: newViewState})) + } + + const selectedTagsChanged = (selected: string[]) => { + setState((prevState => ({...prevState, selectedTags: selected}))) + } + + useEffect(() => { + onSettingsChange(state); + }, [onSettingsChange, state]) + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + { + toggleViewChanged(newViewState) + }}> + + + + + + ) +} \ No newline at end of file diff --git a/src/components/landing/pages/history/history-toolbar/typeahead-hacks.scss b/src/components/landing/pages/history/history-toolbar/typeahead-hacks.scss new file mode 100644 index 000000000..cee53f040 --- /dev/null +++ b/src/components/landing/pages/history/history-toolbar/typeahead-hacks.scss @@ -0,0 +1,11 @@ +.rbt-input-multi { + min-width: 200px !important; + + .rbt-input-main { + &[placeholder=""] { + width: 10px !important; + } + + width: 100%; + } +} \ No newline at end of file diff --git a/src/components/landing/pages/history/history.tsx b/src/components/landing/pages/history/history.tsx index 8327821c3..aa8eacf69 100644 --- a/src/components/landing/pages/history/history.tsx +++ b/src/components/landing/pages/history/history.tsx @@ -1,12 +1,8 @@ import React, {Fragment, useEffect, useState} from 'react' -import {ToggleButton, ToggleButtonGroup} from 'react-bootstrap'; import {HistoryContent} from './history-content/history-content'; +import {HistoryToolbar, HistoryToolbarState, initState as toolbarInitState} from './history-toolbar/history-toolbar'; import {loadHistoryFromLocalStore, sortAndFilterEntries} from "../../../../utils/historyUtils"; - -export enum ViewStateEnum { - card, - table -} +import {Row} from 'react-bootstrap'; export interface HistoryEntry { id: string, @@ -20,7 +16,7 @@ export type pinClick = (entryId: string) => void; export const History: React.FC = () => { const [historyEntries, setHistoryEntries] = useState([]) - const [viewState, setViewState] = useState(ViewStateEnum.card) + const [viewState, setViewState] = useState(toolbarInitState) useEffect(() => { const history = loadHistoryFromLocalStore(); @@ -28,6 +24,9 @@ export const History: React.FC = () => { }, []) useEffect(() => { + if (historyEntries === []) { + return; + } window.localStorage.setItem("history", JSON.stringify(historyEntries)); }, [historyEntries]) @@ -42,16 +41,25 @@ export const History: React.FC = () => { }) } + const tags = historyEntries.map(entry => entry.tags) + .reduce((a, b) => ([...a, ...b]), []) + .filter((value, index, array) => { + if (index === 0) { + return true; + } + return (value !== array[index - 1]) + }) + const entriesToShow = sortAndFilterEntries(historyEntries, viewState); + return (

History

- setViewState(newState)}> - Card - Table - + + +
-
diff --git a/src/components/landing/pages/login/auth/icon-button/icon-button.scss b/src/components/landing/pages/login/auth/social-link-button/social-link-button.scss similarity index 68% rename from src/components/landing/pages/login/auth/icon-button/icon-button.scss rename to src/components/landing/pages/login/auth/social-link-button/social-link-button.scss index b2336df2b..b7be1ed34 100644 --- a/src/components/landing/pages/login/auth/icon-button/icon-button.scss +++ b/src/components/landing/pages/login/auth/social-link-button/social-link-button.scss @@ -1,4 +1,4 @@ -.btn.btn-icon { +.btn.social-link-button { color: #FFFFFF; @mixin button($color) { @@ -8,6 +8,20 @@ } } + .icon-part { + padding: 0.375rem 0.375rem; + border-right: 1px solid rgba(0, 0, 0, 0.2); + display: flex; + + .social-icon { + font-size: 1.5em; + } + } + + .text-part { + padding: 0.375rem 0.75rem; + } + &.btn-social-dropbox { @include button(#1087DD); } @@ -33,16 +47,3 @@ } } -.btn-social-button { - padding: 0.375rem 0.375rem; - border-right: 1px solid rgba(0, 0, 0, 0.2); - display: flex; - - .social-icon { - font-size: 1.5em; - } -} - -.btn-social-text { - padding: 0.375rem 0.75rem; -} diff --git a/src/components/landing/pages/login/auth/icon-button/icon-button.tsx b/src/components/landing/pages/login/auth/social-link-button/social-link-button.tsx similarity index 55% rename from src/components/landing/pages/login/auth/icon-button/icon-button.tsx rename to src/components/landing/pages/login/auth/social-link-button/social-link-button.tsx index 6d723f7cb..f4032f077 100644 --- a/src/components/landing/pages/login/auth/icon-button/icon-button.tsx +++ b/src/components/landing/pages/login/auth/social-link-button/social-link-button.tsx @@ -1,6 +1,6 @@ import React from "react"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import "./icon-button.scss"; +import "./social-link-button.scss"; import {IconProp} from "@fortawesome/fontawesome-svg-core"; export interface SocialButtonProps { @@ -10,14 +10,14 @@ export interface SocialButtonProps { title?: string } -export const IconButton: React.FC = ({title, backgroundClass, href, icon, children}) => { +export const SocialLinkButton: React.FC = ({title, backgroundClass, href, icon, children}) => { return ( - + className={"btn social-link-button p-0 d-inline-flex align-items-stretch " + backgroundClass}> + - + {children} diff --git a/src/components/landing/pages/login/auth/via-one-click.tsx b/src/components/landing/pages/login/auth/via-one-click.tsx index 6b4906145..9425af071 100644 --- a/src/components/landing/pages/login/auth/via-one-click.tsx +++ b/src/components/landing/pages/login/auth/via-one-click.tsx @@ -1,6 +1,6 @@ import React from "react"; import {IconProp} from "@fortawesome/fontawesome-svg-core"; -import {IconButton} from "./icon-button/icon-button"; +import {SocialLinkButton} from "./social-link-button/social-link-button"; export enum OneClickType { 'DROPBOX'="dropbox", @@ -101,14 +101,14 @@ const ViaOneClick: React.FC = ({oneClickType, optionalName}) = const {name, icon, className, url} = getMetadata(oneClickType); const text = !!optionalName ? optionalName : name; return ( - {text} - + ) } diff --git a/src/components/sort-button/sort-button.tsx b/src/components/sort-button/sort-button.tsx new file mode 100644 index 000000000..bafa260de --- /dev/null +++ b/src/components/sort-button/sort-button.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import {IconProp} from "@fortawesome/fontawesome-svg-core"; +import {ButtonProps} from "react-bootstrap"; +import {IconButton} from "../icon-button/icon-button"; + +export enum SortModeEnum { + up = 1, + down = -1, + no = 0 +} + +const getIcon = (direction: SortModeEnum): IconProp => { + switch (direction) { + default: + case SortModeEnum.no: + return "sort"; + case SortModeEnum.up: + return "sort-up"; + case SortModeEnum.down: + return "sort-down"; + } +} + +export interface SortButtonProps extends ButtonProps { + onChange: (direction: SortModeEnum) => void + direction: SortModeEnum +} + +const toggleDirection = (direction: SortModeEnum) => { + switch (direction) { + case SortModeEnum.no: + return SortModeEnum.up; + case SortModeEnum.up: + return SortModeEnum.down; + default: + case SortModeEnum.down: + return SortModeEnum.no; + } +} + +export const SortButton: React.FC = ({children, variant, onChange, direction}) => { + const toggleSort = () => { + onChange(toggleDirection(direction)); + } + + return {children}; +} diff --git a/src/initializers/fontAwesome.ts b/src/initializers/fontAwesome.ts index 2eaaf3220..58f034c1a 100644 --- a/src/initializers/fontAwesome.ts +++ b/src/initializers/fontAwesome.ts @@ -6,14 +6,20 @@ import { faClock, faCloudDownloadAlt, faComment, + faDownload, faFileAlt, faGlobe, faPlus, faSignOutAlt, + faSort, + faSortDown, + faSortUp, + faSync, faThumbtack, faTimes, faTrash, faTv, + faUpload, faUsers, } from "@fortawesome/free-solid-svg-icons"; import { @@ -31,5 +37,5 @@ export function setUpFontAwesome() { library.add(faBolt, faPlus, faChartBar, faTv, faFileAlt, faCloudDownloadAlt, faTrash, faSignOutAlt, faComment, faDiscourse, faMastodon, faGlobe, faThumbtack, faClock, faTimes, faGithub, faGitlab, faGoogle, faFacebook, - faDropbox, faTwitter, faUsers, faAddressCard) + faDropbox, faTwitter, faUsers, faAddressCard, faSort, faDownload, faUpload, faTrash, faSync, faSortUp, faSortDown) } diff --git a/src/utils/historyUtils.ts b/src/utils/historyUtils.ts index 7dce931df..b360a6774 100644 --- a/src/utils/historyUtils.ts +++ b/src/utils/historyUtils.ts @@ -1,24 +1,55 @@ import {HistoryEntry} from "../components/landing/pages/history/history"; import moment from "moment"; +import {HistoryToolbarState} from "../components/landing/pages/history/history-toolbar/history-toolbar"; +import {SortModeEnum} from "../components/sort-button/sort-button"; -export function sortAndFilterEntries(entries: HistoryEntry[]): HistoryEntry[] { - return sortEntries(entries); +export function sortAndFilterEntries(entries: HistoryEntry[], viewState: HistoryToolbarState): HistoryEntry[] { + return sortEntries(filterByKeywordSearch(filterBySelectedTags(entries, viewState.selectedTags), viewState.keywordSearch), viewState); } -function sortEntries(entries: HistoryEntry[]): HistoryEntry[] { - return entries.sort((a, b) => { - if (a.pinned && !b.pinned) { +function filterBySelectedTags(entries: HistoryEntry[], selectedTags: string[]): HistoryEntry[] { + return entries.filter(entry => { + return (selectedTags.length === 0 || arrayCommonCheck(entry.tags, selectedTags)) + } + ) +} + +function arrayCommonCheck(array1: T[], array2: T[]): boolean { + const foundElement = array1.find((element1) => + array2.find((element2) => + element2 === element1 + ) + ) + return !!foundElement; +} + +function filterByKeywordSearch(entries: HistoryEntry[], keywords: string): HistoryEntry[] { + const searchTerm = keywords.toLowerCase(); + return entries.filter(entry => entry.title.toLowerCase().indexOf(searchTerm) !== -1); +} + +function sortEntries(entries: HistoryEntry[], viewState: HistoryToolbarState): HistoryEntry[] { + return entries.sort((firstEntry, secondEntry) => { + if (firstEntry.pinned && !secondEntry.pinned) { return -1; } - if (!a.pinned && b.pinned) { + if (!firstEntry.pinned && secondEntry.pinned) { return 1; } - if (a.lastVisited < b.lastVisited) { - return -1; + + if (viewState.titleSortDirection !== SortModeEnum.no) { + return firstEntry.title.localeCompare(secondEntry.title) * viewState.titleSortDirection; } - if (a.lastVisited > b.lastVisited) { - return 1; + + if (viewState.lastVisitedSortDirection !== SortModeEnum.no) { + if (firstEntry.lastVisited > secondEntry.lastVisited) { + return 1 * viewState.lastVisitedSortDirection; + } + if (firstEntry.lastVisited < secondEntry.lastVisited) { + return -1 * viewState.lastVisitedSortDirection; + } } + return 0; }) } @@ -37,7 +68,7 @@ export interface OldHistoryEntry { export function loadHistoryFromLocalStore(): HistoryEntry[] { const historyJsonString = window.localStorage.getItem("history"); - if (historyJsonString === null) { + if (!historyJsonString) { // if localStorage["history"] is empty we check the old localStorage["notehistory"] // and convert it to the new format const oldHistoryJsonString = window.localStorage.getItem("notehistory") diff --git a/yarn.lock b/yarn.lock index 8c7347272..15a21c892 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1589,6 +1589,13 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/react-bootstrap-typeahead@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@types/react-bootstrap-typeahead/-/react-bootstrap-typeahead-3.4.6.tgz#b97709ad10670ad277b2c7b2f0e6368f890bf849" + integrity sha512-3vrWrPNb2G+ieyWB1VtEPZH6E4NBcd2cVsacb6oUhBNU/D/ZYnUqnbmeTIKzIVXqEkdPtgARG45W1x7tUV9DGA== + dependencies: + "@types/react" "*" + "@types/react-bootstrap@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/react-bootstrap/-/react-bootstrap-1.0.1.tgz#3badd512fc37913b5e72f1ed94e3aacbd1452d97" @@ -3019,7 +3026,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.6: +classnames@^2.2.0, classnames@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== @@ -3212,6 +3219,11 @@ compression@^1.7.4: safe-buffer "5.1.2" vary "~1.1.2" +compute-scroll-into-view@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.13.tgz#be1b1663b0e3f56cd5f7713082549f562a3477e2" + integrity sha512-o+w9w7A98aAFi/GjK8cxSV+CdASuPa2rR5UWs3+yHkJzWqaKoBEufFNWYaXInCSmUfDCVhesG+v9MTWqOjsxFg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -3388,6 +3400,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-react-context@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + cross-spawn@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" @@ -3731,7 +3751,7 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -deep-equal@^1.0.1: +deep-equal@^1.0.1, deep-equal@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== @@ -5661,7 +5681,7 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" -invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -6839,6 +6859,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -8132,6 +8157,11 @@ pnp-webpack-plugin@1.6.4: dependencies: ts-pnp "^1.1.6" +popper.js@^1.14.4, popper.js@^1.15.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== + portfinder@^1.0.25: version "1.0.26" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" @@ -8898,7 +8928,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -9069,6 +9099,22 @@ react-app-polyfill@^1.0.6: regenerator-runtime "^0.13.3" whatwg-fetch "^3.0.0" +react-bootstrap-typeahead@^5.0.0-rc.1: + version "5.0.0-rc.1" + resolved "https://registry.yarnpkg.com/react-bootstrap-typeahead/-/react-bootstrap-typeahead-5.0.0-rc.1.tgz#f20b9d5a7a46783e886b1f79ed074e7e05582495" + integrity sha512-Crmguatcjaw9593MHBNQvsFSd0BFWsx74wC+txpLVpOCEB9JJ+pfkwGopbau3w1mYasZZ046ga7E6lAXmty7xA== + dependencies: + "@babel/runtime" "^7.3.4" + classnames "^2.2.0" + fast-deep-equal "^3.1.1" + invariant "^2.2.1" + lodash.debounce "^4.0.8" + prop-types "^15.5.8" + react-overlays "^2.0.0" + react-popper "^1.0.0" + scroll-into-view-if-needed "^2.2.20" + warning "^4.0.1" + react-bootstrap@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.0.1.tgz#044b51f34a9db8e17dbfb321a71267a8d6ad11b4" @@ -9151,6 +9197,19 @@ react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-overlays@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-2.1.1.tgz#ffe2090c4a10da6b8947a1c7b1a67d0457648a0d" + integrity sha512-gaQJwmb8Ij2IGVt4D1HmLtl4A0mDVYxlsv/8i0dHWK7Mw0kNat6ORelbbEWzaXTK1TqMeQtJw/jraL3WOADz3w== + dependencies: + "@babel/runtime" "^7.4.5" + "@restart/hooks" "^0.3.12" + dom-helpers "^5.1.0" + popper.js "^1.15.0" + prop-types "^15.7.2" + uncontrollable "^7.0.0" + warning "^4.0.3" + react-overlays@^3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-3.1.3.tgz#e6ac2b43fd2179924491bd794508072399940128" @@ -9165,6 +9224,19 @@ react-overlays@^3.1.2: uncontrollable "^7.0.0" warning "^4.0.3" +react-popper@^1.0.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.7.tgz#f6a3471362ef1f0d10a4963673789de1baca2324" + integrity sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww== + dependencies: + "@babel/runtime" "^7.1.2" + create-react-context "^0.3.0" + deep-equal "^1.1.1" + popper.js "^1.14.4" + prop-types "^15.6.1" + typed-styles "^0.0.7" + warning "^4.0.2" + react-redux@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d" @@ -9874,6 +9946,13 @@ schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6 ajv "^6.12.0" ajv-keywords "^3.4.1" +scroll-into-view-if-needed@^2.2.20: + version "2.2.24" + resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.24.tgz#12bca532990769bd509115a49edcfa755e92a0ea" + integrity sha512-vsC6SzyIZUyJG8o4nbUDCiIwsPdH6W/FVmjT2avR2hp/yzS53JjGmg/bKD20TkoNajbu5dAQN4xR7yes4qhwtQ== + dependencies: + compute-scroll-into-view "^1.0.13" + scss-tokenizer@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" @@ -10917,6 +10996,11 @@ type@^2.0.0: resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== +typed-styles@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" + integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -11191,7 +11275,7 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" -warning@^4.0.0, warning@^4.0.3: +warning@^4.0.0, warning@^4.0.1, warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
TitleLast visitedActions