diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index c967d32..7c5868a 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -80,7 +80,7 @@ const NoteList = forwardRef< const { startLogin } = useNostr() const { isSpammer, meetsMinTrustScore } = useUserTrust() const { mutePubkeySet } = useMuteList() - const { hideContentMentioningMutedUsers } = useContentPolicy() + const { hideContentMentioningMutedUsers, mutedWords } = useContentPolicy() const { isEventDeleted } = useDeletedEvent() const [storedEvents, setStoredEvents] = useState([]) const [events, setEvents] = useState([]) @@ -131,10 +131,18 @@ const NoteList = forwardRef< if (filterFn && !filterFn(evt)) { return true } + if (mutedWords.length > 0) { + const contentLower = evt.content.toLowerCase() + for (const word of mutedWords) { + if (contentLower.includes(word)) { + return true + } + } + } return false }, - [mutePubkeySet, JSON.stringify(pinnedEventIds), isEventDeleted, filterFn] + [mutePubkeySet, JSON.stringify(pinnedEventIds), isEventDeleted, filterFn, mutedWords] ) useEffect(() => { diff --git a/src/constants.ts b/src/constants.ts index bc92eea..b7f3a86 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -43,6 +43,7 @@ export const StorageKey = { NSFW_DISPLAY_POLICY: 'nsfwDisplayPolicy', MIN_TRUST_SCORE: 'minTrustScore', DEFAULT_RELAY_URLS: 'defaultRelayUrls', + MUTED_WORDS: 'mutedWords', ENABLE_LIVE_FEED: 'enableLiveFeed', // deprecated HIDE_UNTRUSTED_NOTES: 'hideUntrustedNotes', // deprecated HIDE_UNTRUSTED_INTERACTIONS: 'hideUntrustedInteractions', // deprecated diff --git a/src/i18n/locales/ar.ts b/src/i18n/locales/ar.ts index f85bda7..678634f 100644 --- a/src/i18n/locales/ar.ts +++ b/src/i18n/locales/ar.ts @@ -648,16 +648,20 @@ export default { 'trust-filter.quick-presets': 'إعدادات سريعة', 'trust-filter.show-all-content': 'إظهار جميع المحتويات', 'trust-filter.only-show-wot': 'إظهار شبكة الثقة الخاصة بك فقط (المتابَعون + متابَعوهم)', - 'trust-filter.hide-bottom-percent': - 'تصفية أدنى {{score}}٪ من المستخدمين حسب تصنيف الثقة', - 'trust-filter.trust-score-description': 'محسوبة بناءً على سمعة المستخدم والنسبة المئوية للشبكة الاجتماعية', + 'trust-filter.hide-bottom-percent': 'تصفية أدنى {{score}}٪ من المستخدمين حسب تصنيف الثقة', + 'trust-filter.trust-score-description': + 'محسوبة بناءً على سمعة المستخدم والنسبة المئوية للشبكة الاجتماعية', 'Auto-load profile pictures': 'تحميل صور الملف الشخصي تلقائيًا', 'Disable live feed': 'تعطيل التغذية المباشرة', 'Enable live feed': 'تفعيل التغذية المباشرة', 'Default relays': 'المرحلات الافتراضية', 'Reset to default': 'إعادة تعيين إلى الافتراضي', - 'Default relays description': 'تُستخدم للاستعلام عن تكوينات المرحلات للمستخدمين الآخرين وكبديل احتياطي عندما لا يكون لدى المستخدمين مرحلات مكوّنة.', - 'Default relays warning': 'تحذير: يرجى عدم تعديل هذه الإعدادات بشكل عشوائي، فقد يؤثر ذلك على تجربتك الأساسية.', - 'Invalid relay URL': 'عنوان URL للمرحل غير صالح' + 'Default relays description': + 'تُستخدم للاستعلام عن تكوينات المرحلات للمستخدمين الآخرين وكبديل احتياطي عندما لا يكون لدى المستخدمين مرحلات مكوّنة.', + 'Default relays warning': + 'تحذير: يرجى عدم تعديل هذه الإعدادات بشكل عشوائي، فقد يؤثر ذلك على تجربتك الأساسية.', + 'Invalid relay URL': 'عنوان URL للمرحل غير صالح', + 'Muted words': 'الكلمات المحظورة', + 'Add muted word': 'إضافة كلمة محظورة' } } diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 43efe8d..47a183f 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -678,8 +678,12 @@ export default { 'Enable live feed': 'Live-Feed aktivieren', 'Default relays': 'Standard-Relays', 'Reset to default': 'Auf Standard zurücksetzen', - 'Default relays description': 'Werden verwendet, um die Relay-Konfigurationen anderer Benutzer abzufragen und als Fallback, wenn Benutzer keine Relays konfiguriert haben.', - 'Default relays warning': 'Warnung: Ändern Sie diese Einstellungen nicht leichtfertig, da dies Ihre grundlegende Erfahrung beeinträchtigen kann.', - 'Invalid relay URL': 'Ungültige Relay-URL' + 'Default relays description': + 'Werden verwendet, um die Relay-Konfigurationen anderer Benutzer abzufragen und als Fallback, wenn Benutzer keine Relays konfiguriert haben.', + 'Default relays warning': + 'Warnung: Ändern Sie diese Einstellungen nicht leichtfertig, da dies Ihre grundlegende Erfahrung beeinträchtigen kann.', + 'Invalid relay URL': 'Ungültige Relay-URL', + 'Muted words': 'Stummgeschaltete Wörter', + 'Add muted word': 'Stummgeschaltetes Wort hinzufügen' } } diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index 1258fe9..7cf5a19 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -653,16 +653,20 @@ export default { 'trust-filter.quick-presets': 'Quick presets', 'trust-filter.show-all-content': 'Show all content', 'trust-filter.only-show-wot': 'Only show your Web of Trust (follows + their follows)', - 'trust-filter.hide-bottom-percent': - 'Filter out bottom {{score}}% of users by trust rank', - 'trust-filter.trust-score-description': 'Calculated based on user reputation and social network percentile', + 'trust-filter.hide-bottom-percent': 'Filter out bottom {{score}}% of users by trust rank', + 'trust-filter.trust-score-description': + 'Calculated based on user reputation and social network percentile', 'Auto-load profile pictures': 'Auto-load profile pictures', 'Disable live feed': 'Disable live feed', 'Enable live feed': 'Enable live feed', 'Default relays': 'Default relays', 'Reset to default': 'Reset to default', - 'Default relays description': 'Used to query other users\' relay configurations and as a fallback when users have no relays configured.', - 'Default relays warning': 'Warning: Please do not modify these settings casually, as it may affect your basic experience.', - 'Invalid relay URL': 'Invalid relay URL' + 'Default relays description': + "Used to query other users' relay configurations and as a fallback when users have no relays configured.", + 'Default relays warning': + 'Warning: Please do not modify these settings casually, as it may affect your basic experience.', + 'Invalid relay URL': 'Invalid relay URL', + 'Muted words': 'Muted words', + 'Add muted word': 'Add muted word' } } diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts index 2df6d40..a8cca24 100644 --- a/src/i18n/locales/es.ts +++ b/src/i18n/locales/es.ts @@ -672,8 +672,12 @@ export default { 'Enable live feed': 'Activar feed en vivo', 'Default relays': 'Relés predeterminados', 'Reset to default': 'Restablecer valores predeterminados', - 'Default relays description': 'Se utilizan para consultar las configuraciones de relés de otros usuarios y como respaldo cuando los usuarios no tienen relés configurados.', - 'Default relays warning': 'Advertencia: No modifiques estas configuraciones a la ligera, ya que puede afectar tu experiencia básica.', - 'Invalid relay URL': 'URL de relé no válida' + 'Default relays description': + 'Se utilizan para consultar las configuraciones de relés de otros usuarios y como respaldo cuando los usuarios no tienen relés configurados.', + 'Default relays warning': + 'Advertencia: No modifiques estas configuraciones a la ligera, ya que puede afectar tu experiencia básica.', + 'Invalid relay URL': 'URL de relé no válida', + 'Muted words': 'Palabras silenciadas', + 'Add muted word': 'Agregar palabra silenciada' } } diff --git a/src/i18n/locales/fa.ts b/src/i18n/locales/fa.ts index f0c09b5..82d72e9 100644 --- a/src/i18n/locales/fa.ts +++ b/src/i18n/locales/fa.ts @@ -661,15 +661,18 @@ export default { 'فقط شبکه اعتماد شما را نشان دهید (دنبال‌شوندگان + دنبال‌شوندگان آنها)', 'trust-filter.hide-bottom-percent': 'فیلتر کردن {{score}}٪ پایین‌ترین کاربران بر اساس رتبه اعتماد', - 'trust-filter.trust-score-description': - 'بر اساس شهرت کاربر و صدک شبکه اجتماعی محاسبه می‌شود', + 'trust-filter.trust-score-description': 'بر اساس شهرت کاربر و صدک شبکه اجتماعی محاسبه می‌شود', 'Auto-load profile pictures': 'بارگذاری خودکار تصاویر پروفایل', 'Disable live feed': 'غیرفعال کردن فید زنده', 'Enable live feed': 'فعال کردن فید زنده', 'Default relays': 'رله‌های پیش‌فرض', 'Reset to default': 'بازنشانی به پیش‌فرض', - 'Default relays description': 'برای پرس‌وجو از پیکربندی‌های رله کاربران دیگر و به عنوان جایگزین زمانی که کاربران رله پیکربندی نکرده‌اند استفاده می‌شود.', - 'Default relays warning': 'هشدار: لطفاً این تنظیمات را به صورت تصادفی تغییر ندهید، ممکن است بر تجربه اولیه شما تأثیر بگذارد.', - 'Invalid relay URL': 'آدرس URL رله نامعتبر است' + 'Default relays description': + 'برای پرس‌وجو از پیکربندی‌های رله کاربران دیگر و به عنوان جایگزین زمانی که کاربران رله پیکربندی نکرده‌اند استفاده می‌شود.', + 'Default relays warning': + 'هشدار: لطفاً این تنظیمات را به صورت تصادفی تغییر ندهید، ممکن است بر تجربه اولیه شما تأثیر بگذارد.', + 'Invalid relay URL': 'آدرس URL رله نامعتبر است', + 'Muted words': 'کلمات بی‌صدا شده', + 'Add muted word': 'افزودن کلمه بی‌صدا' } } diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts index 672c571..9f2a788 100644 --- a/src/i18n/locales/fr.ts +++ b/src/i18n/locales/fr.ts @@ -676,8 +676,12 @@ export default { 'Enable live feed': 'Activer le flux en direct', 'Default relays': 'Relais par défaut', 'Reset to default': 'Réinitialiser par défaut', - 'Default relays description': 'Utilisés pour interroger les configurations de relais d\'autres utilisateurs et comme solution de secours lorsque les utilisateurs n\'ont pas de relais configurés.', - 'Default relays warning': 'Attention : Ne modifiez pas ces paramètres à la légère, car cela pourrait affecter votre expérience de base.', - 'Invalid relay URL': 'URL de relais non valide' + 'Default relays description': + "Utilisés pour interroger les configurations de relais d'autres utilisateurs et comme solution de secours lorsque les utilisateurs n'ont pas de relais configurés.", + 'Default relays warning': + 'Attention : Ne modifiez pas ces paramètres à la légère, car cela pourrait affecter votre expérience de base.', + 'Invalid relay URL': 'URL de relais non valide', + 'Muted words': 'Mots masqués', + 'Add muted word': 'Ajouter un mot masqué' } } diff --git a/src/i18n/locales/hi.ts b/src/i18n/locales/hi.ts index 97bf19c..427e381 100644 --- a/src/i18n/locales/hi.ts +++ b/src/i18n/locales/hi.ts @@ -668,8 +668,12 @@ export default { 'Enable live feed': 'लाइव फ़ीड सक्षम करें', 'Default relays': 'डिफ़ॉल्ट रिले', 'Reset to default': 'डिफ़ॉल्ट पर रीसेट करें', - 'Default relays description': 'अन्य उपयोगकर्ताओं के रिले कॉन्फ़िगरेशन की जांच करने के लिए उपयोग किया जाता है और जब उपयोगकर्ताओं के पास रिले कॉन्फ़िगर नहीं है तो फ़ॉलबैक के रूप में।', - 'Default relays warning': 'चेतावनी: कृपया इन सेटिंग्स को बेतरतीब ढंग से संशोधित न करें, क्योंकि यह आपके बुनियादी अनुभव को प्रभावित कर सकता है।', - 'Invalid relay URL': 'अमान्य रिले URL' + 'Default relays description': + 'अन्य उपयोगकर्ताओं के रिले कॉन्फ़िगरेशन की जांच करने के लिए उपयोग किया जाता है और जब उपयोगकर्ताओं के पास रिले कॉन्फ़िगर नहीं है तो फ़ॉलबैक के रूप में।', + 'Default relays warning': + 'चेतावनी: कृपया इन सेटिंग्स को बेतरतीब ढंग से संशोधित न करें, क्योंकि यह आपके बुनियादी अनुभव को प्रभावित कर सकता है।', + 'Invalid relay URL': 'अमान्य रिले URL', + 'Muted words': 'म्यूट किए गए शब्द', + 'Add muted word': 'म्यूट शब्द जोड़ें' } } diff --git a/src/i18n/locales/hu.ts b/src/i18n/locales/hu.ts index 1dd10a1..e0dbf04 100644 --- a/src/i18n/locales/hu.ts +++ b/src/i18n/locales/hu.ts @@ -661,8 +661,12 @@ export default { 'Enable live feed': 'Élő hírfolyam engedélyezése', 'Default relays': 'Alapértelmezett továbbítók', 'Reset to default': 'Visszaállítás alapértelmezettre', - 'Default relays description': 'Más felhasználók továbbító konfigurációinak lekérdezésére használatos, és tartalékként szolgál, ha a felhasználóknak nincsenek továbbítóik beállítva.', - 'Default relays warning': 'Figyelmeztetés: Ne módosítsa ezeket a beállításokat meggondolatlanul, mert ez befolyásolhatja az alapvető élményt.', - 'Invalid relay URL': 'Érvénytelen továbbító URL' + 'Default relays description': + 'Más felhasználók továbbító konfigurációinak lekérdezésére használatos, és tartalékként szolgál, ha a felhasználóknak nincsenek továbbítóik beállítva.', + 'Default relays warning': + 'Figyelmeztetés: Ne módosítsa ezeket a beállításokat meggondolatlanul, mert ez befolyásolhatja az alapvető élményt.', + 'Invalid relay URL': 'Érvénytelen továbbító URL', + 'Muted words': 'Némított szavak', + 'Add muted word': 'Némított szó hozzáadása' } } diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts index 1a6d592..0d3a817 100644 --- a/src/i18n/locales/it.ts +++ b/src/i18n/locales/it.ts @@ -672,8 +672,12 @@ export default { 'Enable live feed': 'Attiva feed live', 'Default relays': 'Relay predefiniti', 'Reset to default': 'Ripristina predefiniti', - 'Default relays description': 'Utilizzati per interrogare le configurazioni dei relay di altri utenti e come fallback quando gli utenti non hanno relay configurati.', - 'Default relays warning': 'Attenzione: Non modificare queste impostazioni alla leggera, potrebbe influire sull\'esperienza di base.', - 'Invalid relay URL': 'URL relay non valido' + 'Default relays description': + 'Utilizzati per interrogare le configurazioni dei relay di altri utenti e come fallback quando gli utenti non hanno relay configurati.', + 'Default relays warning': + "Attenzione: Non modificare queste impostazioni alla leggera, potrebbe influire sull'esperienza di base.", + 'Invalid relay URL': 'URL relay non valido', + 'Muted words': 'Parole silenziate', + 'Add muted word': 'Aggiungi parola silenziata' } } diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts index 9ae0c9d..d94ed9e 100644 --- a/src/i18n/locales/ja.ts +++ b/src/i18n/locales/ja.ts @@ -666,8 +666,12 @@ export default { 'Enable live feed': 'ライブフィードを有効にする', 'Default relays': 'デフォルトリレー', 'Reset to default': 'デフォルトにリセット', - 'Default relays description': '他のユーザーのリレー設定を照会するために使用され、ユーザーがリレーを設定していない場合のフォールバックとして機能します。', - 'Default relays warning': '警告:これらの設定を無闇に変更しないでください。基本的な体験に影響を与える可能性があります。', - 'Invalid relay URL': '無効なリレーURL' + 'Default relays description': + '他のユーザーのリレー設定を照会するために使用され、ユーザーがリレーを設定していない場合のフォールバックとして機能します。', + 'Default relays warning': + '警告:これらの設定を無闇に変更しないでください。基本的な体験に影響を与える可能性があります。', + 'Invalid relay URL': '無効なリレーURL', + 'Muted words': 'ミュートワード', + 'Add muted word': 'ミュートワードを追加' } } diff --git a/src/i18n/locales/ko.ts b/src/i18n/locales/ko.ts index 4e3e2ef..8db0d2e 100644 --- a/src/i18n/locales/ko.ts +++ b/src/i18n/locales/ko.ts @@ -655,14 +655,19 @@ export default { 'trust-filter.show-all-content': '모든 콘텐츠 표시', 'trust-filter.only-show-wot': '신뢰 네트워크만 표시 (팔로우 + 팔로우의 팔로우)', 'trust-filter.hide-bottom-percent': '신뢰도 하위 {{score}}% 사용자 필터링', - 'trust-filter.trust-score-description': '사용자의 평판과 소셜 네트워크를 기반으로 신뢰도 백분위수 계산', + 'trust-filter.trust-score-description': + '사용자의 평판과 소셜 네트워크를 기반으로 신뢰도 백분위수 계산', 'Auto-load profile pictures': '프로필 사진 자동 로드', 'Disable live feed': '라이브 피드 비활성화', 'Enable live feed': '라이브 피드 활성화', 'Default relays': '기본 릴레이', 'Reset to default': '기본값으로 재설정', - 'Default relays description': '다른 사용자의 릴레이 구성을 조회하는 데 사용되며, 사용자가 릴레이를 구성하지 않은 경우 대체 수단으로 사용됩니다.', - 'Default relays warning': '경고: 이러한 설정을 임의로 수정하지 마십시오. 기본 경험에 영향을 줄 수 있습니다.', - 'Invalid relay URL': '유효하지 않은 릴레이 URL' + 'Default relays description': + '다른 사용자의 릴레이 구성을 조회하는 데 사용되며, 사용자가 릴레이를 구성하지 않은 경우 대체 수단으로 사용됩니다.', + 'Default relays warning': + '경고: 이러한 설정을 임의로 수정하지 마십시오. 기본 경험에 영향을 줄 수 있습니다.', + 'Invalid relay URL': '유효하지 않은 릴레이 URL', + 'Muted words': '차단 단어', + 'Add muted word': '차단 단어 추가' } } diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts index 90e8d61..18cb08b 100644 --- a/src/i18n/locales/pl.ts +++ b/src/i18n/locales/pl.ts @@ -673,8 +673,12 @@ export default { 'Enable live feed': 'Włącz kanał na żywo', 'Default relays': 'Domyślne przekaźniki', 'Reset to default': 'Przywróć domyślne', - 'Default relays description': 'Używane do odpytywania konfiguracji przekaźników innych użytkowników i jako rozwiązanie awaryjne, gdy użytkownicy nie mają skonfigurowanych przekaźników.', - 'Default relays warning': 'Ostrzeżenie: Nie modyfikuj tych ustawień pochopnie, może to wpłynąć na podstawowe doświadczenie.', - 'Invalid relay URL': 'Nieprawidłowy adres URL przekaźnika' + 'Default relays description': + 'Używane do odpytywania konfiguracji przekaźników innych użytkowników i jako rozwiązanie awaryjne, gdy użytkownicy nie mają skonfigurowanych przekaźników.', + 'Default relays warning': + 'Ostrzeżenie: Nie modyfikuj tych ustawień pochopnie, może to wpłynąć na podstawowe doświadczenie.', + 'Invalid relay URL': 'Nieprawidłowy adres URL przekaźnika', + 'Muted words': 'Wyciszone słowa', + 'Add muted word': 'Dodaj wyciszone słowo' } } diff --git a/src/i18n/locales/pt-BR.ts b/src/i18n/locales/pt-BR.ts index 4895fae..970a792 100644 --- a/src/i18n/locales/pt-BR.ts +++ b/src/i18n/locales/pt-BR.ts @@ -669,8 +669,12 @@ export default { 'Enable live feed': 'Ativar feed ao vivo', 'Default relays': 'Relays padrão', 'Reset to default': 'Redefinir para padrão', - 'Default relays description': 'Usados para consultar as configurações de relays de outros usuários e como alternativa quando os usuários não têm relays configurados.', - 'Default relays warning': 'Aviso: Não modifique essas configurações casualmente, pois pode afetar sua experiência básica.', - 'Invalid relay URL': 'URL de relay inválida' + 'Default relays description': + 'Usados para consultar as configurações de relays de outros usuários e como alternativa quando os usuários não têm relays configurados.', + 'Default relays warning': + 'Aviso: Não modifique essas configurações casualmente, pois pode afetar sua experiência básica.', + 'Invalid relay URL': 'URL de relé inválida', + 'Muted words': 'Palavras silenciadas', + 'Add muted word': 'Adicionar palavra silenciada' } } diff --git a/src/i18n/locales/pt-PT.ts b/src/i18n/locales/pt-PT.ts index 2af8304..f1366c6 100644 --- a/src/i18n/locales/pt-PT.ts +++ b/src/i18n/locales/pt-PT.ts @@ -672,8 +672,12 @@ export default { 'Enable live feed': 'Ativar feed ao vivo', 'Default relays': 'Relays predefinidos', 'Reset to default': 'Repor predefinições', - 'Default relays description': 'Utilizados para consultar as configurações de relays de outros utilizadores e como alternativa quando os utilizadores não têm relays configurados.', - 'Default relays warning': 'Aviso: Não modifique estas configurações casualmente, pois pode afetar a sua experiência básica.', - 'Invalid relay URL': 'URL de relay inválido' + 'Default relays description': + 'Utilizados para consultar as configurações de relays de outros utilizadores e como alternativa quando os utilizadores não têm relays configurados.', + 'Default relays warning': + 'Aviso: Não modifique estas configurações casualmente, pois pode afetar a sua experiência básica.', + 'Invalid relay URL': 'URL de relay inválido', + 'Muted words': 'Palavras silenciadas', + 'Add muted word': 'Adicionar palavra silenciada' } } diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts index 4e71081..86594e8 100644 --- a/src/i18n/locales/ru.ts +++ b/src/i18n/locales/ru.ts @@ -672,8 +672,12 @@ export default { 'Enable live feed': 'Включить прямую трансляцию', 'Default relays': 'Реле по умолчанию', 'Reset to default': 'Сбросить по умолчанию', - 'Default relays description': 'Используются для запроса конфигураций реле других пользователей и в качестве резервного варианта, когда у пользователей не настроены реле.', - 'Default relays warning': 'Предупреждение: Не изменяйте эти настройки без необходимости, это может повлиять на базовый опыт использования.', - 'Invalid relay URL': 'Неверный URL реле' + 'Default relays description': + 'Используются для запроса конфигураций реле других пользователей и в качестве резервного варианта, когда у пользователей не настроены реле.', + 'Default relays warning': + 'Предупреждение: Не изменяйте эти настройки без необходимости, это может повлиять на базовый опыт использования.', + 'Invalid relay URL': 'Неверный URL реле', + 'Muted words': 'Заблокированные слова', + 'Add muted word': 'Добавить заблокированное слово' } } diff --git a/src/i18n/locales/th.ts b/src/i18n/locales/th.ts index 8f52ae8..1caf5d7 100644 --- a/src/i18n/locales/th.ts +++ b/src/i18n/locales/th.ts @@ -649,8 +649,7 @@ export default { 'trust-filter.show-all-content': 'แสดงเนื้อหาทั้งหมด', 'trust-filter.only-show-wot': 'แสดงเฉพาะเครือข่ายความไว้วางใจของคุณ (ผู้ติดตาม + ผู้ติดตามของพวกเขา)', - 'trust-filter.hide-bottom-percent': - 'กรอง {{score}}% ล่างสุดของผู้ใช้ตามอันดับความไว้วางใจ', + 'trust-filter.hide-bottom-percent': 'กรอง {{score}}% ล่างสุดของผู้ใช้ตามอันดับความไว้วางใจ', 'trust-filter.trust-score-description': 'คำนวณจากชื่อเสียงของผู้ใช้และเปอร์เซ็นไทล์ของเครือข่ายสังคม', 'Auto-load profile pictures': 'โหลดรูปโปรไฟล์อัตโนมัติ', @@ -658,8 +657,12 @@ export default { 'Enable live feed': 'เปิดฟีดสด', 'Default relays': 'รีเลย์เริ่มต้น', 'Reset to default': 'รีเซ็ตเป็นค่าเริ่มต้น', - 'Default relays description': 'ใช้สำหรับสอบถามการกำหนดค่ารีเลย์ของผู้ใช้อื่นและเป็นทางเลือกสำรองเมื่อผู้ใช้ไม่ได้กำหนดค่ารีเลย์', - 'Default relays warning': 'คำเตือน: กรุณาอย่าแก้ไขการตั้งค่าเหล่านี้โดยไม่ระมัดระวัง เพราะอาจส่งผลต่อประสบการณ์พื้นฐานของคุณ', - 'Invalid relay URL': 'URL รีเลย์ไม่ถูกต้อง' + 'Default relays description': + 'ใช้สำหรับสอบถามการกำหนดค่ารีเลย์ของผู้ใช้อื่นและเป็นทางเลือกสำรองเมื่อผู้ใช้ไม่ได้กำหนดค่ารีเลย์', + 'Default relays warning': + 'คำเตือน: กรุณาอย่าแก้ไขการตั้งค่าเหล่านี้โดยไม่ระมัดระวัง เพราะอาจส่งผลต่อประสบการณ์พื้นฐานของคุณ', + 'Invalid relay URL': 'URL รีเลย์ไม่ถูกต้อง', + 'Muted words': 'คำที่ถูกปิดเสียง', + 'Add muted word': 'เพิ่มคำที่ถูกปิดเสียง' } } diff --git a/src/i18n/locales/zh-TW.ts b/src/i18n/locales/zh-TW.ts index b6cf94f..2d29c23 100644 --- a/src/i18n/locales/zh-TW.ts +++ b/src/i18n/locales/zh-TW.ts @@ -641,8 +641,11 @@ export default { 'Enable live feed': '啟用即時推送', 'Default relays': '預設中繼', 'Reset to default': '重置為預設', - 'Default relays description': '用於查詢其他使用者的中繼配置,並在使用者沒有配置中繼時作為回退策略。', + 'Default relays description': + '用於查詢其他使用者的中繼配置,並在使用者沒有配置中繼時作為回退策略。', 'Default relays warning': '警告:請不要隨意修改這些設定,可能會影響基礎體驗。', - 'Invalid relay URL': '無效的中繼地址' + 'Invalid relay URL': '無效的中繼地址', + 'Muted words': '屏蔽詞', + 'Add muted word': '添加屏蔽詞' } } diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts index 062f626..617aa3d 100644 --- a/src/i18n/locales/zh.ts +++ b/src/i18n/locales/zh.ts @@ -646,8 +646,11 @@ export default { 'Enable live feed': '启用实时推送', 'Default relays': '默认中继', 'Reset to default': '重置为默认', - 'Default relays description': '用于查询其他用户的中继配置,并在用户没有配置中继时作为回退策略。', - 'Default relays warning': '警告:请不要随意修改这些设置,可能会影响基础体验。', - 'Invalid relay URL': '无效的中继地址' + 'Default relays description': + '用于查询其他用户的中继配置,以及当用户没有配置中继时的备用选项。', + 'Default relays warning': '警告:请不要随意修改这些设置,可能会影响您的基本体验。', + 'Invalid relay URL': '无效的中继地址', + 'Muted words': '屏蔽词', + 'Add muted word': '添加屏蔽词' } } diff --git a/src/pages/secondary/GeneralSettingsPage/MutedWords.tsx b/src/pages/secondary/GeneralSettingsPage/MutedWords.tsx new file mode 100644 index 0000000..7b6a104 --- /dev/null +++ b/src/pages/secondary/GeneralSettingsPage/MutedWords.tsx @@ -0,0 +1,78 @@ +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { useContentPolicy } from '@/providers/ContentPolicyProvider' +import { Plus, X } from 'lucide-react' +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import SettingItem from './SettingItem' + +export default function MutedWords() { + const { t } = useTranslation() + const { mutedWords, setMutedWords } = useContentPolicy() + const [newMutedWord, setNewMutedWord] = useState('') + + const handleAddMutedWord = () => { + const word = newMutedWord.trim().toLowerCase() + if (word && !mutedWords.includes(word)) { + setMutedWords([...mutedWords, word]) + setNewMutedWord('') + } + } + + const handleRemoveMutedWord = (word: string) => { + setMutedWords(mutedWords.filter((w) => w !== word)) + } + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + e.preventDefault() + handleAddMutedWord() + } + } + + return ( + + +
+
+ setNewMutedWord(e.target.value)} + onKeyDown={handleKeyDown} + className="flex-1" + /> + +
+ {mutedWords.length > 0 && ( +
+ {mutedWords.map((word) => ( +
+ {word} + +
+ ))} +
+ )} +
+
+ ) +} diff --git a/src/pages/secondary/GeneralSettingsPage/SettingItem.tsx b/src/pages/secondary/GeneralSettingsPage/SettingItem.tsx new file mode 100644 index 0000000..8ad96f9 --- /dev/null +++ b/src/pages/secondary/GeneralSettingsPage/SettingItem.tsx @@ -0,0 +1,21 @@ +import { cn } from '@/lib/utils' +import { forwardRef, HTMLProps } from 'react' + +const SettingItem = forwardRef>( + ({ children, className, ...props }, ref) => { + return ( +
+ {children} +
+ ) + } +) +SettingItem.displayName = 'SettingItem' +export default SettingItem diff --git a/src/pages/secondary/GeneralSettingsPage/index.tsx b/src/pages/secondary/GeneralSettingsPage/index.tsx index 06ed4e0..6e40c26 100644 --- a/src/pages/secondary/GeneralSettingsPage/index.tsx +++ b/src/pages/secondary/GeneralSettingsPage/index.tsx @@ -11,14 +11,16 @@ import { } from '@/constants' import { LocalizedLanguageNames, TLanguage } from '@/i18n' import SecondaryPageLayout from '@/layouts/SecondaryPageLayout' -import { cn, isSupportCheckConnectionType } from '@/lib/utils' +import { isSupportCheckConnectionType } from '@/lib/utils' import { useContentPolicy } from '@/providers/ContentPolicyProvider' import { useUserPreferences } from '@/providers/UserPreferencesProvider' import { TMediaAutoLoadPolicy, TNsfwDisplayPolicy, TProfilePictureAutoLoadPolicy } from '@/types' import { SelectValue } from '@radix-ui/react-select' import { RotateCcw } from 'lucide-react' -import { forwardRef, HTMLProps, useState } from 'react' +import { forwardRef, useState } from 'react' import { useTranslation } from 'react-i18next' +import MutedWords from './MutedWords' +import SettingItem from './SettingItem' const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => { const { t, i18n } = useTranslation() @@ -188,27 +190,10 @@ const GeneralSettingsPage = forwardRef(({ index }: { index?: number }, ref) => { )} + ) }) GeneralSettingsPage.displayName = 'GeneralSettingsPage' export default GeneralSettingsPage - -const SettingItem = forwardRef>( - ({ children, className, ...props }, ref) => { - return ( -
- {children} -
- ) - } -) -SettingItem.displayName = 'SettingItem' diff --git a/src/providers/ContentPolicyProvider.tsx b/src/providers/ContentPolicyProvider.tsx index 008d320..87d0fb6 100644 --- a/src/providers/ContentPolicyProvider.tsx +++ b/src/providers/ContentPolicyProvider.tsx @@ -23,6 +23,9 @@ type TContentPolicyContext = { faviconUrlTemplate: string setFaviconUrlTemplate: (template: string) => void + + mutedWords: string[] + setMutedWords: (words: string[]) => void } const ContentPolicyContext = createContext(undefined) @@ -46,6 +49,7 @@ export function ContentPolicyProvider({ children }: { children: React.ReactNode storage.getProfilePictureAutoLoadPolicy() ) const [faviconUrlTemplate, setFaviconUrlTemplate] = useState(storage.getFaviconUrlTemplate()) + const [mutedWords, setMutedWords] = useState(storage.getMutedWords()) const [connectionType, setConnectionType] = useState((navigator as any).connection?.type) useEffect(() => { @@ -115,6 +119,11 @@ export function ContentPolicyProvider({ children }: { children: React.ReactNode setFaviconUrlTemplate(template) } + const updateMutedWords = (words: string[]) => { + storage.setMutedWords(words) + setMutedWords(words) + } + return ( {children} diff --git a/src/services/local-storage.service.ts b/src/services/local-storage.service.ts index 95ea95f..9720245 100644 --- a/src/services/local-storage.service.ts +++ b/src/services/local-storage.service.ts @@ -66,6 +66,7 @@ class LocalStorageService { private nsfwDisplayPolicy: TNsfwDisplayPolicy = NSFW_DISPLAY_POLICY.HIDE_CONTENT private minTrustScore: number = 40 private defaultRelayUrls: string[] = BIG_RELAY_URLS + private mutedWords: string[] = [] constructor() { if (!LocalStorageService.instance) { @@ -293,6 +294,18 @@ class LocalStorageService { } } + const mutedWordsStr = window.localStorage.getItem(StorageKey.MUTED_WORDS) + if (mutedWordsStr) { + try { + const words = JSON.parse(mutedWordsStr) + if (Array.isArray(words) && words.every((word) => typeof word === 'string')) { + this.mutedWords = words + } + } catch { + // Invalid JSON, use default + } + } + // Clean up deprecated data window.localStorage.removeItem(StorageKey.PINNED_PUBKEYS) window.localStorage.removeItem(StorageKey.ACCOUNT_PROFILE_EVENT_MAP) @@ -640,6 +653,15 @@ class LocalStorageService { this.defaultRelayUrls = urls window.localStorage.setItem(StorageKey.DEFAULT_RELAY_URLS, JSON.stringify(urls)) } + + getMutedWords() { + return this.mutedWords + } + + setMutedWords(words: string[]) { + this.mutedWords = words + window.localStorage.setItem(StorageKey.MUTED_WORDS, JSON.stringify(this.mutedWords)) + } } const instance = new LocalStorageService()