diff --git a/src/components/PostEditor/PostContent.tsx b/src/components/PostEditor/PostContent.tsx index 42c7635..4684905 100644 --- a/src/components/PostEditor/PostContent.tsx +++ b/src/components/PostEditor/PostContent.tsx @@ -14,11 +14,14 @@ import { useNostr } from '@/providers/NostrProvider' import postEditorCache from '@/services/post-editor-cache.service' import threadService from '@/services/thread.service' import { TPollCreateData } from '@/types' -import { ImageUp, ListTodo, LoaderCircle, Settings, Smile, X } from 'lucide-react' +import { CircleHelp, ImageUp, ListTodo, LoaderCircle, Settings, Smile, X } from 'lucide-react' import { Event, kinds } from 'nostr-tools' -import { useEffect, useMemo, useRef, useState } from 'react' +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' +import { Label } from '@/components/ui/label' +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' +import { Switch } from '@/components/ui/switch' import EmojiPickerDialog from '../EmojiPickerDialog' import Mentions from './Mentions' import PollEditor from './PollEditor' @@ -67,6 +70,18 @@ export default function PostContent({ relays: [] }) const [minPow, setMinPow] = useState(0) + const userDismissedProtected = useRef(false) + const handleProtectedSuggestionChange = useCallback((suggested: boolean) => { + if (suggested && !userDismissedProtected.current) { + setIsProtectedEvent(true) + } + }, []) + const handleProtectedToggle = useCallback((checked: boolean) => { + if (!checked) { + userDismissedProtected.current = true + } + setIsProtectedEvent(checked) + }, []) const isFirstRender = useRef(true) const canPost = useMemo(() => { return ( @@ -257,12 +272,39 @@ export default function PostContent({ ))} {!isPoll && ( - +
+
+ +
+
+ + + + + + + + {t('Protected event hint')} + + +
+
)}
diff --git a/src/components/PostEditor/PostRelaySelector.tsx b/src/components/PostEditor/PostRelaySelector.tsx index d563dc6..c99d763 100644 --- a/src/components/PostEditor/PostRelaySelector.tsx +++ b/src/components/PostEditor/PostRelaySelector.tsx @@ -38,12 +38,12 @@ type TPostTargetItem = export default function PostRelaySelector({ parentEvent, openFrom, - setIsProtectedEvent, + onProtectedSuggestionChange, setAdditionalRelayUrls }: { parentEvent?: NostrEvent openFrom?: string[] - setIsProtectedEvent: Dispatch> + onProtectedSuggestionChange: (suggested: boolean) => void setAdditionalRelayUrls: Dispatch> }) { const { t } = useTranslation() @@ -108,7 +108,8 @@ export default function PostRelaySelector({ }, [openFrom, parentEventSeenOnRelays]) useEffect(() => { - const isProtectedEvent = postTargetItems.every((item) => item.type !== 'optimalRelays') + const shouldProtect = + postTargetItems.length > 0 && postTargetItems.every((item) => item.type !== 'optimalRelays') const relayUrls = postTargetItems.flatMap((item) => { if (item.type === 'relay') { return [item.url] @@ -119,7 +120,7 @@ export default function PostRelaySelector({ return [] }) - setIsProtectedEvent(isProtectedEvent) + onProtectedSuggestionChange(shouldProtect) setAdditionalRelayUrls(relayUrls) }, [postTargetItems]) @@ -208,10 +209,10 @@ export default function PostRelaySelector({ return ( <>
- + diff --git a/src/i18n/locales/ar.ts b/src/i18n/locales/ar.ts index 98f235c..6eeccba 100644 --- a/src/i18n/locales/ar.ts +++ b/src/i18n/locales/ar.ts @@ -673,6 +673,7 @@ export default { 'Automatically replay videos when they end': 'إعادة تشغيل مقاطع الفيديو تلقائيًا عند انتهائها', 'Relays used for searching notes (NIP-50)': 'الريلايات المستخدمة للبحث عن الملاحظات (NIP-50)', 'Protected event (NIP-70)': 'حدث محمي (NIP-70)', - 'Protected': 'محمي' + 'Protected': 'محمي', + 'Protected event hint': 'الأحداث المحمية (NIP-70) لا يمكن نشرها إلا من قبل المؤلف. سترفض الخوادم هذه الأحداث من أطراف ثالثة، مما يمنع الآخرين من إعادة بث محتواك. ملاحظة: لا تدعم جميع الخوادم الأحداث المحمية.' } } diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 34f2e64..ed217ee 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -697,6 +697,7 @@ export default { 'Automatically replay videos when they end': 'Videos automatisch wiederholen, wenn sie enden', 'Relays used for searching notes (NIP-50)': 'Relays für die Notizsuche (NIP-50)', 'Protected event (NIP-70)': 'Geschütztes Ereignis (NIP-70)', - 'Protected': 'Geschützt' + 'Protected': 'Geschützt', + 'Protected event hint': 'Geschützte Ereignisse (NIP-70) können nur vom Autor veröffentlicht werden. Relays lehnen diese Ereignisse von Dritten ab und verhindern so, dass andere Ihre Inhalte weiterverbreiten. Hinweis: Nicht alle Relays unterstützen geschützte Ereignisse.' } } diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index cef8a28..8207787 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -679,6 +679,8 @@ export default { 'Automatically replay videos when they end': 'Automatically replay videos when they end', 'Relays used for searching notes (NIP-50)': 'Relays used for searching notes (NIP-50)', 'Protected event (NIP-70)': 'Protected event (NIP-70)', - 'Protected': 'Protected' + 'Protected': 'Protected', + 'Protected event hint': + 'Protected events (NIP-70) can only be published by the author. Relays will reject these events from third parties, preventing others from rebroadcasting your content. Note: not all relays support protected events.' } } diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts index 99a29b1..dade224 100644 --- a/src/i18n/locales/es.ts +++ b/src/i18n/locales/es.ts @@ -690,6 +690,7 @@ export default { 'Automatically replay videos when they end': 'Reproducir automáticamente los videos cuando terminen', 'Relays used for searching notes (NIP-50)': 'Relés utilizados para buscar notas (NIP-50)', 'Protected event (NIP-70)': 'Evento protegido (NIP-70)', - 'Protected': 'Protegido' + 'Protected': 'Protegido', + 'Protected event hint': 'Los eventos protegidos (NIP-70) solo pueden ser publicados por el autor. Los relés rechazarán estos eventos de terceros, evitando que otros redistribuyan tu contenido. Nota: no todos los relés admiten eventos protegidos.' } } diff --git a/src/i18n/locales/fa.ts b/src/i18n/locales/fa.ts index 01ab315..aecb1b8 100644 --- a/src/i18n/locales/fa.ts +++ b/src/i18n/locales/fa.ts @@ -685,6 +685,7 @@ export default { 'Automatically replay videos when they end': 'پخش خودکار ویدیوها پس از پایان', 'Relays used for searching notes (NIP-50)': 'رله‌هایی که برای جستجوی یادداشت‌ها استفاده می‌شوند (NIP-50)', 'Protected event (NIP-70)': 'رویداد محافظت‌شده (NIP-70)', - 'Protected': 'محافظت‌شده' + 'Protected': 'محافظت‌شده', + 'Protected event hint': 'رویدادهای محافظت‌شده (NIP-70) فقط توسط نویسنده قابل انتشار هستند. رله‌ها این رویدادها را از اشخاص ثالث رد می‌کنند و از بازنشر محتوای شما توسط دیگران جلوگیری می‌کنند. توجه: همه رله‌ها از رویدادهای محافظت‌شده پشتیبانی نمی‌کنند.' } } diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts index ee1a8cd..7c4bd55 100644 --- a/src/i18n/locales/fr.ts +++ b/src/i18n/locales/fr.ts @@ -694,6 +694,7 @@ export default { 'Automatically replay videos when they end': 'Rejouer automatiquement les vidéos à la fin', 'Relays used for searching notes (NIP-50)': 'Relais utilisés pour rechercher des notes (NIP-50)', 'Protected event (NIP-70)': 'Événement protégé (NIP-70)', - 'Protected': 'Protégé' + 'Protected': 'Protégé', + 'Protected event hint': 'Les événements protégés (NIP-70) ne peuvent être publiés que par l\'auteur. Les relais rejetteront ces événements provenant de tiers, empêchant les autres de rediffuser votre contenu. Remarque : tous les relais ne prennent pas en charge les événements protégés.' } } diff --git a/src/i18n/locales/hi.ts b/src/i18n/locales/hi.ts index 52da36e..8790470 100644 --- a/src/i18n/locales/hi.ts +++ b/src/i18n/locales/hi.ts @@ -685,6 +685,7 @@ export default { 'Automatically replay videos when they end': 'वीडियो समाप्त होने पर स्वचालित रूप से दोबारा चलाएं', 'Relays used for searching notes (NIP-50)': 'नोट्स खोजने के लिए उपयोग किए जाने वाले रिले (NIP-50)', 'Protected event (NIP-70)': 'संरक्षित इवेंट (NIP-70)', - 'Protected': 'संरक्षित' + 'Protected': 'संरक्षित', + 'Protected event hint': 'संरक्षित इवेंट (NIP-70) केवल लेखक द्वारा प्रकाशित किए जा सकते हैं। रिले तीसरे पक्ष से इन इवेंट को अस्वीकार कर देंगे, जिससे दूसरों को आपकी सामग्री को पुनः प्रसारित करने से रोका जा सके। नोट: सभी रिले संरक्षित इवेंट का समर्थन नहीं करते।' } } diff --git a/src/i18n/locales/hu.ts b/src/i18n/locales/hu.ts index eb8679a..368fe07 100644 --- a/src/i18n/locales/hu.ts +++ b/src/i18n/locales/hu.ts @@ -679,6 +679,7 @@ export default { 'Automatically replay videos when they end': 'Videók automatikus újrajátszása, amikor véget érnek', 'Relays used for searching notes (NIP-50)': 'Jegyzetek kereséséhez használt csomópontok (NIP-50)', 'Protected event (NIP-70)': 'Védett esemény (NIP-70)', - 'Protected': 'Védett' + 'Protected': 'Védett', + 'Protected event hint': 'A védett eseményeket (NIP-70) csak a szerző teheti közzé. A csomópontok elutasítják ezeket az eseményeket harmadik felektől, megakadályozva, hogy mások újraközvetítsék a tartalmadat. Megjegyzés: nem minden csomópont támogatja a védett eseményeket.' } } diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts index 127cd8a..862eee6 100644 --- a/src/i18n/locales/it.ts +++ b/src/i18n/locales/it.ts @@ -690,6 +690,7 @@ export default { 'Automatically replay videos when they end': 'Riprodurre automaticamente i video quando terminano', 'Relays used for searching notes (NIP-50)': 'Relay utilizzati per cercare le note (NIP-50)', 'Protected event (NIP-70)': 'Evento protetto (NIP-70)', - 'Protected': 'Protetto' + 'Protected': 'Protetto', + 'Protected event hint': 'Gli eventi protetti (NIP-70) possono essere pubblicati solo dall\'autore. I relay rifiuteranno questi eventi da terze parti, impedendo ad altri di ridiffondere i tuoi contenuti. Nota: non tutti i relay supportano gli eventi protetti.' } } diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts index 1642f35..a2b914e 100644 --- a/src/i18n/locales/ja.ts +++ b/src/i18n/locales/ja.ts @@ -685,6 +685,7 @@ export default { 'Automatically replay videos when they end': 'ビデオ終了時に自動的にリプレイする', 'Relays used for searching notes (NIP-50)': 'ノート検索に使用するリレー (NIP-50)', 'Protected event (NIP-70)': '保護されたイベント (NIP-70)', - 'Protected': '保護' + 'Protected': '保護', + 'Protected event hint': '保護されたイベント(NIP-70)は作成者のみが公開できます。リレーは第三者からのこれらのイベントを拒否し、他者によるコンテンツの再配信を防ぎます。 注意:すべてのリレーが保護されたイベントに対応しているわけではありません。' } } diff --git a/src/i18n/locales/ko.ts b/src/i18n/locales/ko.ts index 795ca35..042bbe8 100644 --- a/src/i18n/locales/ko.ts +++ b/src/i18n/locales/ko.ts @@ -679,6 +679,7 @@ export default { 'Automatically replay videos when they end': '비디오가 끝나면 자동으로 다시 재생', 'Relays used for searching notes (NIP-50)': '노트 검색에 사용되는 릴레이 (NIP-50)', 'Protected event (NIP-70)': '보호된 이벤트 (NIP-70)', - 'Protected': '보호됨' + 'Protected': '보호됨', + 'Protected event hint': '보호된 이벤트(NIP-70)는 작성자만 게시할 수 있습니다. 릴레이는 제3자의 이벤트를 거부하여 다른 사람이 콘텐츠를 재배포하는 것을 방지합니다. 참고: 모든 릴레이가 보호된 이벤트를 지원하는 것은 아닙니다.' } } diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts index 85a2836..55907f0 100644 --- a/src/i18n/locales/pl.ts +++ b/src/i18n/locales/pl.ts @@ -691,6 +691,7 @@ export default { 'Automatically replay videos when they end': 'Automatycznie powtarzaj filmy po zakończeniu', 'Relays used for searching notes (NIP-50)': 'Przekaźniki używane do wyszukiwania notatek (NIP-50)', 'Protected event (NIP-70)': 'Chronione zdarzenie (NIP-70)', - 'Protected': 'Chronione' + 'Protected': 'Chronione', + 'Protected event hint': 'Chronione zdarzenia (NIP-70) mogą być publikowane tylko przez autora. Przekaźniki odrzucą te zdarzenia od osób trzecich, uniemożliwiając innym retransmisję Twoich treści. Uwaga: nie wszystkie przekaźniki obsługują chronione zdarzenia.' } } diff --git a/src/i18n/locales/pt-BR.ts b/src/i18n/locales/pt-BR.ts index bb3d9f2..4eae112 100644 --- a/src/i18n/locales/pt-BR.ts +++ b/src/i18n/locales/pt-BR.ts @@ -688,6 +688,7 @@ export default { 'Automatically replay videos when they end': 'Reproduzir automaticamente os vídeos quando terminarem', 'Relays used for searching notes (NIP-50)': 'Relays usados para buscar notas (NIP-50)', 'Protected event (NIP-70)': 'Evento protegido (NIP-70)', - 'Protected': 'Protegido' + 'Protected': 'Protegido', + 'Protected event hint': 'Eventos protegidos (NIP-70) só podem ser publicados pelo autor. Os relays rejeitarão esses eventos de terceiros, impedindo que outros retransmitam seu conteúdo. Nota: nem todos os relays suportam eventos protegidos.' } } diff --git a/src/i18n/locales/pt-PT.ts b/src/i18n/locales/pt-PT.ts index 6d18ad2..49c0db6 100644 --- a/src/i18n/locales/pt-PT.ts +++ b/src/i18n/locales/pt-PT.ts @@ -691,6 +691,7 @@ export default { 'Automatically replay videos when they end': 'Reproduzir automaticamente os vídeos quando terminarem', 'Relays used for searching notes (NIP-50)': 'Relés usados para pesquisar notas (NIP-50)', 'Protected event (NIP-70)': 'Evento protegido (NIP-70)', - 'Protected': 'Protegido' + 'Protected': 'Protegido', + 'Protected event hint': 'Eventos protegidos (NIP-70) só podem ser publicados pelo autor. Os relés rejeitarão estes eventos de terceiros, impedindo que outros retransmitam o seu conteúdo. Nota: nem todos os relés suportam eventos protegidos.' } } diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts index b9be787..9d9a786 100644 --- a/src/i18n/locales/ru.ts +++ b/src/i18n/locales/ru.ts @@ -690,6 +690,7 @@ export default { 'Automatically replay videos when they end': 'Автоматически воспроизводить видео заново после окончания', 'Relays used for searching notes (NIP-50)': 'Ретрансляторы для поиска заметок (NIP-50)', 'Protected event (NIP-70)': 'Защищённое событие (NIP-70)', - 'Protected': 'Защищённый' + 'Protected': 'Защищённый', + 'Protected event hint': 'Защищённые события (NIP-70) могут быть опубликованы только автором. Ретрансляторы отклонят эти события от третьих лиц, предотвращая повторную трансляцию вашего контента. Примечание: не все ретрансляторы поддерживают защищённые события.' } } diff --git a/src/i18n/locales/th.ts b/src/i18n/locales/th.ts index 2c24539..f238e8d 100644 --- a/src/i18n/locales/th.ts +++ b/src/i18n/locales/th.ts @@ -675,6 +675,7 @@ export default { 'Automatically replay videos when they end': 'เล่นวิดีโอซ้ำอัตโนมัติเมื่อจบ', 'Relays used for searching notes (NIP-50)': 'รีเลย์ที่ใช้สำหรับค้นหาโน้ต (NIP-50)', 'Protected event (NIP-70)': 'เหตุการณ์ที่ได้รับการป้องกัน (NIP-70)', - 'Protected': 'ป้องกัน' + 'Protected': 'ป้องกัน', + 'Protected event hint': 'เหตุการณ์ที่ได้รับการป้องกัน (NIP-70) สามารถเผยแพร่ได้โดยผู้เขียนเท่านั้น รีเลย์จะปฏิเสธเหตุการณ์เหล่านี้จากบุคคลที่สาม ป้องกันไม่ให้ผู้อื่นเผยแพร่เนื้อหาของคุณซ้ำ หมายเหตุ: รีเลย์บางแห่งไม่รองรับเหตุการณ์ที่ได้รับการป้องกัน' } } diff --git a/src/i18n/locales/zh-TW.ts b/src/i18n/locales/zh-TW.ts index f2435c7..f48ce3f 100644 --- a/src/i18n/locales/zh-TW.ts +++ b/src/i18n/locales/zh-TW.ts @@ -657,6 +657,7 @@ export default { 'Automatically replay videos when they end': '影片播放結束後自動重新播放', 'Relays used for searching notes (NIP-50)': '用於搜尋筆記的伺服器 (NIP-50)', 'Protected event (NIP-70)': '受保護的事件 (NIP-70)', - 'Protected': '受保護' + 'Protected': '受保護', + 'Protected event hint': '受保護的事件(NIP-70)只能由作者發布。伺服器將拒絕來自第三方的這些事件,防止他人轉播你的內容。 注意:並非所有伺服器都支持受保護的事件。' } } diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts index 71c0014..6fa7fc6 100644 --- a/src/i18n/locales/zh.ts +++ b/src/i18n/locales/zh.ts @@ -662,6 +662,7 @@ export default { 'Automatically replay videos when they end': '视频播放结束后自动重新播放', 'Relays used for searching notes (NIP-50)': '用于搜索笔记的服务器 (NIP-50)', 'Protected event (NIP-70)': '受保护的事件 (NIP-70)', - 'Protected': '受保护' + 'Protected': '受保护', + 'Protected event hint': '受保护的事件(NIP-70)只能由作者发布。服务器将拒绝来自第三方的这些事件,防止他人转播你的内容。 注意:并非所有服务器都支持受保护的事件。' } }