mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(catalog): add catalog filters
This commit is contained in:
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "تم إزالة هذا الموضوع بواسطة مشرفي المنتدى",
|
"this_thread_was_removed": "تم إزالة هذا الموضوع بواسطة مشرفي المنتدى",
|
||||||
"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": "الفلاتر والإبرازات"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "এই থ্রেডটি বোর্ড moderators দ্বারা মুছে ফেলা হয়েছে",
|
"this_thread_was_removed": "এই থ্রেডটি বোর্ড moderators দ্বারা মুছে ফেলা হয়েছে",
|
||||||
"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": "ফিল্টার এবং হাইলাইট"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Čeká na schválení",
|
"pending": "Čeká na schválení",
|
||||||
"failed": "Nepodařilo se",
|
"failed": "Nepodařilo se",
|
||||||
"add": "Přidat",
|
"add": "Přidat",
|
||||||
"pattern": "Vzor",
|
"pattern": "vzor",
|
||||||
"enable": "Povolit",
|
"enable": "Povolit",
|
||||||
"order": "Pořadí",
|
"order": "Pořadí",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Toto vlákno bylo odstraněno moderátory fóra",
|
"this_thread_was_removed": "Toto vlákno bylo odstraněno moderátory fóra",
|
||||||
"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í"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Afventer",
|
"pending": "Afventer",
|
||||||
"failed": "Mislykkedes",
|
"failed": "Mislykkedes",
|
||||||
"add": "Tilføj",
|
"add": "Tilføj",
|
||||||
"pattern": "Mønster",
|
"pattern": "mønster",
|
||||||
"enable": "Aktiver",
|
"enable": "Aktiver",
|
||||||
"order": "Rækkefølge",
|
"order": "Rækkefølge",
|
||||||
"text": "Tekst",
|
"text": "Tekst",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Denne tråd blev fjernet af boardmoderatorer",
|
"this_thread_was_removed": "Denne tråd blev fjernet af boardmoderatorer",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Dieser Thread wurde von den Moderatoren des Boards entfernt",
|
"this_thread_was_removed": "Dieser Thread wurde von den Moderatoren des Boards entfernt",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Σε εκκρεμότητα",
|
"pending": "Σε εκκρεμότητα",
|
||||||
"failed": "Απέτυχε",
|
"failed": "Απέτυχε",
|
||||||
"add": "Προσθήκη",
|
"add": "Προσθήκη",
|
||||||
"pattern": "Μοτίβο",
|
"pattern": "μοτίβο",
|
||||||
"enable": "Ενεργοποιήστε",
|
"enable": "Ενεργοποιήστε",
|
||||||
"order": "Σειρά",
|
"order": "Σειρά",
|
||||||
"text": "Κείμενο",
|
"text": "Κείμενο",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Αυτή η συζήτηση αφαιρέθηκε από τους διαχειριστές του φόρουμ",
|
"this_thread_was_removed": "Αυτή η συζήτηση αφαιρέθηκε από τους διαχειριστές του φόρουμ",
|
||||||
"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": "Φίλτρα και επισημάνσεις"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Pending",
|
"pending": "Pending",
|
||||||
"failed": "Failed",
|
"failed": "Failed",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"pattern": "Pattern",
|
"pattern": "pattern",
|
||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"order": "Order",
|
"order": "Order",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "This thread was removed by board moderators",
|
"this_thread_was_removed": "This thread was removed by board moderators",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Pendiente",
|
"pending": "Pendiente",
|
||||||
"failed": "Fallido",
|
"failed": "Fallido",
|
||||||
"add": "Añadir",
|
"add": "Añadir",
|
||||||
"pattern": "Patrón",
|
"pattern": "patrón",
|
||||||
"enable": "Habilitar",
|
"enable": "Habilitar",
|
||||||
"order": "Orden",
|
"order": "Orden",
|
||||||
"text": "Texto",
|
"text": "Texto",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Este hilo fue eliminado por los moderadores del foro",
|
"this_thread_was_removed": "Este hilo fue eliminado por los moderadores del foro",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "این تاپیک توسط مدیران انجمن حذف شد",
|
"this_thread_was_removed": "این تاپیک توسط مدیران انجمن حذف شد",
|
||||||
"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": "فیلترها و هایلایتها"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Odottaa",
|
"pending": "Odottaa",
|
||||||
"failed": "Epäonnistui",
|
"failed": "Epäonnistui",
|
||||||
"add": "Lisää",
|
"add": "Lisää",
|
||||||
"pattern": "Malli",
|
"pattern": "malli",
|
||||||
"enable": "Ota käyttöön",
|
"enable": "Ota käyttöön",
|
||||||
"order": "Järjestys",
|
"order": "Järjestys",
|
||||||
"text": "Teksti",
|
"text": "Teksti",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Tämä ketju poistettiin foorumin moderaattoreiden toimesta",
|
"this_thread_was_removed": "Tämä ketju poistettiin foorumin moderaattoreiden toimesta",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Naghihintay",
|
"pending": "Naghihintay",
|
||||||
"failed": "Nabigo",
|
"failed": "Nabigo",
|
||||||
"add": "Idagdag",
|
"add": "Idagdag",
|
||||||
"pattern": "Pattern",
|
"pattern": "pattern",
|
||||||
"enable": "I-enable",
|
"enable": "I-enable",
|
||||||
"order": "Kaayusan",
|
"order": "Kaayusan",
|
||||||
"text": "Teksto",
|
"text": "Teksto",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Inalis ang thread na ito ng mga moderator ng board",
|
"this_thread_was_removed": "Inalis ang thread na ito ng mga moderator ng board",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "En attente",
|
"pending": "En attente",
|
||||||
"failed": "Échoué",
|
"failed": "Échoué",
|
||||||
"add": "Ajouter",
|
"add": "Ajouter",
|
||||||
"pattern": "Modèle",
|
"pattern": "motif",
|
||||||
"enable": "Activer",
|
"enable": "Activer",
|
||||||
"order": "Ordre",
|
"order": "Ordre",
|
||||||
"text": "Texte",
|
"text": "Texte",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Ce sujet a été supprimé par les modérateurs du forum",
|
"this_thread_was_removed": "Ce sujet a été supprimé par les modérateurs du forum",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "ממתין",
|
"pending": "ממתין",
|
||||||
"failed": "נכשל",
|
"failed": "נכשל",
|
||||||
"add": "הוסף",
|
"add": "הוסף",
|
||||||
"pattern": "תבנית",
|
"pattern": "דפוס",
|
||||||
"enable": "הפעל",
|
"enable": "הפעל",
|
||||||
"order": "סדר",
|
"order": "סדר",
|
||||||
"text": "טקסט",
|
"text": "טקסט",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "השרשור הזה הוסר על ידי מנהלי הפורום",
|
"this_thread_was_removed": "השרשור הזה הוסר על ידי מנהלי הפורום",
|
||||||
"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": "סינונים והדגשות"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "यह थ्रेड बोर्ड मॉडरेटर्स द्वारा हटा दिया गया था",
|
"this_thread_was_removed": "यह थ्रेड बोर्ड मॉडरेटर्स द्वारा हटा दिया गया था",
|
||||||
"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": "फ़िल्टर और हाइलाइट्स"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Függőben",
|
"pending": "Függőben",
|
||||||
"failed": "Sikertelen",
|
"failed": "Sikertelen",
|
||||||
"add": "Hozzáad",
|
"add": "Hozzáad",
|
||||||
"pattern": "Minta",
|
"pattern": "minta",
|
||||||
"enable": "Engedélyez",
|
"enable": "Engedélyez",
|
||||||
"order": "Rendelés",
|
"order": "Rendelés",
|
||||||
"text": "Szöveg",
|
"text": "Szöveg",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Ezt a témát a fórum moderátorai eltávolították",
|
"this_thread_was_removed": "Ezt a témát a fórum moderátorai eltávolították",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Tertunda",
|
"pending": "Tertunda",
|
||||||
"failed": "Gagal",
|
"failed": "Gagal",
|
||||||
"add": "Tambahkan",
|
"add": "Tambahkan",
|
||||||
"pattern": "Pola",
|
"pattern": "pola",
|
||||||
"enable": "Aktifkan",
|
"enable": "Aktifkan",
|
||||||
"order": "Urutan",
|
"order": "Urutan",
|
||||||
"text": "Teks",
|
"text": "Teks",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Thread ini dihapus oleh moderator papan",
|
"this_thread_was_removed": "Thread ini dihapus oleh moderator papan",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "In attesa",
|
"pending": "In attesa",
|
||||||
"failed": "Fallito",
|
"failed": "Fallito",
|
||||||
"add": "Aggiungi",
|
"add": "Aggiungi",
|
||||||
"pattern": "Modello",
|
"pattern": "modello",
|
||||||
"enable": "Abilita",
|
"enable": "Abilita",
|
||||||
"order": "Ordine",
|
"order": "Ordine",
|
||||||
"text": "Testo",
|
"text": "Testo",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Questo thread è stato rimosso dai moderatori del board",
|
"this_thread_was_removed": "Questo thread è stato rimosso dai moderatori del board",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "このスレッドはボードのモデレーターによって削除されました",
|
"this_thread_was_removed": "このスレッドはボードのモデレーターによって削除されました",
|
||||||
"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": "フィルターとハイライト"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "이 스레드는 보드 관리자에 의해 제거되었습니다",
|
"this_thread_was_removed": "이 스레드는 보드 관리자에 의해 제거되었습니다",
|
||||||
"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": "필터 및 하이라이트"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "हे थ्रेड बोर्ड मध्यमाने काढले गेले आहे",
|
"this_thread_was_removed": "हे थ्रेड बोर्ड मध्यमाने काढले गेले आहे",
|
||||||
"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": "फिल्टर आणि हायलाइट्स"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "In afwachting",
|
"pending": "In afwachting",
|
||||||
"failed": "Mislukt",
|
"failed": "Mislukt",
|
||||||
"add": "Toevoegen",
|
"add": "Toevoegen",
|
||||||
"pattern": "Patroon",
|
"pattern": "patroon",
|
||||||
"enable": "Inschakelen",
|
"enable": "Inschakelen",
|
||||||
"order": "Volgorde",
|
"order": "Volgorde",
|
||||||
"text": "Tekst",
|
"text": "Tekst",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Deze thread werd verwijderd door boardmoderators",
|
"this_thread_was_removed": "Deze thread werd verwijderd door boardmoderators",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Venter",
|
"pending": "Venter",
|
||||||
"failed": "Feilet",
|
"failed": "Feilet",
|
||||||
"add": "Legg til",
|
"add": "Legg til",
|
||||||
"pattern": "Mønster",
|
"pattern": "mønster",
|
||||||
"enable": "Aktiver",
|
"enable": "Aktiver",
|
||||||
"order": "Rekkefølge",
|
"order": "Rekkefølge",
|
||||||
"text": "Tekst",
|
"text": "Tekst",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Denne tråden ble fjernet av boardmoderatorer",
|
"this_thread_was_removed": "Denne tråden ble fjernet av boardmoderatorer",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Oczekujące",
|
"pending": "Oczekujące",
|
||||||
"failed": "Nieudane",
|
"failed": "Nieudane",
|
||||||
"add": "Dodaj",
|
"add": "Dodaj",
|
||||||
"pattern": "Wzór",
|
"pattern": "wzór",
|
||||||
"enable": "Włącz",
|
"enable": "Włącz",
|
||||||
"order": "Kolejność",
|
"order": "Kolejność",
|
||||||
"text": "Tekst",
|
"text": "Tekst",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Wątek został usunięty przez moderatorów forum",
|
"this_thread_was_removed": "Wątek został usunięty przez moderatorów forum",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Pendente",
|
"pending": "Pendente",
|
||||||
"failed": "Falhou",
|
"failed": "Falhou",
|
||||||
"add": "Adicionar",
|
"add": "Adicionar",
|
||||||
"pattern": "Padrão",
|
"pattern": "padrão",
|
||||||
"enable": "Ativar",
|
"enable": "Ativar",
|
||||||
"order": "Ordem",
|
"order": "Ordem",
|
||||||
"text": "Texto",
|
"text": "Texto",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Este tópico foi removido pelos moderadores do fórum",
|
"this_thread_was_removed": "Este tópico foi removido pelos moderadores do fórum",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "În așteptare",
|
"pending": "În așteptare",
|
||||||
"failed": "Eșuat",
|
"failed": "Eșuat",
|
||||||
"add": "Adaugă",
|
"add": "Adaugă",
|
||||||
"pattern": "Model",
|
"pattern": "model",
|
||||||
"enable": "Activare",
|
"enable": "Activare",
|
||||||
"order": "Ordine",
|
"order": "Ordine",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Acest thread a fost eliminat de moderatorii board-ului",
|
"this_thread_was_removed": "Acest thread a fost eliminat de moderatorii board-ului",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "В ожидании",
|
"pending": "В ожидании",
|
||||||
"failed": "Не удалось",
|
"failed": "Не удалось",
|
||||||
"add": "Добавить",
|
"add": "Добавить",
|
||||||
"pattern": "Шаблон",
|
"pattern": "узор",
|
||||||
"enable": "Включить",
|
"enable": "Включить",
|
||||||
"order": "Порядок",
|
"order": "Порядок",
|
||||||
"text": "Текст",
|
"text": "Текст",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Эта тема была удалена модераторами форума",
|
"this_thread_was_removed": "Эта тема была удалена модераторами форума",
|
||||||
"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": "Фильтры и выделения"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Në pritje",
|
"pending": "Në pritje",
|
||||||
"failed": "Dështuar",
|
"failed": "Dështuar",
|
||||||
"add": "Shto",
|
"add": "Shto",
|
||||||
"pattern": "Model",
|
"pattern": "model",
|
||||||
"enable": "Aktivizo",
|
"enable": "Aktivizo",
|
||||||
"order": "Rendit",
|
"order": "Rendit",
|
||||||
"text": "Tekst",
|
"text": "Tekst",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Ky thread u hoq nga moderatorët e bordit",
|
"this_thread_was_removed": "Ky thread u hoq nga moderatorët e bordit",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Väntande",
|
"pending": "Väntande",
|
||||||
"failed": "Misslyckades",
|
"failed": "Misslyckades",
|
||||||
"add": "Lägg till",
|
"add": "Lägg till",
|
||||||
"pattern": "Mönster",
|
"pattern": "mönster",
|
||||||
"enable": "Aktivera",
|
"enable": "Aktivera",
|
||||||
"order": "Ordning",
|
"order": "Ordning",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Denna tråd togs bort av forumets moderatorer",
|
"this_thread_was_removed": "Denna tråd togs bort av forumets moderatorer",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "అనుమతించబడాలి",
|
"pending": "అనుమతించబడాలి",
|
||||||
"failed": "విజయవంతం కాలేదు",
|
"failed": "విజయవంతం కాలేదు",
|
||||||
"add": "చేర్చండి",
|
"add": "చేర్చండి",
|
||||||
"pattern": "ప్యాటర్న్",
|
"pattern": "పాటర్న్",
|
||||||
"enable": "చేర్చు",
|
"enable": "చేర్చు",
|
||||||
"order": "ఆర్డర్",
|
"order": "ఆర్డర్",
|
||||||
"text": "పాఠం",
|
"text": "పాఠం",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "ఈ థ్రెడ్ బోర్డ్ మోడరేటర్ల ద్వారా తీసివేయబడింది",
|
"this_thread_was_removed": "ఈ థ్రెడ్ బోర్డ్ మోడరేటర్ల ద్వారా తీసివేయబడింది",
|
||||||
"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": "ఫిల్టర్లు మరియు హైలైట్లు"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "กระทู้นี้ถูกลบโดยผู้ดูแลบอร์ด",
|
"this_thread_was_removed": "กระทู้นี้ถูกลบโดยผู้ดูแลบอร์ด",
|
||||||
"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": "ตัวกรองและไฮไลท์"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Beklemede",
|
"pending": "Beklemede",
|
||||||
"failed": "Başarısız",
|
"failed": "Başarısız",
|
||||||
"add": "Ekle",
|
"add": "Ekle",
|
||||||
"pattern": "Desen",
|
"pattern": "desen",
|
||||||
"enable": "Etkinleştir",
|
"enable": "Etkinleştir",
|
||||||
"order": "Sıra",
|
"order": "Sıra",
|
||||||
"text": "Metin",
|
"text": "Metin",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Bu konu, board moderatörleri tarafından kaldırıldı",
|
"this_thread_was_removed": "Bu konu, board moderatörleri tarafından kaldırıldı",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Очікує",
|
"pending": "Очікує",
|
||||||
"failed": "Не вдалося",
|
"failed": "Не вдалося",
|
||||||
"add": "Додати",
|
"add": "Додати",
|
||||||
"pattern": "Шаблон",
|
"pattern": "шаблон",
|
||||||
"enable": "Увімкнути",
|
"enable": "Увімкнути",
|
||||||
"order": "Порядок",
|
"order": "Порядок",
|
||||||
"text": "Текст",
|
"text": "Текст",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Цю тему було видалено модераторами форуму",
|
"this_thread_was_removed": "Цю тему було видалено модераторами форуму",
|
||||||
"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": "Фільтри та виділення"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "منتظر",
|
"pending": "منتظر",
|
||||||
"failed": "ناکام",
|
"failed": "ناکام",
|
||||||
"add": "شامل کریں",
|
"add": "شامل کریں",
|
||||||
"pattern": "نمونہ",
|
"pattern": "پیٹرن",
|
||||||
"enable": "فعال کریں",
|
"enable": "فعال کریں",
|
||||||
"order": "ترتیب",
|
"order": "ترتیب",
|
||||||
"text": "متن",
|
"text": "متن",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "اس تھریڈ کو بورڈ کے موڈریٹرز نے ہٹا دیا ہے",
|
"this_thread_was_removed": "اس تھریڈ کو بورڈ کے موڈریٹرز نے ہٹا دیا ہے",
|
||||||
"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": "فلٹرز اور ہائیلائٹس"
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"pending": "Đang chờ",
|
"pending": "Đang chờ",
|
||||||
"failed": "Thất bại",
|
"failed": "Thất bại",
|
||||||
"add": "Thêm",
|
"add": "Thêm",
|
||||||
"pattern": "Mẫu",
|
"pattern": "mẫu",
|
||||||
"enable": "Kích hoạt",
|
"enable": "Kích hoạt",
|
||||||
"order": "Thứ tự",
|
"order": "Thứ tự",
|
||||||
"text": "Văn bản",
|
"text": "Văn bản",
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "Chủ đề này đã bị các quản trị viên diễn đàn xóa",
|
"this_thread_was_removed": "Chủ đề này đã bị các quản trị viên diễn đà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_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"
|
||||||
}
|
}
|
||||||
@@ -291,5 +291,6 @@
|
|||||||
"this_thread_was_removed": "此帖子已被论坛版主删除",
|
"this_thread_was_removed": "此帖子已被论坛版主删除",
|
||||||
"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": "筛选器和高亮"
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,6 @@ import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import useIsMobile from '../../hooks/use-is-mobile';
|
import useIsMobile from '../../hooks/use-is-mobile';
|
||||||
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
|
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
interface BoardButtonsProps {
|
interface BoardButtonsProps {
|
||||||
address?: string | undefined;
|
address?: string | undefined;
|
||||||
@@ -244,13 +243,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, resetFilteredCount } = useCatalogFiltersStore();
|
const { filteredCount } = useCatalogFiltersStore();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (subplebbitAddress) {
|
|
||||||
resetFilteredCount();
|
|
||||||
}
|
|
||||||
}, [subplebbitAddress, resetFilteredCount]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}>
|
<div className={`${styles.mobileBoardButtons} ${!isInCatalogView ? styles.addMargin : ''}`}>
|
||||||
@@ -334,13 +327,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, resetFilteredCount } = useCatalogFiltersStore();
|
const { filteredCount } = useCatalogFiltersStore();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (subplebbitAddress) {
|
|
||||||
resetFilteredCount();
|
|
||||||
}
|
|
||||||
}, [subplebbitAddress, resetFilteredCount]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { persist } from 'zustand/middleware';
|
import { persist } from 'zustand/middleware';
|
||||||
import { Comment } from '@plebbit/plebbit-react-hooks';
|
import { Comment } from '@plebbit/plebbit-react-hooks';
|
||||||
import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils';
|
|
||||||
|
|
||||||
interface FilterItem {
|
interface FilterItem {
|
||||||
text: string;
|
text: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
count: number;
|
||||||
|
filteredCids: Set<string>;
|
||||||
|
hide: boolean;
|
||||||
|
top: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CatalogFiltersStore {
|
interface CatalogFiltersStore {
|
||||||
@@ -20,7 +23,9 @@ interface CatalogFiltersStore {
|
|||||||
updateFilter: () => void;
|
updateFilter: () => void;
|
||||||
initializeFilter: () => void;
|
initializeFilter: () => void;
|
||||||
filteredCount: number;
|
filteredCount: number;
|
||||||
resetFilteredCount: () => void;
|
filteredCids: Set<string>;
|
||||||
|
incrementFilterCount: (filterIndex: number, cid: string) => void;
|
||||||
|
recalcFilteredCount: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useCatalogFiltersStore = create(
|
const useCatalogFiltersStore = create(
|
||||||
@@ -28,76 +33,109 @@ const useCatalogFiltersStore = create(
|
|||||||
(set, get) => ({
|
(set, get) => ({
|
||||||
showTextOnlyThreads: false,
|
showTextOnlyThreads: false,
|
||||||
setShowTextOnlyThreads: (value: boolean) => {
|
setShowTextOnlyThreads: (value: boolean) => {
|
||||||
set({ showTextOnlyThreads: value, filteredCount: 0 });
|
set({ showTextOnlyThreads: value });
|
||||||
get().updateFilter();
|
get().updateFilter();
|
||||||
},
|
},
|
||||||
filterText: '',
|
filterText: '',
|
||||||
setFilterText: (value: string) => set({ filterText: value }),
|
setFilterText: (value: string) => set({ filterText: value }),
|
||||||
filterItems: [],
|
filterItems: [],
|
||||||
|
filteredCount: 0,
|
||||||
|
filteredCids: new Set<string>(),
|
||||||
setFilterItems: (items: FilterItem[]) => {
|
setFilterItems: (items: FilterItem[]) => {
|
||||||
const nonEmptyItems = items.filter((item) => item.text.trim() !== '');
|
const nonEmptyItems = items
|
||||||
|
.filter((item) => item.text.trim() !== '')
|
||||||
|
.map((item) => ({
|
||||||
|
...item,
|
||||||
|
count: item.count || 0,
|
||||||
|
filteredCids: item.filteredCids || new Set(),
|
||||||
|
hide: item.hide ?? true,
|
||||||
|
top: item.top ?? false,
|
||||||
|
}));
|
||||||
set({ filterItems: nonEmptyItems });
|
set({ filterItems: nonEmptyItems });
|
||||||
|
get().recalcFilteredCount();
|
||||||
},
|
},
|
||||||
saveAndApplyFilters: (items: FilterItem[]) => {
|
saveAndApplyFilters: (items: FilterItem[]) => {
|
||||||
const nonEmptyItems = items.filter((item) => item.text.trim() !== '');
|
const nonEmptyItems = items
|
||||||
set({ filterItems: nonEmptyItems, filteredCount: 0 });
|
.filter((item) => item.text.trim() !== '')
|
||||||
|
.map((item) => ({
|
||||||
|
...item,
|
||||||
|
count: item.count || 0,
|
||||||
|
filteredCids: item.filteredCids || new Set(),
|
||||||
|
hide: item.hide ?? true,
|
||||||
|
top: item.top ?? false,
|
||||||
|
}));
|
||||||
|
set({
|
||||||
|
filterItems: nonEmptyItems,
|
||||||
|
filteredCids: new Set<string>(),
|
||||||
|
});
|
||||||
|
get().recalcFilteredCount();
|
||||||
get().updateFilter();
|
get().updateFilter();
|
||||||
},
|
},
|
||||||
filter: undefined,
|
filter: undefined,
|
||||||
updateFilter: () => {
|
updateFilter: () => {
|
||||||
// const filteredCids = new Set<string>();
|
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
filter: (comment: Comment) => {
|
filter: (comment: Comment) => {
|
||||||
const {
|
if (!comment?.cid) return true;
|
||||||
showTextOnlyThreads,
|
const { filterItems } = state;
|
||||||
// filterItems
|
let shouldHide = false;
|
||||||
} = state;
|
for (let i = 0; i < filterItems.length; i++) {
|
||||||
|
const item = filterItems[i];
|
||||||
const { link, linkHeight, linkWidth, thumbnailUrl } = comment || {};
|
if (item.enabled && item.text.trim() !== '') {
|
||||||
|
const pattern = item.text.toLowerCase();
|
||||||
const hasThumbnail = getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link);
|
const title = comment?.title?.toLowerCase() || '';
|
||||||
// const title = comment?.title?.toLowerCase() || '';
|
const content = comment?.content?.toLowerCase() || '';
|
||||||
// const content = comment?.content?.toLowerCase() || '';
|
if (title.includes(pattern) || content.includes(pattern)) {
|
||||||
|
if (item.hide) {
|
||||||
// const matchesFilterItems = filterItems
|
shouldHide = true;
|
||||||
// .filter((item) => item.enabled)
|
}
|
||||||
// .some((item) => {
|
}
|
||||||
// const text = item.text.toLowerCase();
|
}
|
||||||
// return title.includes(text) || content.includes(text);
|
|
||||||
// });
|
|
||||||
|
|
||||||
const shouldShow = showTextOnlyThreads || hasThumbnail;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!shouldShow
|
|
||||||
// || matchesFilterItems
|
|
||||||
) {
|
|
||||||
// if (
|
|
||||||
// matchesFilterItems &&
|
|
||||||
// !filteredCids.has(comment.cid)) {
|
|
||||||
// filteredCids.add(comment.cid);
|
|
||||||
// set((state) => ({ filteredCount: state.filteredCount + 1 }));
|
|
||||||
// }
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return !shouldHide;
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
initializeFilter: () => {
|
initializeFilter: () => {
|
||||||
const { updateFilter } = get();
|
get().updateFilter();
|
||||||
updateFilter();
|
},
|
||||||
|
incrementFilterCount: (filterIndex: number, cid: string) => {
|
||||||
|
set((state) => {
|
||||||
|
const newFilterItems = [...state.filterItems];
|
||||||
|
if (newFilterItems[filterIndex]) {
|
||||||
|
const item = newFilterItems[filterIndex];
|
||||||
|
if (!item.filteredCids.has(cid)) {
|
||||||
|
const newItemFilteredCids = new Set(item.filteredCids);
|
||||||
|
newItemFilteredCids.add(cid);
|
||||||
|
newFilterItems[filterIndex] = {
|
||||||
|
...item,
|
||||||
|
count: item.count + 1,
|
||||||
|
filteredCids: newItemFilteredCids,
|
||||||
|
};
|
||||||
|
const newFilteredCount = newFilterItems.reduce((sum, filt) => (filt.hide ? sum + filt.count : sum), 0);
|
||||||
|
return { filterItems: newFilterItems, filteredCount: newFilteredCount };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
recalcFilteredCount: () => {
|
||||||
|
set((state) => ({
|
||||||
|
filteredCount: state.filterItems.reduce((sum, item) => (item.hide ? sum + item.count : sum), 0),
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
filteredCount: 0,
|
|
||||||
resetFilteredCount: () => set({ filteredCount: 0 }),
|
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: 'catalog-filters-storage',
|
name: 'catalog-filters-storage',
|
||||||
onRehydrateStorage: () => (state) => {
|
partialize: (state) => {
|
||||||
if (state) {
|
return {
|
||||||
state.updateFilter();
|
showTextOnlyThreads: state.showTextOnlyThreads,
|
||||||
}
|
filterItems: state.filterItems.map((item) => ({
|
||||||
|
text: item.text,
|
||||||
|
enabled: item.enabled,
|
||||||
|
hide: item.hide,
|
||||||
|
top: item.top,
|
||||||
|
})),
|
||||||
|
} as any;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
top: 60px;
|
top: 60px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 340px;
|
width: 380px;
|
||||||
height: auto;
|
height: auto;
|
||||||
max-height: 80%;
|
max-height: 80%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -51,6 +51,12 @@
|
|||||||
border-left: var(--settings-modal-border-left);
|
border-left: var(--settings-modal-border-left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 420px) {
|
||||||
|
.modal {
|
||||||
|
width: 90vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -142,7 +148,7 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
border: var(--reply-modal-field-input-border, revert);
|
border: var(--reply-modal-field-input-border, revert);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
width: 200px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filtersTable input[type='text']:focus {
|
.filtersTable input[type='text']:focus {
|
||||||
@@ -164,3 +170,22 @@
|
|||||||
.saveButton {
|
.saveButton {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filterHits {
|
||||||
|
font-size: 12px !important;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickbox {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-size: 10px;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #000;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useCallback, useRef } from 'react';
|
import { useState, useCallback, useRef, useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import useCatalogFiltersStore from '../../../stores/use-catalog-filters-store';
|
import useCatalogFiltersStore from '../../../stores/use-catalog-filters-store';
|
||||||
import styles from './catalog-filters.module.css';
|
import styles from './catalog-filters.module.css';
|
||||||
@@ -7,16 +7,44 @@ const FiltersTable = ({ onSave }: { onSave: () => void }) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { filterItems, saveAndApplyFilters } = useCatalogFiltersStore();
|
const { filterItems, saveAndApplyFilters } = useCatalogFiltersStore();
|
||||||
|
|
||||||
const [localFilterItems, setLocalFilterItems] = useState(filterItems);
|
const [localFilterItems, setLocalFilterItems] = useState(
|
||||||
|
filterItems.map((item) => ({
|
||||||
|
...item,
|
||||||
|
hide: item.hide ?? true,
|
||||||
|
top: item.top ?? false,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
|
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
|
||||||
|
|
||||||
|
// Update local items when store changes
|
||||||
|
useEffect(() => {
|
||||||
|
setLocalFilterItems(
|
||||||
|
filterItems.map((item) => ({
|
||||||
|
...item,
|
||||||
|
hide: item.hide ?? true,
|
||||||
|
top: item.top ?? false,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
}, [filterItems]);
|
||||||
|
|
||||||
const handleAddFilter = useCallback(() => {
|
const handleAddFilter = useCallback(() => {
|
||||||
setLocalFilterItems((prev) => {
|
setLocalFilterItems((prev) => {
|
||||||
const newIndex = prev.length;
|
const newIndex = prev.length;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inputRefs.current[newIndex]?.focus();
|
inputRefs.current[newIndex]?.focus();
|
||||||
}, 0);
|
}, 0);
|
||||||
return [...prev, { text: '', enabled: true }];
|
return [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
enabled: true,
|
||||||
|
count: 0,
|
||||||
|
filteredCids: new Set<string>(),
|
||||||
|
hide: true,
|
||||||
|
top: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -47,10 +75,13 @@ const FiltersTable = ({ onSave }: { onSave: () => void }) => {
|
|||||||
<table className={styles.filtersTable}>
|
<table className={styles.filtersTable}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('order')}</th>
|
<th>order</th>
|
||||||
<th>{t('enable')}</th>
|
<th>on</th>
|
||||||
<th>{t('text')}</th>
|
<th>pattern</th>
|
||||||
<th>{t('delete')}</th>
|
<th>color</th>
|
||||||
|
<th>hide</th>
|
||||||
|
<th>top</th>
|
||||||
|
<th>del</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -80,17 +111,27 @@ const FiltersTable = ({ onSave }: { onSave: () => void }) => {
|
|||||||
ref={(el) => (inputRefs.current[index] = el)}
|
ref={(el) => (inputRefs.current[index] = el)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<span className={styles.clickbox} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type='checkbox' checked={item.hide} onChange={(e) => updateLocalFilterItem(index, { ...item, hide: e.target.checked })} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type='checkbox' checked={item.top} onChange={(e) => updateLocalFilterItem(index, { ...item, top: e.target.checked })} />
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span className={styles.deleteButton} onClick={() => removeLocalFilterItem(index)}>
|
<span className={styles.deleteButton} onClick={() => removeLocalFilterItem(index)}>
|
||||||
×
|
×
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
<td className={styles.filterHits}>{item.count > 0 && `x${item.count}`}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={4}>
|
<td colSpan={7}>
|
||||||
<button className={styles.addButton} onClick={handleAddFilter}>
|
<button className={styles.addButton} onClick={handleAddFilter}>
|
||||||
{t('add')}
|
{t('add')}
|
||||||
</button>
|
</button>
|
||||||
@@ -112,7 +153,7 @@ const FiltersModal = ({ closeModal }: { closeModal: () => void }) => {
|
|||||||
<div className={styles.overlay} onClick={closeModal} />
|
<div className={styles.overlay} onClick={closeModal} />
|
||||||
<div className={styles.modal}>
|
<div className={styles.modal}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<span className={styles.title}>{t('filters')}</span>
|
<span className={styles.title}>{t('filters_and_highlights')}</span>
|
||||||
<span className={styles.closeButton} title='close' onClick={closeModal} />
|
<span className={styles.closeButton} title='close' onClick={closeModal} />
|
||||||
</div>
|
</div>
|
||||||
<FiltersTable onSave={closeModal} />
|
<FiltersTable onSave={closeModal} />
|
||||||
@@ -125,13 +166,23 @@ const CatalogFilters = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = useCallback(() => {
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onEscapeKey = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener('keydown', onEscapeKey);
|
||||||
|
return () => document.removeEventListener('keydown', onEscapeKey);
|
||||||
|
}, [closeModal]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<span className={`${styles.filtersButton} button`} onClick={() => setShowModal(false)} style={{ cursor: 'not-allowed' }}>
|
<span className={`${styles.filtersButton} button`} onClick={() => setShowModal(true)}>
|
||||||
{t('filters')}
|
{t('filters')}
|
||||||
</span>
|
</span>
|
||||||
{showModal && <FiltersModal closeModal={closeModal} />}
|
{showModal && <FiltersModal closeModal={closeModal} />}
|
||||||
|
|||||||
+138
-20
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
||||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { Comment, useAccount, useFeed, useSubplebbit, useBlock, useAccountComments } from '@plebbit/plebbit-react-hooks';
|
import { Comment, useAccount, useFeed, useSubplebbit, useBlock, useAccountComments } from '@plebbit/plebbit-react-hooks';
|
||||||
@@ -14,22 +14,97 @@ import useCatalogStyleStore from '../../stores/use-catalog-style-store';
|
|||||||
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
||||||
import useInterfaceSettingsStore from '../../stores/use-interface-settings-store';
|
import useInterfaceSettingsStore from '../../stores/use-interface-settings-store';
|
||||||
import useSortingStore from '../../stores/use-sorting-store';
|
import useSortingStore from '../../stores/use-sorting-store';
|
||||||
|
import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
|
||||||
import CatalogRow from '../../components/catalog-row';
|
import CatalogRow from '../../components/catalog-row';
|
||||||
import LoadingEllipsis from '../../components/loading-ellipsis';
|
import LoadingEllipsis from '../../components/loading-ellipsis';
|
||||||
import styles from './catalog.module.css';
|
import styles from './catalog.module.css';
|
||||||
|
|
||||||
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
|
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
|
||||||
|
|
||||||
const createThreadsWithoutImagesFilter = () => ({
|
const createContentFilter = (
|
||||||
filter: (comment: Comment) => {
|
filterItems: { text: string; enabled: boolean; count: number; filteredCids: Set<string>; hide: boolean; top: boolean }[],
|
||||||
const { link, linkHeight, linkWidth, thumbnailUrl } = comment || {};
|
onFilterMatch?: (filterIndex: number, cid: string) => void,
|
||||||
if (!getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link)) {
|
) => {
|
||||||
return false;
|
// Create a unique key based on the enabled filter items
|
||||||
}
|
const enabledFilters = filterItems.filter((item) => item.enabled && item.text.trim() !== '');
|
||||||
return true;
|
const filterKey =
|
||||||
},
|
enabledFilters.length > 0
|
||||||
key: 'threads-with-images-only',
|
? `content-filter-${enabledFilters.map((item) => `${item.text}-${item.hide ? 'hide' : ''}-${item.top ? 'top' : ''}`).join('-')}`
|
||||||
});
|
: 'no-content-filter';
|
||||||
|
|
||||||
|
return {
|
||||||
|
filter: (comment: Comment) => {
|
||||||
|
if (!comment?.cid) return true;
|
||||||
|
|
||||||
|
if (enabledFilters.length === 0) return true;
|
||||||
|
|
||||||
|
const titleLower = comment?.title?.toLowerCase() || '';
|
||||||
|
const contentLower = comment?.content?.toLowerCase() || '';
|
||||||
|
|
||||||
|
// Check if any enabled filter matches the content
|
||||||
|
for (let i = 0; i < enabledFilters.length; i++) {
|
||||||
|
const item = enabledFilters[i];
|
||||||
|
const pattern = item.text.toLowerCase();
|
||||||
|
|
||||||
|
if (titleLower.includes(pattern) || contentLower.includes(pattern)) {
|
||||||
|
// Find the original filter index to increment count
|
||||||
|
const filterIndex = filterItems.findIndex((f) => f.text === item.text && f.enabled);
|
||||||
|
if (filterIndex !== -1) {
|
||||||
|
if (onFilterMatch) {
|
||||||
|
onFilterMatch(filterIndex, comment.cid);
|
||||||
|
} else {
|
||||||
|
// Fallback to the store method if no callback provided
|
||||||
|
useCatalogFiltersStore.getState().incrementFilterCount(filterIndex, comment.cid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this filter is set to hide, filter out the comment
|
||||||
|
if (item.hide) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this filter is set to top, we'll handle it separately in the component
|
||||||
|
// (we don't filter it out here)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
key: filterKey,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createImageFilter = (showTextOnlyThreads: boolean) => {
|
||||||
|
return {
|
||||||
|
filter: (comment: Comment) => {
|
||||||
|
if (showTextOnlyThreads) return true;
|
||||||
|
|
||||||
|
const { link, linkHeight, linkWidth, thumbnailUrl } = comment || {};
|
||||||
|
const hasThumbnail = getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link);
|
||||||
|
|
||||||
|
return hasThumbnail;
|
||||||
|
},
|
||||||
|
key: showTextOnlyThreads ? 'no-image-filter' : 'threads-with-images-only',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createCombinedFilter = (
|
||||||
|
showTextOnlyThreads: boolean,
|
||||||
|
filterItems: { text: string; enabled: boolean; count: number; filteredCids: Set<string>; hide: boolean; top: boolean }[],
|
||||||
|
onFilterMatch?: (filterIndex: number, cid: string) => void,
|
||||||
|
) => {
|
||||||
|
const imageFilter = createImageFilter(showTextOnlyThreads);
|
||||||
|
const contentFilter = createContentFilter(filterItems, onFilterMatch);
|
||||||
|
|
||||||
|
return {
|
||||||
|
filter: (comment: Comment) => {
|
||||||
|
if (!imageFilter.filter(comment)) return false;
|
||||||
|
|
||||||
|
return contentFilter.filter(comment);
|
||||||
|
},
|
||||||
|
key: `${imageFilter.key}-${contentFilter.key}`,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const Catalog = () => {
|
const Catalog = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -39,7 +114,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 { hideThreadsWithoutImages } = useInterfaceSettingsStore();
|
const { showTextOnlyThreads, filterItems } = useCatalogFiltersStore();
|
||||||
|
|
||||||
const account = useAccount();
|
const account = useAccount();
|
||||||
const subscriptions = account?.subscriptions;
|
const subscriptions = account?.subscriptions;
|
||||||
@@ -77,12 +152,17 @@ const Catalog = () => {
|
|||||||
const { timeFilterSeconds, timeFilterName } = useTimeFilter();
|
const { timeFilterSeconds, timeFilterName } = useTimeFilter();
|
||||||
const { sortType } = useSortingStore();
|
const { sortType } = useSortingStore();
|
||||||
|
|
||||||
|
// stable callback for filter matching
|
||||||
|
const handleFilterMatch = useCallback((filterIndex: number, cid: string) => {
|
||||||
|
useCatalogFiltersStore.getState().incrementFilterCount(filterIndex, cid);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const feedOptions = useMemo(() => {
|
const feedOptions = useMemo(() => {
|
||||||
const options: any = {
|
const options: any = {
|
||||||
subplebbitAddresses,
|
subplebbitAddresses,
|
||||||
sortType,
|
sortType,
|
||||||
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
|
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
|
||||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
filter: createCombinedFilter(showTextOnlyThreads, filterItems, handleFilterMatch),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isInAllView || isInSubscriptionsView) {
|
if (isInAllView || isInSubscriptionsView) {
|
||||||
@@ -90,7 +170,7 @@ const Catalog = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}, [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, timeFilterSeconds, hideThreadsWithoutImages]);
|
}, [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, timeFilterSeconds, showTextOnlyThreads, filterItems, handleFilterMatch]);
|
||||||
|
|
||||||
const { feed, hasMore, loadMore, reset, subplebbitAddressesWithNewerPosts } = useFeed(feedOptions);
|
const { feed, hasMore, loadMore, reset, subplebbitAddressesWithNewerPosts } = useFeed(feedOptions);
|
||||||
const { accountComments } = useAccountComments();
|
const { accountComments } = useAccountComments();
|
||||||
@@ -108,13 +188,13 @@ const Catalog = () => {
|
|||||||
timestamp > Date.now() / 1000 - 60 * 60 &&
|
timestamp > Date.now() / 1000 - 60 * 60 &&
|
||||||
state === 'succeeded' &&
|
state === 'succeeded' &&
|
||||||
cid &&
|
cid &&
|
||||||
(hideThreadsWithoutImages ? 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)
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
[accountComments, subplebbitAddress, feed, hideThreadsWithoutImages],
|
[accountComments, subplebbitAddress, feed, showTextOnlyThreads],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 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
|
||||||
@@ -146,13 +226,14 @@ const Catalog = () => {
|
|||||||
subplebbitAddresses,
|
subplebbitAddresses,
|
||||||
sortType,
|
sortType,
|
||||||
newerThan: 60 * 60 * 24 * 7,
|
newerThan: 60 * 60 * 24 * 7,
|
||||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
filter: createCombinedFilter(showTextOnlyThreads, filterItems, handleFilterMatch),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { feed: monthlyFeed } = useFeed({
|
const { feed: monthlyFeed } = useFeed({
|
||||||
subplebbitAddresses,
|
subplebbitAddresses,
|
||||||
sortType,
|
sortType,
|
||||||
newerThan: 60 * 60 * 24 * 30,
|
newerThan: 60 * 60 * 24 * 30,
|
||||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
filter: createCombinedFilter(showTextOnlyThreads, filterItems, handleFilterMatch),
|
||||||
});
|
});
|
||||||
|
|
||||||
const [showMorePostsSuggestion, setShowMorePostsSuggestion] = useState(false);
|
const [showMorePostsSuggestion, setShowMorePostsSuggestion] = useState(false);
|
||||||
@@ -265,7 +346,44 @@ const Catalog = () => {
|
|||||||
|
|
||||||
const isFeedLoaded = feed.length > 0 || state === 'failed';
|
const isFeedLoaded = feed.length > 0 || state === 'failed';
|
||||||
|
|
||||||
const rows = useCatalogFeedRows(columnCount, combinedFeed, isFeedLoaded, subplebbit);
|
// Process the feed to move "top" posts to the top
|
||||||
|
const processedFeed = useMemo(() => {
|
||||||
|
if (!combinedFeed || combinedFeed.length === 0) return combinedFeed;
|
||||||
|
|
||||||
|
const enabledTopFilters = filterItems.filter((item) => item.enabled && item.text.trim() !== '' && item.top);
|
||||||
|
if (enabledTopFilters.length === 0) return combinedFeed;
|
||||||
|
|
||||||
|
// Separate posts that match "top" filters
|
||||||
|
const topPosts: Comment[] = [];
|
||||||
|
const regularPosts: Comment[] = [];
|
||||||
|
|
||||||
|
combinedFeed.forEach((comment) => {
|
||||||
|
if (!comment) return;
|
||||||
|
|
||||||
|
const titleLower = comment?.title?.toLowerCase() || '';
|
||||||
|
const contentLower = comment?.content?.toLowerCase() || '';
|
||||||
|
|
||||||
|
let isTop = false;
|
||||||
|
for (const filter of enabledTopFilters) {
|
||||||
|
const pattern = filter.text.toLowerCase();
|
||||||
|
if (titleLower.includes(pattern) || contentLower.includes(pattern)) {
|
||||||
|
isTop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTop) {
|
||||||
|
topPosts.push(comment);
|
||||||
|
} else {
|
||||||
|
regularPosts.push(comment);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return top posts followed by regular posts
|
||||||
|
return [...topPosts, ...regularPosts];
|
||||||
|
}, [combinedFeed, filterItems]);
|
||||||
|
|
||||||
|
const rows = useCatalogFeedRows(columnCount, processedFeed, isFeedLoaded, subplebbit);
|
||||||
|
|
||||||
// save the last Virtuoso state to restore it when navigating back
|
// save the last Virtuoso state to restore it when navigating back
|
||||||
const virtuosoRef = useRef<VirtuosoHandle | null>(null);
|
const virtuosoRef = useRef<VirtuosoHandle | null>(null);
|
||||||
@@ -293,7 +411,7 @@ const Catalog = () => {
|
|||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<hr />
|
<hr />
|
||||||
<div className={styles.catalog}>
|
<div className={styles.catalog}>
|
||||||
{combinedFeed.length !== 0 ? (
|
{processedFeed.length !== 0 ? (
|
||||||
<>
|
<>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
increaseViewportBy={{ bottom: 1200, top: 1200 }}
|
increaseViewportBy={{ bottom: 1200, top: 1200 }}
|
||||||
|
|||||||
@@ -3085,22 +3085,6 @@
|
|||||||
uuid "8.3.2"
|
uuid "8.3.2"
|
||||||
zustand "4.0.0"
|
zustand "4.0.0"
|
||||||
|
|
||||||
"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#6d35eb3b4dc84f8fdcbb46d95e3b1d78f1750b5f":
|
|
||||||
version "0.0.1"
|
|
||||||
resolved "https://github.com/plebbit/plebbit-react-hooks.git#6d35eb3b4dc84f8fdcbb46d95e3b1d78f1750b5f"
|
|
||||||
dependencies:
|
|
||||||
"@plebbit/plebbit-js" "https://github.com/plebbit/plebbit-js.git#5ff48e9b9a906a098a51b474a52692eebfb6561d"
|
|
||||||
"@plebbit/plebbit-logger" "https://github.com/plebbit/plebbit-logger.git"
|
|
||||||
assert "2.0.0"
|
|
||||||
ethers "5.6.9"
|
|
||||||
localforage "1.10.0"
|
|
||||||
lodash.isequal "4.5.0"
|
|
||||||
memoizee "0.4.15"
|
|
||||||
quick-lru "5.1.1"
|
|
||||||
uint8arrays "3.1.1"
|
|
||||||
uuid "8.3.2"
|
|
||||||
zustand "4.0.0"
|
|
||||||
|
|
||||||
"@plebbit/proper-lockfile@github:plebbit/node-proper-lockfile#7fd6332117340c1d3d98dd0afee2d31cc06f72b8":
|
"@plebbit/proper-lockfile@github:plebbit/node-proper-lockfile#7fd6332117340c1d3d98dd0afee2d31cc06f72b8":
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://codeload.github.com/plebbit/node-proper-lockfile/tar.gz/7fd6332117340c1d3d98dd0afee2d31cc06f72b8"
|
resolved "https://codeload.github.com/plebbit/node-proper-lockfile/tar.gz/7fd6332117340c1d3d98dd0afee2d31cc06f72b8"
|
||||||
|
|||||||
Reference in New Issue
Block a user