feat(catalog): add search

This commit is contained in:
Tom (plebeius.eth)
2025-03-06 16:27:09 +01:00
parent cf183393a4
commit a8f7de7d85
41 changed files with 213 additions and 60 deletions
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "تم حذف هذه الرد من قبل مؤلفه", "this_reply_was_deleted": "تم حذف هذه الرد من قبل مؤلفه",
"this_reply_was_removed": "تمت إزالة هذه الرد من قبل مشرفي المنتدى", "this_reply_was_removed": "تمت إزالة هذه الرد من قبل مشرفي المنتدى",
"not_mod_of_any_board": "أنت لست مشرفًا في أي لوحة.", "not_mod_of_any_board": "أنت لست مشرفًا في أي لوحة.",
"filters_and_highlights": "الفلاتر والإبرازات" "filters_and_highlights": "الفلاتر والإبرازات",
"search_results_for": "نتائج البحث عن"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "এই প্রতিক্রিয়া তার লেখক দ্বারা মুছে ফেলা হয়েছে", "this_reply_was_deleted": "এই প্রতিক্রিয়া তার লেখক দ্বারা মুছে ফেলা হয়েছে",
"this_reply_was_removed": "এই প্রতিক্রিয়া বোর্ড পরিচালকদের দ্বারা সরানো হয়েছে", "this_reply_was_removed": "এই প্রতিক্রিয়া বোর্ড পরিচালকদের দ্বারা সরানো হয়েছে",
"not_mod_of_any_board": "আপনি কোনও বোর্ডের মড নন।", "not_mod_of_any_board": "আপনি কোনও বোর্ডের মড নন।",
"filters_and_highlights": "ফিল্টার এবং হাইলাইট" "filters_and_highlights": "ফিল্টার এবং হাইলাইট",
"search_results_for": "অনুসন্ধান ফলাফল"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Tato odpověď byla smazána autorem", "this_reply_was_deleted": "Tato odpověď byla smazána autorem",
"this_reply_was_removed": "Tato odpověď byla odstraněna moderátory fóra", "this_reply_was_removed": "Tato odpověď byla odstraněna moderátory fóra",
"not_mod_of_any_board": "Nejste moderátor žádné desky.", "not_mod_of_any_board": "Nejste moderátor žádné desky.",
"filters_and_highlights": "Filtry a zvýraznění" "filters_and_highlights": "Filtry a zvýraznění",
"search_results_for": "Výsledky hledání pro"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Dette svar blev slettet af forfatteren", "this_reply_was_deleted": "Dette svar blev slettet af forfatteren",
"this_reply_was_removed": "Dette svar blev fjernet af forummoderatorer", "this_reply_was_removed": "Dette svar blev fjernet af forummoderatorer",
"not_mod_of_any_board": "Du er ikke moderator for nogen tavler.", "not_mod_of_any_board": "Du er ikke moderator for nogen tavler.",
"filters_and_highlights": "Filtre og fremhævninger" "filters_and_highlights": "Filtre og fremhævninger",
"search_results_for": "Søgeresultater for"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Diese Antwort wurde vom Autor gelöscht", "this_reply_was_deleted": "Diese Antwort wurde vom Autor gelöscht",
"this_reply_was_removed": "Diese Antwort wurde von den Forenmoderatoren entfernt", "this_reply_was_removed": "Diese Antwort wurde von den Forenmoderatoren entfernt",
"not_mod_of_any_board": "Du bist kein Moderator eines Boards.", "not_mod_of_any_board": "Du bist kein Moderator eines Boards.",
"filters_and_highlights": "Filter & Highlights" "filters_and_highlights": "Filter & Highlights",
"search_results_for": "Suchergebnisse für"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Αυτή η απάντηση διαγράφηκε από τον συγγραφέα της", "this_reply_was_deleted": "Αυτή η απάντηση διαγράφηκε από τον συγγραφέα της",
"this_reply_was_removed": "Η απάντηση αυτή αφαιρέθηκε από τους διαχειριστές του φόρουμ", "this_reply_was_removed": "Η απάντηση αυτή αφαιρέθηκε από τους διαχειριστές του φόρουμ",
"not_mod_of_any_board": "Δεν είστε διαχειριστής σε καμία κοινότητα.", "not_mod_of_any_board": "Δεν είστε διαχειριστής σε καμία κοινότητα.",
"filters_and_highlights": "Φίλτρα και επισημάνσεις" "filters_and_highlights": "Φίλτρα και επισημάνσεις",
"search_results_for": "Αποτελέσματα αναζήτησης για"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "This reply was deleted by its author", "this_reply_was_deleted": "This reply was deleted by its author",
"this_reply_was_removed": "This reply was removed by board moderators", "this_reply_was_removed": "This reply was removed by board moderators",
"not_mod_of_any_board": "You are not a mod of any board.", "not_mod_of_any_board": "You are not a mod of any board.",
"filters_and_highlights": "Filters & Highlights" "filters_and_highlights": "Filters & Highlights",
"search_results_for": "Search results for"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Esta respuesta fue eliminada por su autor", "this_reply_was_deleted": "Esta respuesta fue eliminada por su autor",
"this_reply_was_removed": "Esta respuesta fue eliminada por los moderadores del foro", "this_reply_was_removed": "Esta respuesta fue eliminada por los moderadores del foro",
"not_mod_of_any_board": "No eres moderador de ningún tablero.", "not_mod_of_any_board": "No eres moderador de ningún tablero.",
"filters_and_highlights": "Filtros y resaltar" "filters_and_highlights": "Filtros y resaltar",
"search_results_for": "Resultados de búsqueda para"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "این پاسخ توسط نویسنده‌اش حذف شد", "this_reply_was_deleted": "این پاسخ توسط نویسنده‌اش حذف شد",
"this_reply_was_removed": "این پاسخ توسط مدیران انجمن حذف شد", "this_reply_was_removed": "این پاسخ توسط مدیران انجمن حذف شد",
"not_mod_of_any_board": "شما هیچ تابلو مدیر نیستید.", "not_mod_of_any_board": "شما هیچ تابلو مدیر نیستید.",
"filters_and_highlights": "فیلترها و هایلایت‌ها" "filters_and_highlights": "فیلترها و هایلایت‌ها",
"search_results_for": "نتایج جستجو برای"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Tämä vastaus poistettiin sen kirjoittajalta", "this_reply_was_deleted": "Tämä vastaus poistettiin sen kirjoittajalta",
"this_reply_was_removed": "Tämä vastaus poistettiin foorumin moderaattoreiden toimesta", "this_reply_was_removed": "Tämä vastaus poistettiin foorumin moderaattoreiden toimesta",
"not_mod_of_any_board": "Et ole moderaattori missään taulussa.", "not_mod_of_any_board": "Et ole moderaattori missään taulussa.",
"filters_and_highlights": "Suodattimet ja korostukset" "filters_and_highlights": "Suodattimet ja korostukset",
"search_results_for": "Hakutulokset hakusanalle"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Ang tugon na ito ay tinanggal ng may-akda nito", "this_reply_was_deleted": "Ang tugon na ito ay tinanggal ng may-akda nito",
"this_reply_was_removed": "Ang sagot na ito ay tinanggal ng mga moderator ng board", "this_reply_was_removed": "Ang sagot na ito ay tinanggal ng mga moderator ng board",
"not_mod_of_any_board": "Hindi ka mod ng anumang board.", "not_mod_of_any_board": "Hindi ka mod ng anumang board.",
"filters_and_highlights": "Mga filter at highlight" "filters_and_highlights": "Mga filter at highlight",
"search_results_for": "Mga resulta ng paghahanap para sa"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Cette réponse a été supprimée par son auteur", "this_reply_was_deleted": "Cette réponse a été supprimée par son auteur",
"this_reply_was_removed": "Cette réponse a été supprimée par les modérateurs du forum", "this_reply_was_removed": "Cette réponse a été supprimée par les modérateurs du forum",
"not_mod_of_any_board": "Vous n'êtes pas modérateur de n'aucun forum.", "not_mod_of_any_board": "Vous n'êtes pas modérateur de n'aucun forum.",
"filters_and_highlights": "Filtres et mises en évidence" "filters_and_highlights": "Filtres et mises en évidence",
"search_results_for": "Résultats de recherche pour"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "תשובה זו נמחקה על ידי המחבר שלה", "this_reply_was_deleted": "תשובה זו נמחקה על ידי המחבר שלה",
"this_reply_was_removed": "תשובה זו הוסרה על ידי מנהלי הפורום", "this_reply_was_removed": "תשובה זו הוסרה על ידי מנהלי הפורום",
"not_mod_of_any_board": "אתה לא מוד בכל לוח.", "not_mod_of_any_board": "אתה לא מוד בכל לוח.",
"filters_and_highlights": "סינונים והדגשות" "filters_and_highlights": "סינונים והדגשות",
"search_results_for": "תוצאות חיפוש עבור"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "इस उत्तर को इसके लेखक द्वारा हटा दिया गया था", "this_reply_was_deleted": "इस उत्तर को इसके लेखक द्वारा हटा दिया गया था",
"this_reply_was_removed": "यह उत्तर बोर्ड मॉडरेटर द्वारा हटा दिया गया था", "this_reply_was_removed": "यह उत्तर बोर्ड मॉडरेटर द्वारा हटा दिया गया था",
"not_mod_of_any_board": "आप किसी बोर्ड के मॉड नहीं हैं।", "not_mod_of_any_board": "आप किसी बोर्ड के मॉड नहीं हैं।",
"filters_and_highlights": "फ़िल्टर और हाइलाइट्स" "filters_and_highlights": "फ़िल्टर और हाइलाइट्स",
"search_results_for": "के लिए खोज परिणाम"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Ez a válasz törölve lett a szerzője által", "this_reply_was_deleted": "Ez a válasz törölve lett a szerzője által",
"this_reply_was_removed": "Ez a válasz törlésre került a fórum moderátorai által", "this_reply_was_removed": "Ez a válasz törlésre került a fórum moderátorai által",
"not_mod_of_any_board": "Nem vagy moderátor egyetlen táblán sem.", "not_mod_of_any_board": "Nem vagy moderátor egyetlen táblán sem.",
"filters_and_highlights": "Szűrők és kiemelések" "filters_and_highlights": "Szűrők és kiemelések",
"search_results_for": "Keresési eredmények"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Balasan ini dihapus oleh penulisnya", "this_reply_was_deleted": "Balasan ini dihapus oleh penulisnya",
"this_reply_was_removed": "Balasan ini dihapus oleh moderator papan", "this_reply_was_removed": "Balasan ini dihapus oleh moderator papan",
"not_mod_of_any_board": "Anda bukan mod di papan manapun.", "not_mod_of_any_board": "Anda bukan mod di papan manapun.",
"filters_and_highlights": "Filter dan Sorotan" "filters_and_highlights": "Filter dan Sorotan",
"search_results_for": "Hasil pencarian untuk"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Questa risposta è stata eliminata dal suo autore", "this_reply_was_deleted": "Questa risposta è stata eliminata dal suo autore",
"this_reply_was_removed": "Questa risposta è stata rimossa dai moderatori del forum", "this_reply_was_removed": "Questa risposta è stata rimossa dai moderatori del forum",
"not_mod_of_any_board": "Non sei un mod di nessuna board.", "not_mod_of_any_board": "Non sei un mod di nessuna board.",
"filters_and_highlights": "Filtri e Evidenziazioni" "filters_and_highlights": "Filtri e Evidenziazioni",
"search_results_for": "Risultati di ricerca per"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "この返信はその著者によって削除されました", "this_reply_was_deleted": "この返信はその著者によって削除されました",
"this_reply_was_removed": "この返信は掲示板のモデレーターによって削除されました", "this_reply_was_removed": "この返信は掲示板のモデレーターによって削除されました",
"not_mod_of_any_board": "あなたはどのボードのモデレーターでもありません。", "not_mod_of_any_board": "あなたはどのボードのモデレーターでもありません。",
"filters_and_highlights": "フィルターとハイライト" "filters_and_highlights": "フィルターとハイライト",
"search_results_for": "検索結果"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "이 답글은 작성자에 의해 삭제되었습니다", "this_reply_was_deleted": "이 답글은 작성자에 의해 삭제되었습니다",
"this_reply_was_removed": "이 답글은 게시판 관리자에 의해 삭제되었습니다", "this_reply_was_removed": "이 답글은 게시판 관리자에 의해 삭제되었습니다",
"not_mod_of_any_board": "당신은 어떤 게시판의 관리자도 아닙니다.", "not_mod_of_any_board": "당신은 어떤 게시판의 관리자도 아닙니다.",
"filters_and_highlights": "필터 및 하이라이트" "filters_and_highlights": "필터 및 하이라이트",
"search_results_for": "검색 결과"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "हा प्रतिसाद त्याच्या लेखकाने हटवला आहे", "this_reply_was_deleted": "हा प्रतिसाद त्याच्या लेखकाने हटवला आहे",
"this_reply_was_removed": "या उत्तराला बोर्ड मॉडरेटरने काढले आहे", "this_reply_was_removed": "या उत्तराला बोर्ड मॉडरेटरने काढले आहे",
"not_mod_of_any_board": "तुम्ही कोणत्याही बोर्डचे मॉड नाहीत.", "not_mod_of_any_board": "तुम्ही कोणत्याही बोर्डचे मॉड नाहीत.",
"filters_and_highlights": "फिल्टर आणि हायलाइट्स" "filters_and_highlights": "फिल्टर आणि हायलाइट्स",
"search_results_for": "सर्च परिणाम"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Dit antwoord werd verwijderd door de auteur", "this_reply_was_deleted": "Dit antwoord werd verwijderd door de auteur",
"this_reply_was_removed": "Dit antwoord is verwijderd door de forum moderators", "this_reply_was_removed": "Dit antwoord is verwijderd door de forum moderators",
"not_mod_of_any_board": "Je bent geen mod van een bord.", "not_mod_of_any_board": "Je bent geen mod van een bord.",
"filters_and_highlights": "Filters en markeringen" "filters_and_highlights": "Filters en markeringen",
"search_results_for": "Zoekresultaten voor"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Dette svaret ble slettet av forfatteren", "this_reply_was_deleted": "Dette svaret ble slettet av forfatteren",
"this_reply_was_removed": "Dette svaret ble fjernet av forummoderatorer", "this_reply_was_removed": "Dette svaret ble fjernet av forummoderatorer",
"not_mod_of_any_board": "Du er ikke moderator på noen brett.", "not_mod_of_any_board": "Du er ikke moderator på noen brett.",
"filters_and_highlights": "Filtre og fremhevinger" "filters_and_highlights": "Filtre og fremhevinger",
"search_results_for": "Søkeresultater for"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Ta odpowiedź została usunięta przez autora", "this_reply_was_deleted": "Ta odpowiedź została usunięta przez autora",
"this_reply_was_removed": "Ta odpowiedź została usunięta przez moderatorów forum", "this_reply_was_removed": "Ta odpowiedź została usunięta przez moderatorów forum",
"not_mod_of_any_board": "Nie jesteś moderatorem żadnej tablicy.", "not_mod_of_any_board": "Nie jesteś moderatorem żadnej tablicy.",
"filters_and_highlights": "Filtry i wyróżnienia" "filters_and_highlights": "Filtry i wyróżnienia",
"search_results_for": "Wyniki wyszukiwania dla"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Esta resposta foi excluída pelo autor", "this_reply_was_deleted": "Esta resposta foi excluída pelo autor",
"this_reply_was_removed": "Esta resposta foi removida pelos moderadores do fórum", "this_reply_was_removed": "Esta resposta foi removida pelos moderadores do fórum",
"not_mod_of_any_board": "Você não é um moderador de nenhum quadro.", "not_mod_of_any_board": "Você não é um moderador de nenhum quadro.",
"filters_and_highlights": "Filtros e Destaques" "filters_and_highlights": "Filtros e Destaques",
"search_results_for": "Resultados de pesquisa para"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Acest răspuns a fost șters de autorul său", "this_reply_was_deleted": "Acest răspuns a fost șters de autorul său",
"this_reply_was_removed": "Acest răspuns a fost eliminat de moderatorii forumului", "this_reply_was_removed": "Acest răspuns a fost eliminat de moderatorii forumului",
"not_mod_of_any_board": "Nu ești moderator pe niciun tablou.", "not_mod_of_any_board": "Nu ești moderator pe niciun tablou.",
"filters_and_highlights": "Filtre și evidențiere" "filters_and_highlights": "Filtre și evidențiere",
"search_results_for": "Rezultatele căutării pentru"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Этот ответ был удален автором", "this_reply_was_deleted": "Этот ответ был удален автором",
"this_reply_was_removed": "Этот ответ был удален модераторами форума", "this_reply_was_removed": "Этот ответ был удален модераторами форума",
"not_mod_of_any_board": "Вы не модератор ни одной доски.", "not_mod_of_any_board": "Вы не модератор ни одной доски.",
"filters_and_highlights": "Фильтры и выделения" "filters_and_highlights": "Фильтры и выделения",
"search_results_for": "Результаты поиска для"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Ky përgjigje u fshi nga autori i saj", "this_reply_was_deleted": "Ky përgjigje u fshi nga autori i saj",
"this_reply_was_removed": "Ky përgjigje u hoq nga moderatorët e forumit", "this_reply_was_removed": "Ky përgjigje u hoq nga moderatorët e forumit",
"not_mod_of_any_board": "Nuk jeni mod në asnjë bord.", "not_mod_of_any_board": "Nuk jeni mod në asnjë bord.",
"filters_and_highlights": "Filtra dhe theksime" "filters_and_highlights": "Filtra dhe theksime",
"search_results_for": "Rezultatet e kërkimit për"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Detta svar togs bort av författaren", "this_reply_was_deleted": "Detta svar togs bort av författaren",
"this_reply_was_removed": "Detta svar togs bort av forumets moderatorer", "this_reply_was_removed": "Detta svar togs bort av forumets moderatorer",
"not_mod_of_any_board": "Du är inte moderator på någon tavla.", "not_mod_of_any_board": "Du är inte moderator på någon tavla.",
"filters_and_highlights": "Filter och markeringar" "filters_and_highlights": "Filter och markeringar",
"search_results_for": "Sökresultat för"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "ఈ స్పందనను దాని రచయిత తొలగించారు", "this_reply_was_deleted": "ఈ స్పందనను దాని రచయిత తొలగించారు",
"this_reply_was_removed": "ఈ స్పందన బోర్డ్ మోడరేటర్లచే తొలగించబడింది", "this_reply_was_removed": "ఈ స్పందన బోర్డ్ మోడరేటర్లచే తొలగించబడింది",
"not_mod_of_any_board": "మీరు ఎటువంటి బోర్డుకు మోడ్ కంటే లేరు.", "not_mod_of_any_board": "మీరు ఎటువంటి బోర్డుకు మోడ్ కంటే లేరు.",
"filters_and_highlights": "ఫిల్టర్లు మరియు హైలైట్‌లు" "filters_and_highlights": "ఫిల్టర్లు మరియు హైలైట్‌లు",
"search_results_for": "శోధన ఫలితాలు"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "การตอบกลับนี้ถูกลบโดยผู้แต่ง", "this_reply_was_deleted": "การตอบกลับนี้ถูกลบโดยผู้แต่ง",
"this_reply_was_removed": "คำตอบนี้ถูกลบโดยผู้ดูแลบอร์ด", "this_reply_was_removed": "คำตอบนี้ถูกลบโดยผู้ดูแลบอร์ด",
"not_mod_of_any_board": "คุณไม่ใช่ผู้ดูแลบอร์ดใดๆ", "not_mod_of_any_board": "คุณไม่ใช่ผู้ดูแลบอร์ดใดๆ",
"filters_and_highlights": "ตัวกรองและไฮไลท์" "filters_and_highlights": "ตัวกรองและไฮไลท์",
"search_results_for": "ผลการค้นหาสำหรับ"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Bu yanıt, yazar tarafından silindi", "this_reply_was_deleted": "Bu yanıt, yazar tarafından silindi",
"this_reply_was_removed": "Bu yanıt, forum moderatörleri tarafından kaldırıldı", "this_reply_was_removed": "Bu yanıt, forum moderatörleri tarafından kaldırıldı",
"not_mod_of_any_board": "Hiçbir tahtanın moderatörü değilsiniz.", "not_mod_of_any_board": "Hiçbir tahtanın moderatörü değilsiniz.",
"filters_and_highlights": "Filtreler ve Vurgular" "filters_and_highlights": "Filtreler ve Vurgular",
"search_results_for": "Arama sonuçları için"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Цю відповідь було видалено її автором", "this_reply_was_deleted": "Цю відповідь було видалено її автором",
"this_reply_was_removed": "Цю відповідь було видалено модераторами форуму", "this_reply_was_removed": "Цю відповідь було видалено модераторами форуму",
"not_mod_of_any_board": "Ви не модератор жодної дошки.", "not_mod_of_any_board": "Ви не модератор жодної дошки.",
"filters_and_highlights": "Фільтри та виділення" "filters_and_highlights": "Фільтри та виділення",
"search_results_for": "Результати пошуку для"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "اس جواب کو اس کے مصنف نے حذف کر دیا تھا", "this_reply_was_deleted": "اس جواب کو اس کے مصنف نے حذف کر دیا تھا",
"this_reply_was_removed": "اس جواب کو بورڈ کے منتظمین نے حذف کر دیا ہے", "this_reply_was_removed": "اس جواب کو بورڈ کے منتظمین نے حذف کر دیا ہے",
"not_mod_of_any_board": "آپ کسی بورڈ کے موڈ نہیں ہیں۔", "not_mod_of_any_board": "آپ کسی بورڈ کے موڈ نہیں ہیں۔",
"filters_and_highlights": "فلٹرز اور ہائیلائٹس" "filters_and_highlights": "فلٹرز اور ہائیلائٹس",
"search_results_for": "تلاش کے نتائج"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "Câu trả lời này đã bị tác giả của nó xóa", "this_reply_was_deleted": "Câu trả lời này đã bị tác giả của nó xóa",
"this_reply_was_removed": "Phản hồi này đã bị xóa bởi các quản trị viên diễn đàn", "this_reply_was_removed": "Phản hồi này đã bị xóa bởi các quản trị viên diễn đàn",
"not_mod_of_any_board": "Bạn không phải là quản trị viên của bất kỳ bảng nào.", "not_mod_of_any_board": "Bạn không phải là quản trị viên của bất kỳ bảng nào.",
"filters_and_highlights": "Bộ lọc và Nổi bật" "filters_and_highlights": "Bộ lọc và Nổi bật",
"search_results_for": "Kết quả tìm kiếm cho"
} }
+2 -1
View File
@@ -292,5 +292,6 @@
"this_reply_was_deleted": "该回复已被其作者删除", "this_reply_was_deleted": "该回复已被其作者删除",
"this_reply_was_removed": "该回复已被版主删除", "this_reply_was_removed": "该回复已被版主删除",
"not_mod_of_any_board": "您不是任何板块的管理员。", "not_mod_of_any_board": "您不是任何板块的管理员。",
"filters_and_highlights": "筛选器和高亮" "filters_and_highlights": "筛选器和高亮",
"search_results_for": "搜索结果"
} }
+22 -6
View File
@@ -246,7 +246,7 @@ export const MobileBoardButtons = () => {
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
const { filteredCount } = useCatalogFiltersStore(); const { filteredCount, searchText } = useCatalogFiltersStore();
return ( return (
<div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}> <div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}>
@@ -269,11 +269,19 @@ export const MobileBoardButtons = () => {
)} )}
{!(isInAllView || isInSubscriptionsView) && <SubscribeButton address={subplebbitAddress} />} {!(isInAllView || isInSubscriptionsView) && <SubscribeButton address={subplebbitAddress} />}
<RefreshButton /> <RefreshButton />
{isInCatalogView && filteredCount > 0 && ( {isInCatalogView && searchText ? (
<span className={styles.filteredThreadsCount}> <span className={styles.filteredThreadsCount}>
{' '} {' '}
{t('filtered_threads')}: <strong>{filteredCount}</strong> {t('search_results_for')}: <strong>{searchText}</strong>
</span> </span>
) : (
isInCatalogView &&
filteredCount > 0 && (
<span className={styles.filteredThreadsCount}>
{' '}
{t('filtered_threads')}: <strong>{filteredCount}</strong>
</span>
)
)} )}
{isInCatalogView && ( {isInCatalogView && (
<> <>
@@ -331,7 +339,7 @@ export const DesktopBoardButtons = () => {
const isInPostView = isPostPageView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
const { filteredCount } = useCatalogFiltersStore(); const { filteredCount, searchText } = useCatalogFiltersStore();
return ( return (
<> <>
@@ -364,11 +372,19 @@ export const DesktopBoardButtons = () => {
</> </>
)} )}
[<RefreshButton />] [<RefreshButton />]
{isInCatalogView && filteredCount > 0 && ( {isInCatalogView && searchText ? (
<span className={styles.filteredThreadsCount}> <span className={styles.filteredThreadsCount}>
{' '} {' '}
{t('filtered_threads')}: <strong>{filteredCount}</strong> {t('search_results_for')}: <strong>{searchText}</strong>
</span> </span>
) : (
isInCatalogView &&
filteredCount > 0 && (
<span className={styles.filteredThreadsCount}>
{' '}
{t('filtered_threads')}: <strong>{filteredCount}</strong>
</span>
)
)} )}
<span className={styles.rightSideButtons}> <span className={styles.rightSideButtons}>
{isInCatalogView && ( {isInCatalogView && (
@@ -1,11 +1,43 @@
import { useEffect, useState } from 'react'; import { useEffect, useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import styles from './catalog-search.module.css'; import styles from './catalog-search.module.css';
import useIsMobile from '../../hooks/use-is-mobile'; import useIsMobile from '../../hooks/use-is-mobile';
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
import _ from 'lodash';
const CatalogSearch = () => { const CatalogSearch = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [openSearch, setOpenSearch] = useState(false); const [openSearch, setOpenSearch] = useState(false);
const [inputValue, setInputValue] = useState('');
const { setSearchFilter, clearSearchFilter } = useCatalogFiltersStore();
// Create a debounced version of setSearchFilter
// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedSetSearchFilter = useCallback(
_.debounce((text: string) => {
if (text.trim()) {
setSearchFilter(text);
} else {
clearSearchFilter();
}
}, 300),
[setSearchFilter, clearSearchFilter],
);
const handleToggleSearch = useCallback(() => {
setOpenSearch((prev) => !prev);
if (openSearch) {
setInputValue('');
clearSearchFilter();
}
}, [openSearch, clearSearchFilter]);
const handleCloseSearch = useCallback(() => {
setOpenSearch(false);
setInputValue('');
clearSearchFilter();
}, [clearSearchFilter]);
useEffect(() => { useEffect(() => {
if (openSearch) { if (openSearch) {
@@ -14,26 +46,42 @@ const CatalogSearch = () => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') { if (event.key === 'Escape') {
setOpenSearch(false); handleCloseSearch();
} }
}; };
window.addEventListener('keydown', handleKeyDown); window.addEventListener('keydown', handleKeyDown);
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
} }
}, [openSearch]); }, [openSearch, handleCloseSearch]);
useEffect(() => {
debouncedSetSearchFilter(inputValue);
return () => {
debouncedSetSearchFilter.cancel();
};
}, [inputValue, debouncedSetSearchFilter]);
const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
const isMobile = useIsMobile(); const isMobile = useIsMobile();
return ( return (
<> <>
{!isMobile && '['} {!isMobile && '['}
<span className={`${styles.filtersButton} button`} onClick={() => setOpenSearch(!openSearch)}> <span className={`${styles.filtersButton} button`} onClick={handleToggleSearch}>
{t('search')} {t('search')}
</span> </span>
{!isMobile && ']'} {!isMobile && ']'}
{openSearch && ( {openSearch && (
<div className={styles.searchContainer}> <div className={styles.searchContainer}>
<input type='text' /> <input type='text' value={inputValue} onChange={handleSearchChange} />
<span className={styles.closeSearch} onClick={() => setOpenSearch(false)}> <span className={styles.closeSearch} onClick={handleCloseSearch}>
</span> </span>
</div> </div>
+4 -2
View File
@@ -7,6 +7,7 @@ import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils';
import { isAllView } from '../lib/utils/view-utils'; import { isAllView } from '../lib/utils/view-utils';
import { useMultisubMetadata } from './use-default-subplebbits'; import { useMultisubMetadata } from './use-default-subplebbits';
import _ from 'lodash'; import _ from 'lodash';
import useCatalogFiltersStore from '../stores/use-catalog-filters-store';
const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolean, subplebbit: Subplebbit) => { const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolean, subplebbit: Subplebbit) => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -19,6 +20,7 @@ const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolea
const multisub = useMultisubMetadata(); const multisub = useMultisubMetadata();
const { accountComments } = useAccountComments(); const { accountComments } = useAccountComments();
const { searchText } = useCatalogFiltersStore();
const feedWithFakePostsOnTop = useMemo(() => { const feedWithFakePostsOnTop = useMemo(() => {
if (!isFeedLoaded) { if (!isFeedLoaded) {
@@ -64,7 +66,7 @@ const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolea
} }
// add subplebbit description and rules as fake posts at the top of the feed // add subplebbit description and rules as fake posts at the top of the feed
if (description && description.length > 0) { if (description && description.length > 0 && !searchText) {
_feed.unshift({ _feed.unshift({
isDescription: true, isDescription: true,
subplebbitAddress: address, subplebbitAddress: address,
@@ -79,7 +81,7 @@ const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolea
} }
// rules are shown in description thread if both are set // rules are shown in description thread if both are set
if (rules && rules.length > 0 && !description) { if (rules && rules.length > 0 && !description && !searchText) {
_feed.unshift({ _feed.unshift({
isRules: true, isRules: true,
subplebbitAddress: address, subplebbitAddress: address,
+23
View File
@@ -31,6 +31,9 @@ interface CatalogFiltersStore {
currentSubplebbitAddress: string | null; currentSubplebbitAddress: string | null;
setCurrentSubplebbitAddress: (address: string | null) => void; setCurrentSubplebbitAddress: (address: string | null) => void;
getFilteredCountForCurrentSubplebbit: () => number; getFilteredCountForCurrentSubplebbit: () => number;
searchText: string;
setSearchFilter: (text: string) => void;
clearSearchFilter: () => void;
} }
const useCatalogFiltersStore = create( const useCatalogFiltersStore = create(
@@ -48,6 +51,15 @@ const useCatalogFiltersStore = create(
filteredCids: new Set<string>(), filteredCids: new Set<string>(),
currentSubplebbitAddress: null, currentSubplebbitAddress: null,
setCurrentSubplebbitAddress: (address: string | null) => set({ currentSubplebbitAddress: address }), setCurrentSubplebbitAddress: (address: string | null) => set({ currentSubplebbitAddress: address }),
searchText: '',
setSearchFilter: (text: string) => {
set({ searchText: text });
get().updateFilter();
},
clearSearchFilter: () => {
set({ searchText: '' });
get().updateFilter();
},
setFilterItems: (items: FilterItem[]) => { setFilterItems: (items: FilterItem[]) => {
const nonEmptyItems = items const nonEmptyItems = items
.filter((item) => item.text.trim() !== '') .filter((item) => item.text.trim() !== '')
@@ -87,6 +99,17 @@ const useCatalogFiltersStore = create(
set((state) => ({ set((state) => ({
filter: (comment: Comment) => { filter: (comment: Comment) => {
if (!comment?.cid) return true; if (!comment?.cid) return true;
if (state.searchText.trim() !== '') {
const searchPattern = state.searchText.toLowerCase();
const title = comment?.title?.toLowerCase() || '';
const content = comment?.content?.toLowerCase() || '';
if (!title.includes(searchPattern) && !content.includes(searchPattern)) {
return false;
}
}
const { filterItems } = state; const { filterItems } = state;
let shouldHide = false; let shouldHide = false;
for (let i = 0; i < filterItems.length; i++) { for (let i = 0; i < filterItems.length; i++) {
+39 -10
View File
@@ -92,19 +92,35 @@ const createImageFilter = (showTextOnlyThreads: boolean) => {
const createCombinedFilter = ( const createCombinedFilter = (
showTextOnlyThreads: boolean, showTextOnlyThreads: boolean,
filterItems: { text: string; enabled: boolean; count: number; filteredCids: Set<string>; hide: boolean; top: boolean }[], filterItems: { text: string; enabled: boolean; count: number; filteredCids: Set<string>; hide: boolean; top: boolean }[],
searchText: string,
subplebbitAddress: string, subplebbitAddress: string,
onFilterMatch?: (filterIndex: number, cid: string, subplebbitAddress: string) => void, onFilterMatch?: (filterIndex: number, cid: string, subplebbitAddress: string) => void,
) => { ) => {
const imageFilter = createImageFilter(showTextOnlyThreads); const imageFilter = createImageFilter(showTextOnlyThreads);
const contentFilter = createContentFilter(filterItems, subplebbitAddress, onFilterMatch); const contentFilter = createContentFilter(filterItems, subplebbitAddress, onFilterMatch);
const searchFilter = {
filter: (comment: Comment) => {
if (!searchText.trim()) return true;
const titleLower = comment?.title?.toLowerCase() || '';
const contentLower = comment?.content?.toLowerCase() || '';
const searchPattern = searchText.toLowerCase();
return titleLower.includes(searchPattern) || contentLower.includes(searchPattern);
},
key: searchText ? `search-filter-${searchText}` : 'no-search-filter',
};
return { return {
filter: (comment: Comment) => { filter: (comment: Comment) => {
if (!imageFilter.filter(comment)) return false; if (!imageFilter.filter(comment)) return false;
if (!contentFilter.filter(comment)) return false;
if (!searchFilter.filter(comment)) return false;
return contentFilter.filter(comment); return true;
}, },
key: `${imageFilter.key}-${contentFilter.key}`, key: `${imageFilter.key}-${contentFilter.key}-${searchFilter.key}`,
}; };
}; };
@@ -116,7 +132,7 @@ const Catalog = () => {
const isInAllView = isAllView(location.pathname); const isInAllView = isAllView(location.pathname);
const defaultSubplebbits = useDefaultSubplebbits(); const defaultSubplebbits = useDefaultSubplebbits();
const { hideAdultBoards, hideGoreBoards } = useInterfaceSettingsStore(); const { hideAdultBoards, hideGoreBoards } = useInterfaceSettingsStore();
const { showTextOnlyThreads, filterItems } = useCatalogFiltersStore(); const { showTextOnlyThreads, filterItems, searchText } = useCatalogFiltersStore();
const account = useAccount(); const account = useAccount();
const subscriptions = account?.subscriptions; const subscriptions = account?.subscriptions;
@@ -172,7 +188,7 @@ const Catalog = () => {
subplebbitAddresses, subplebbitAddresses,
sortType, sortType,
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage, postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
filter: createCombinedFilter(showTextOnlyThreads, filterItems, subplebbitAddress || 'all', handleFilterMatch), filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
}; };
if (isInAllView || isInSubscriptionsView) { if (isInAllView || isInSubscriptionsView) {
@@ -189,6 +205,7 @@ const Catalog = () => {
timeFilterSeconds, timeFilterSeconds,
showTextOnlyThreads, showTextOnlyThreads,
filterItems, filterItems,
searchText,
subplebbitAddress, subplebbitAddress,
handleFilterMatch, handleFilterMatch,
]); ]);
@@ -203,7 +220,9 @@ const Catalog = () => {
() => () =>
accountComments.filter((comment) => { accountComments.filter((comment) => {
const { cid, deleted, link, linkHeight, linkWidth, postCid, removed, state, thumbnailUrl, timestamp } = comment || {}; const { cid, deleted, link, linkHeight, linkWidth, postCid, removed, state, thumbnailUrl, timestamp } = comment || {};
return (
// Basic filtering conditions
const basicConditions =
!deleted && !deleted &&
!removed && !removed &&
timestamp > Date.now() / 1000 - 60 * 60 && timestamp > Date.now() / 1000 - 60 * 60 &&
@@ -212,10 +231,20 @@ const Catalog = () => {
(showTextOnlyThreads ? getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), comment?.link) : true) && (showTextOnlyThreads ? getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), comment?.link) : true) &&
cid === postCid && cid === postCid &&
comment?.subplebbitAddress === subplebbitAddress && comment?.subplebbitAddress === subplebbitAddress &&
!feed.some((post) => post.cid === cid) !feed.some((post) => post.cid === cid);
);
// If search is active, also check search conditions
if (basicConditions && searchText.trim()) {
const titleLower = comment?.title?.toLowerCase() || '';
const contentLower = comment?.content?.toLowerCase() || '';
const searchPattern = searchText.toLowerCase();
return titleLower.includes(searchPattern) || contentLower.includes(searchPattern);
}
return basicConditions;
}), }),
[accountComments, subplebbitAddress, feed, showTextOnlyThreads], [accountComments, subplebbitAddress, feed, showTextOnlyThreads, searchText],
); );
// show newest account comment at the top of the feed but after pinned posts // show newest account comment at the top of the feed but after pinned posts
@@ -247,14 +276,14 @@ const Catalog = () => {
subplebbitAddresses, subplebbitAddresses,
sortType, sortType,
newerThan: 60 * 60 * 24 * 7, newerThan: 60 * 60 * 24 * 7,
filter: createCombinedFilter(showTextOnlyThreads, filterItems, subplebbitAddress || 'all', handleFilterMatch), filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
}); });
const { feed: monthlyFeed } = useFeed({ const { feed: monthlyFeed } = useFeed({
subplebbitAddresses, subplebbitAddresses,
sortType, sortType,
newerThan: 60 * 60 * 24 * 30, newerThan: 60 * 60 * 24 * 30,
filter: createCombinedFilter(showTextOnlyThreads, filterItems, subplebbitAddress || 'all', handleFilterMatch), filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
}); });
const [showMorePostsSuggestion, setShowMorePostsSuggestion] = useState(false); const [showMorePostsSuggestion, setShowMorePostsSuggestion] = useState(false);
+1 -1
View File
@@ -562,7 +562,7 @@
width: 24px; width: 24px;
max-height: 24px; max-height: 24px;
position: absolute; position: absolute;
bottom: -5px; bottom: -7px;
} }
@media (max-width: 640px) { @media (max-width: 640px) {