mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(post-menu): add Report/Delete, reorder buttons, edit-only-for-mods, copy link 5chan.app (#1089)
* Update crypto address UI for .bso accounts * feat(post-menu): add Report/Delete, reorder buttons, edit-only-for-mods, copy link 5chan.app - Remove redundant reason field from edit menu (purged posts unreachable) - Add Report post (placeholder alert) and Delete post (mobile) to post menus - Reorder: Report, Hide, Delete, Copy x3, Image search - Mobile edit checkbox only for mods; authors use Delete in post menu - Copy direct link always uses 5chan.app domain - 10px margin-top on mod menu save button * fix(post-menu): add confirmation before delete post (Bugbot)
This commit is contained in:
@@ -314,5 +314,8 @@
|
|||||||
"archived": "مؤرشف",
|
"archived": "مؤرشف",
|
||||||
"loading_archive": "تحميل الأرشيف...",
|
"loading_archive": "تحميل الأرشيف...",
|
||||||
"thread_archived": "تم أرشفة الموضوع.",
|
"thread_archived": "تم أرشفة الموضوع.",
|
||||||
"view": "عرض"
|
"view": "عرض",
|
||||||
|
"report_post": "الإبلاغ عن المنشور",
|
||||||
|
"delete_post": "حذف المنشور",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "আর্কাইভ করা",
|
"archived": "আর্কাইভ করা",
|
||||||
"loading_archive": "সংরক্ষণাগার লোড করা হচ্ছে...",
|
"loading_archive": "সংরক্ষণাগার লোড করা হচ্ছে...",
|
||||||
"thread_archived": "থ্রেড আর্কাইভ করা হয়েছে।",
|
"thread_archived": "থ্রেড আর্কাইভ করা হয়েছে।",
|
||||||
"view": "দেখুন"
|
"view": "দেখুন",
|
||||||
|
"report_post": "পোস্ট রিপোর্ট করুন",
|
||||||
|
"delete_post": "পোস্ট মুছুন",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Archivováno",
|
"archived": "Archivováno",
|
||||||
"loading_archive": "Načítání archivu...",
|
"loading_archive": "Načítání archivu...",
|
||||||
"thread_archived": "Vlákno archivováno.",
|
"thread_archived": "Vlákno archivováno.",
|
||||||
"view": "Zobrazit"
|
"view": "Zobrazit",
|
||||||
|
"report_post": "Nahlásit příspěvek",
|
||||||
|
"delete_post": "Smazat příspěvek",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arkiveret",
|
"archived": "Arkiveret",
|
||||||
"loading_archive": "Indlæser arkiv...",
|
"loading_archive": "Indlæser arkiv...",
|
||||||
"thread_archived": "Tråd arkiveret.",
|
"thread_archived": "Tråd arkiveret.",
|
||||||
"view": "Se"
|
"view": "Se",
|
||||||
|
"report_post": "Rapporter indlæg",
|
||||||
|
"delete_post": "Slet indlæg",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Archiviert",
|
"archived": "Archiviert",
|
||||||
"loading_archive": "Archiv wird geladen...",
|
"loading_archive": "Archiv wird geladen...",
|
||||||
"thread_archived": "Thread archiviert.",
|
"thread_archived": "Thread archiviert.",
|
||||||
"view": "Ansehen"
|
"view": "Ansehen",
|
||||||
|
"report_post": "Beitrag melden",
|
||||||
|
"delete_post": "Beitrag löschen",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Αρχειοθετημένο",
|
"archived": "Αρχειοθετημένο",
|
||||||
"loading_archive": "Φόρτωση αρχείου...",
|
"loading_archive": "Φόρτωση αρχείου...",
|
||||||
"thread_archived": "Το νήμα αρχειοθετήθηκε.",
|
"thread_archived": "Το νήμα αρχειοθετήθηκε.",
|
||||||
"view": "Προβολή"
|
"view": "Προβολή",
|
||||||
|
"report_post": "Αναφορά ανάρτησης",
|
||||||
|
"delete_post": "Διαγραφή ανάρτησης",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,9 @@
|
|||||||
"invalid_url": "Invalid URL",
|
"invalid_url": "Invalid URL",
|
||||||
"image_search": "image search",
|
"image_search": "image search",
|
||||||
"hide_post": "Hide post",
|
"hide_post": "Hide post",
|
||||||
|
"report_post": "Report post",
|
||||||
|
"delete_post": "Delete post",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone.",
|
||||||
"hide_thread": "Hide thread",
|
"hide_thread": "Hide thread",
|
||||||
"unhide_post": "Unhide post",
|
"unhide_post": "Unhide post",
|
||||||
"unhide_thread": "Unhide thread",
|
"unhide_thread": "Unhide thread",
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Archivado",
|
"archived": "Archivado",
|
||||||
"loading_archive": "Cargando archivo...",
|
"loading_archive": "Cargando archivo...",
|
||||||
"thread_archived": "Hilo archivado.",
|
"thread_archived": "Hilo archivado.",
|
||||||
"view": "Ver"
|
"view": "Ver",
|
||||||
|
"report_post": "Denunciar publicación",
|
||||||
|
"delete_post": "Eliminar publicación",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "بایگانی شده",
|
"archived": "بایگانی شده",
|
||||||
"loading_archive": "در حال بارگذاری بایگانی...",
|
"loading_archive": "در حال بارگذاری بایگانی...",
|
||||||
"thread_archived": "موضوع بایگانی شد.",
|
"thread_archived": "موضوع بایگانی شد.",
|
||||||
"view": "مشاهده"
|
"view": "مشاهده",
|
||||||
|
"report_post": "گزارش پست",
|
||||||
|
"delete_post": "حذف پست",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arkistoitu",
|
"archived": "Arkistoitu",
|
||||||
"loading_archive": "Ladataan arkistoa...",
|
"loading_archive": "Ladataan arkistoa...",
|
||||||
"thread_archived": "Keskustelu arkistoitu.",
|
"thread_archived": "Keskustelu arkistoitu.",
|
||||||
"view": "Katso"
|
"view": "Katso",
|
||||||
|
"report_post": "Ilmoita viestistä",
|
||||||
|
"delete_post": "Poista viesti",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Na-archive",
|
"archived": "Na-archive",
|
||||||
"loading_archive": "Naglo-load ng arkibo...",
|
"loading_archive": "Naglo-load ng arkibo...",
|
||||||
"thread_archived": "Thread na-archive na.",
|
"thread_archived": "Thread na-archive na.",
|
||||||
"view": "Tingnan"
|
"view": "Tingnan",
|
||||||
|
"report_post": "I-report ang post",
|
||||||
|
"delete_post": "Tanggalin ang post",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Archivé",
|
"archived": "Archivé",
|
||||||
"loading_archive": "Chargement des archives...",
|
"loading_archive": "Chargement des archives...",
|
||||||
"thread_archived": "Fil archivé.",
|
"thread_archived": "Fil archivé.",
|
||||||
"view": "Voir"
|
"view": "Voir",
|
||||||
|
"report_post": "Signaler la publication",
|
||||||
|
"delete_post": "Supprimer la publication",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "בארכיון",
|
"archived": "בארכיון",
|
||||||
"loading_archive": "טוען ארכיון...",
|
"loading_archive": "טוען ארכיון...",
|
||||||
"thread_archived": "השרשור נשמר בארכיון.",
|
"thread_archived": "השרשור נשמר בארכיון.",
|
||||||
"view": "צפה"
|
"view": "צפה",
|
||||||
|
"report_post": "דווח על פוסט",
|
||||||
|
"delete_post": "מחק פוסט",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "संग्रहीत",
|
"archived": "संग्रहीत",
|
||||||
"loading_archive": "संग्रह लोड हो रहा है...",
|
"loading_archive": "संग्रह लोड हो रहा है...",
|
||||||
"thread_archived": "थ्रेड आर्काइव हो गया।",
|
"thread_archived": "थ्रेड आर्काइव हो गया।",
|
||||||
"view": "देखें"
|
"view": "देखें",
|
||||||
|
"report_post": "पोस्ट की रिपोर्ट करें",
|
||||||
|
"delete_post": "पोस्ट हटाएं",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Archivált",
|
"archived": "Archivált",
|
||||||
"loading_archive": "Archívum betöltése...",
|
"loading_archive": "Archívum betöltése...",
|
||||||
"thread_archived": "A téma archiválva.",
|
"thread_archived": "A téma archiválva.",
|
||||||
"view": "Megtekintés"
|
"view": "Megtekintés",
|
||||||
|
"report_post": "Bejegyzés jelentése",
|
||||||
|
"delete_post": "Bejegyzés törlése",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Diarsipkan",
|
"archived": "Diarsipkan",
|
||||||
"loading_archive": "Memuat arsip...",
|
"loading_archive": "Memuat arsip...",
|
||||||
"thread_archived": "Benang diarsipkan.",
|
"thread_archived": "Benang diarsipkan.",
|
||||||
"view": "Lihat"
|
"view": "Lihat",
|
||||||
|
"report_post": "Laporkan kiriman",
|
||||||
|
"delete_post": "Hapus kiriman",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Archiviato",
|
"archived": "Archiviato",
|
||||||
"loading_archive": "Caricamento archivio...",
|
"loading_archive": "Caricamento archivio...",
|
||||||
"thread_archived": "Thread archiviato.",
|
"thread_archived": "Thread archiviato.",
|
||||||
"view": "Visualizza"
|
"view": "Visualizza",
|
||||||
|
"report_post": "Segnala post",
|
||||||
|
"delete_post": "Elimina post",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "アーカイブ済み",
|
"archived": "アーカイブ済み",
|
||||||
"loading_archive": "アーカイブを読み込み中...",
|
"loading_archive": "アーカイブを読み込み中...",
|
||||||
"thread_archived": "スレッドがアーカイブされました。",
|
"thread_archived": "スレッドがアーカイブされました。",
|
||||||
"view": "表示"
|
"view": "表示",
|
||||||
|
"report_post": "投稿を報告",
|
||||||
|
"delete_post": "投稿を削除",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "보관됨",
|
"archived": "보관됨",
|
||||||
"loading_archive": "아카이브 로딩 중...",
|
"loading_archive": "아카이브 로딩 중...",
|
||||||
"thread_archived": "스레드가 아카이브되었습니다.",
|
"thread_archived": "스레드가 아카이브되었습니다.",
|
||||||
"view": "보기"
|
"view": "보기",
|
||||||
|
"report_post": "게시물 신고",
|
||||||
|
"delete_post": "게시물 삭제",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "संग्रहित",
|
"archived": "संग्रहित",
|
||||||
"loading_archive": "संग्रह लोड करत आहे...",
|
"loading_archive": "संग्रह लोड करत आहे...",
|
||||||
"thread_archived": "सूत्र आर्काइव केले गेले.",
|
"thread_archived": "सूत्र आर्काइव केले गेले.",
|
||||||
"view": "पहा"
|
"view": "पहा",
|
||||||
|
"report_post": "पोस्ट निर्वेदन करा",
|
||||||
|
"delete_post": "पोस्ट हटवा",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Gearchiveerd",
|
"archived": "Gearchiveerd",
|
||||||
"loading_archive": "Archief laden...",
|
"loading_archive": "Archief laden...",
|
||||||
"thread_archived": "Thread gearchiveerd.",
|
"thread_archived": "Thread gearchiveerd.",
|
||||||
"view": "Bekijken"
|
"view": "Bekijken",
|
||||||
|
"report_post": "Bericht melden",
|
||||||
|
"delete_post": "Bericht verwijderen",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arkivert",
|
"archived": "Arkivert",
|
||||||
"loading_archive": "Laster arkiv...",
|
"loading_archive": "Laster arkiv...",
|
||||||
"thread_archived": "Tråd arkivert.",
|
"thread_archived": "Tråd arkivert.",
|
||||||
"view": "Se"
|
"view": "Se",
|
||||||
|
"report_post": "Rapporter innlegg",
|
||||||
|
"delete_post": "Slett innlegg",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Zarchiwizowany",
|
"archived": "Zarchiwizowany",
|
||||||
"loading_archive": "Ładowanie archiwum...",
|
"loading_archive": "Ładowanie archiwum...",
|
||||||
"thread_archived": "Wątek zarchiwizowany.",
|
"thread_archived": "Wątek zarchiwizowany.",
|
||||||
"view": "Zobacz"
|
"view": "Zobacz",
|
||||||
|
"report_post": "Zgłoś post",
|
||||||
|
"delete_post": "Usuń post",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arquivado",
|
"archived": "Arquivado",
|
||||||
"loading_archive": "Carregando arquivo...",
|
"loading_archive": "Carregando arquivo...",
|
||||||
"thread_archived": "Tópico arquivado.",
|
"thread_archived": "Tópico arquivado.",
|
||||||
"view": "Ver"
|
"view": "Ver",
|
||||||
|
"report_post": "Denunciar publicação",
|
||||||
|
"delete_post": "Excluir publicação",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arhivat",
|
"archived": "Arhivat",
|
||||||
"loading_archive": "Încărcare arhivă...",
|
"loading_archive": "Încărcare arhivă...",
|
||||||
"thread_archived": "Thread arhivat.",
|
"thread_archived": "Thread arhivat.",
|
||||||
"view": "Vizualizare"
|
"view": "Vizualizare",
|
||||||
|
"report_post": "Raportează postarea",
|
||||||
|
"delete_post": "Șterge postarea",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Архивировано",
|
"archived": "Архивировано",
|
||||||
"loading_archive": "Загрузка архива...",
|
"loading_archive": "Загрузка архива...",
|
||||||
"thread_archived": "Тема архивирована.",
|
"thread_archived": "Тема архивирована.",
|
||||||
"view": "Смотреть"
|
"view": "Смотреть",
|
||||||
|
"report_post": "Пожаловаться на пост",
|
||||||
|
"delete_post": "Удалить пост",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arkivuar",
|
"archived": "Arkivuar",
|
||||||
"loading_archive": "Po ngarkoni arkivin...",
|
"loading_archive": "Po ngarkoni arkivin...",
|
||||||
"thread_archived": "Fjala është arkivuar.",
|
"thread_archived": "Fjala është arkivuar.",
|
||||||
"view": "Shiko"
|
"view": "Shiko",
|
||||||
|
"report_post": "Raporto postimin",
|
||||||
|
"delete_post": "Fshi postimin",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arkiverad",
|
"archived": "Arkiverad",
|
||||||
"loading_archive": "Laddar arkiv...",
|
"loading_archive": "Laddar arkiv...",
|
||||||
"thread_archived": "Tråd arkiverad.",
|
"thread_archived": "Tråd arkiverad.",
|
||||||
"view": "Visa"
|
"view": "Visa",
|
||||||
|
"report_post": "Rapportera inlägg",
|
||||||
|
"delete_post": "Radera inlägg",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "ఆర్కైవ్ చేయబడింది",
|
"archived": "ఆర్కైవ్ చేయబడింది",
|
||||||
"loading_archive": "ఆర్కైవ్ లోడ్ అవుతోంది...",
|
"loading_archive": "ఆర్కైవ్ లోడ్ అవుతోంది...",
|
||||||
"thread_archived": "థ్రెడ్ ఆర్కైవ్ చేయబడింది.",
|
"thread_archived": "థ్రెడ్ ఆర్కైవ్ చేయబడింది.",
|
||||||
"view": "చూడు"
|
"view": "చూడు",
|
||||||
|
"report_post": "పోస్ట్ రిపోర్ట్ చేయండి",
|
||||||
|
"delete_post": "పోస్ట్ తొలగించండి",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "เก็บถาวร",
|
"archived": "เก็บถาวร",
|
||||||
"loading_archive": "กำลังโหลดเก็บถาวร...",
|
"loading_archive": "กำลังโหลดเก็บถาวร...",
|
||||||
"thread_archived": "เธรดถูกเก็บถาวร",
|
"thread_archived": "เธรดถูกเก็บถาวร",
|
||||||
"view": "ดู"
|
"view": "ดู",
|
||||||
|
"report_post": "แจ้งรายงานโพสต์",
|
||||||
|
"delete_post": "ลบโพสต์",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Arşivlendi",
|
"archived": "Arşivlendi",
|
||||||
"loading_archive": "Arşiv yükleniyor...",
|
"loading_archive": "Arşiv yükleniyor...",
|
||||||
"thread_archived": "Konu arşivlendi.",
|
"thread_archived": "Konu arşivlendi.",
|
||||||
"view": "Görüntüle"
|
"view": "Görüntüle",
|
||||||
|
"report_post": "Gönderiyi bildir",
|
||||||
|
"delete_post": "Gönderiyi sil",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Архівовано",
|
"archived": "Архівовано",
|
||||||
"loading_archive": "Завантаження архіву...",
|
"loading_archive": "Завантаження архіву...",
|
||||||
"thread_archived": "Тему архівовано.",
|
"thread_archived": "Тему архівовано.",
|
||||||
"view": "Переглянути"
|
"view": "Переглянути",
|
||||||
|
"report_post": "Поскаржитися на пост",
|
||||||
|
"delete_post": "Видалити пост",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "محفوظ شدہ",
|
"archived": "محفوظ شدہ",
|
||||||
"loading_archive": "آرکائیو لوڈ ہو رہا ہے...",
|
"loading_archive": "آرکائیو لوڈ ہو رہا ہے...",
|
||||||
"thread_archived": "موضوع آرکائیو کر دیا گیا ہے۔",
|
"thread_archived": "موضوع آرکائیو کر دیا گیا ہے۔",
|
||||||
"view": "دیکھیں"
|
"view": "دیکھیں",
|
||||||
|
"report_post": "پوسٹ ریپورٹ کریں",
|
||||||
|
"delete_post": "پوسٹ حذف کریں",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "Đã lưu trữ",
|
"archived": "Đã lưu trữ",
|
||||||
"loading_archive": "Đang tải lưu trữ...",
|
"loading_archive": "Đang tải lưu trữ...",
|
||||||
"thread_archived": "Chủ đề đã được lưu trữ.",
|
"thread_archived": "Chủ đề đã được lưu trữ.",
|
||||||
"view": "Xem"
|
"view": "Xem",
|
||||||
|
"report_post": "Báo cáo bài viết",
|
||||||
|
"delete_post": "Xóa bài viết",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,5 +314,8 @@
|
|||||||
"archived": "已归档",
|
"archived": "已归档",
|
||||||
"loading_archive": "正在加载归档...",
|
"loading_archive": "正在加载归档...",
|
||||||
"thread_archived": "主题已归档。",
|
"thread_archived": "主题已归档。",
|
||||||
"view": "查看"
|
"view": "查看",
|
||||||
|
"report_post": "举报帖子",
|
||||||
|
"delete_post": "删除帖子",
|
||||||
|
"delete_post_confirm": "Delete this post permanently? This cannot be undone."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ const basePost = {
|
|||||||
parentCid: undefined as string | undefined,
|
parentCid: undefined as string | undefined,
|
||||||
pinned: false,
|
pinned: false,
|
||||||
postCid: 'post-1',
|
postCid: 'post-1',
|
||||||
reason: '',
|
|
||||||
removed: false,
|
removed: false,
|
||||||
spoiler: false,
|
spoiler: false,
|
||||||
communityAddress: 'music-posting.eth',
|
communityAddress: 'music-posting.eth',
|
||||||
@@ -228,7 +227,7 @@ describe('EditMenu', () => {
|
|||||||
expect(alertSpy).toHaveBeenLastCalledWith('cannot_edit_reply');
|
expect(alertSpy).toHaveBeenLastCalledWith('cannot_edit_reply');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('lets comment authors update content, deletion, and reason', async () => {
|
it('lets comment authors update content and deletion', async () => {
|
||||||
testState.privileges = {
|
testState.privileges = {
|
||||||
isAccountCommentAuthor: true,
|
isAccountCommentAuthor: true,
|
||||||
isAccountMod: false,
|
isAccountMod: false,
|
||||||
@@ -242,12 +241,9 @@ describe('EditMenu', () => {
|
|||||||
await click(getLabelCheckbox('Edit?'));
|
await click(getLabelCheckbox('Edit?'));
|
||||||
|
|
||||||
const textarea = container.querySelector('textarea');
|
const textarea = container.querySelector('textarea');
|
||||||
const reasonInput = container.querySelector<HTMLInputElement>('input[type="text"]');
|
|
||||||
expect(textarea).not.toBeNull();
|
expect(textarea).not.toBeNull();
|
||||||
expect(reasonInput).not.toBeNull();
|
|
||||||
|
|
||||||
await dispatchInput(textarea as HTMLTextAreaElement, 'Updated body');
|
await dispatchInput(textarea as HTMLTextAreaElement, 'Updated body');
|
||||||
await dispatchInput(reasonInput as HTMLInputElement, 'cleanup');
|
|
||||||
await clickButton('save');
|
await clickButton('save');
|
||||||
|
|
||||||
expect(testState.publishAuthorEditMock).toHaveBeenCalledOnce();
|
expect(testState.publishAuthorEditMock).toHaveBeenCalledOnce();
|
||||||
@@ -260,7 +256,6 @@ describe('EditMenu', () => {
|
|||||||
commentCid: 'comment-1',
|
commentCid: 'comment-1',
|
||||||
content: 'Updated body',
|
content: 'Updated body',
|
||||||
deleted: true,
|
deleted: true,
|
||||||
reason: 'cleanup',
|
|
||||||
spoiler: false,
|
spoiler: false,
|
||||||
communityAddress: 'music-posting.eth',
|
communityAddress: 'music-posting.eth',
|
||||||
});
|
});
|
||||||
@@ -343,12 +338,9 @@ describe('EditMenu', () => {
|
|||||||
await click(getCheckbox('banUser'));
|
await click(getCheckbox('banUser'));
|
||||||
|
|
||||||
const banDurationInput = container.querySelector<HTMLInputElement>('[data-testid="ban-duration-input"]');
|
const banDurationInput = container.querySelector<HTMLInputElement>('[data-testid="ban-duration-input"]');
|
||||||
const reasonInput = container.querySelector<HTMLInputElement>('input[type="text"]');
|
|
||||||
expect(banDurationInput).not.toBeNull();
|
expect(banDurationInput).not.toBeNull();
|
||||||
expect(reasonInput).not.toBeNull();
|
|
||||||
|
|
||||||
await dispatchInput(banDurationInput as HTMLInputElement, '7');
|
await dispatchInput(banDurationInput as HTMLInputElement, '7');
|
||||||
await dispatchInput(reasonInput as HTMLInputElement, 'rule violation');
|
|
||||||
await clickButton('save');
|
await clickButton('save');
|
||||||
|
|
||||||
expect(confirmSpy).toHaveBeenCalledWith('purge_confirm');
|
expect(confirmSpy).toHaveBeenCalledWith('purge_confirm');
|
||||||
@@ -363,7 +355,6 @@ describe('EditMenu', () => {
|
|||||||
communityAddress: 'music-posting.eth',
|
communityAddress: 'music-posting.eth',
|
||||||
});
|
});
|
||||||
expect(testState.modOptions?.commentModeration).toMatchObject({
|
expect(testState.modOptions?.commentModeration).toMatchObject({
|
||||||
reason: 'rule violation',
|
|
||||||
archived: true,
|
archived: true,
|
||||||
locked: true,
|
locked: true,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
|
|||||||
@@ -74,6 +74,7 @@
|
|||||||
.bottom button {
|
.bottom button {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
|
margin-top: 10px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +91,8 @@
|
|||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.bottom button {
|
.bottom button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 2px 6px 3px;
|
margin-top: 10px;
|
||||||
|
padding: 2px 6px 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const EditMenu = ({ post }: { post: Comment }) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const resolvedPost = withResolvedCommentCommunityAddress(post);
|
const resolvedPost = withResolvedCommentCommunityAddress(post);
|
||||||
const { author, cid, content, deleted, locked, parentCid, pinned, postCid, reason, removed, spoiler } = resolvedPost || {};
|
const { author, cid, content, deleted, locked, parentCid, pinned, postCid, removed, spoiler } = resolvedPost || {};
|
||||||
const communityAddress = getCommentCommunityAddress(resolvedPost);
|
const communityAddress = getCommentCommunityAddress(resolvedPost);
|
||||||
const archived = isCommentArchived(resolvedPost);
|
const archived = isCommentArchived(resolvedPost);
|
||||||
const authorDisplayName = resolvedPost?.author?.displayName;
|
const authorDisplayName = resolvedPost?.author?.displayName;
|
||||||
@@ -80,7 +80,6 @@ const EditMenu = ({ post }: { post: Comment }) => {
|
|||||||
removed: removed ?? false,
|
removed: removed ?? false,
|
||||||
purged: purged ?? false,
|
purged: purged ?? false,
|
||||||
spoiler: spoiler ?? false,
|
spoiler: spoiler ?? false,
|
||||||
reason,
|
|
||||||
author: modBanExpiresAt ? { banExpiresAt: modBanExpiresAt } : undefined,
|
author: modBanExpiresAt ? { banExpiresAt: modBanExpiresAt } : undefined,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
@@ -101,7 +100,6 @@ const EditMenu = ({ post }: { post: Comment }) => {
|
|||||||
deleted,
|
deleted,
|
||||||
locked,
|
locked,
|
||||||
pinned,
|
pinned,
|
||||||
reason,
|
|
||||||
removed,
|
removed,
|
||||||
purged,
|
purged,
|
||||||
spoiler,
|
spoiler,
|
||||||
@@ -118,7 +116,6 @@ const EditMenu = ({ post }: { post: Comment }) => {
|
|||||||
communityAddress,
|
communityAddress,
|
||||||
content: publishCommentEditOptions.content,
|
content: publishCommentEditOptions.content,
|
||||||
deleted: publishCommentEditOptions.deleted,
|
deleted: publishCommentEditOptions.deleted,
|
||||||
reason: publishCommentEditOptions.reason,
|
|
||||||
spoiler: publishCommentEditOptions.spoiler,
|
spoiler: publishCommentEditOptions.spoiler,
|
||||||
onChallenge,
|
onChallenge,
|
||||||
onChallengeVerification: alertChallengeVerificationFailed,
|
onChallengeVerification: alertChallengeVerificationFailed,
|
||||||
@@ -150,7 +147,6 @@ const EditMenu = ({ post }: { post: Comment }) => {
|
|||||||
removed: publishCommentEditOptions.commentModeration?.removed,
|
removed: publishCommentEditOptions.commentModeration?.removed,
|
||||||
purged: publishCommentEditOptions.commentModeration?.purged,
|
purged: publishCommentEditOptions.commentModeration?.purged,
|
||||||
spoiler: publishCommentEditOptions.commentModeration?.spoiler,
|
spoiler: publishCommentEditOptions.commentModeration?.spoiler,
|
||||||
reason: publishCommentEditOptions.reason,
|
|
||||||
author: publishCommentEditOptions.commentModeration?.author,
|
author: publishCommentEditOptions.commentModeration?.author,
|
||||||
},
|
},
|
||||||
author: account?.author,
|
author: account?.author,
|
||||||
@@ -436,18 +432,6 @@ const EditMenu = ({ post }: { post: Comment }) => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className={`${styles.menuItem} ${styles.menuReason}`}>
|
|
||||||
{capitalize(t('reason'))}? ({t('optional')})
|
|
||||||
<input
|
|
||||||
type='text'
|
|
||||||
value={publishCommentEditOptions.reason || ''}
|
|
||||||
onChange={(e) => {
|
|
||||||
const newReason = e.target.value;
|
|
||||||
setPublishCommentEditOptions((state) => ({ ...state, reason: newReason }));
|
|
||||||
}}
|
|
||||||
size={14}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={styles.bottom}>
|
<div className={styles.bottom}>
|
||||||
<button className={isMobile ? 'button' : ''} onClick={_publishCommentEdit} disabled={!canSave}>
|
<button className={isMobile ? 'button' : ''} onClick={_publishCommentEdit} disabled={!canSave}>
|
||||||
{t('save')}
|
{t('save')}
|
||||||
|
|||||||
@@ -229,9 +229,24 @@ const PostMenuDesktop = ({ postMenu }: PostMenuDesktopProps) => {
|
|||||||
createPortal(
|
createPortal(
|
||||||
<FloatingFocusManager context={context} modal={false}>
|
<FloatingFocusManager context={context} modal={false}>
|
||||||
<div className={styles.postMenu} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
|
<div className={styles.postMenu} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
|
||||||
{cid && resolvedCommunityAddress && <CopyLinkButton cid={cid} communityAddress={resolvedCommunityAddress} linkType='thread' onClose={handleClose} />}
|
<div
|
||||||
{cid && <CopyContentIdButton cid={cid} onClose={handleClose} />}
|
className={styles.postMenuItem}
|
||||||
{authorAddress && <CopyUserIdButton address={authorAddress} onClose={handleClose} />}
|
role='button'
|
||||||
|
tabIndex={0}
|
||||||
|
onClick={() => {
|
||||||
|
alert("Reporting isn't available yet.");
|
||||||
|
handleClose();
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
e.preventDefault();
|
||||||
|
alert("Reporting isn't available yet.");
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('report_post')}
|
||||||
|
</div>
|
||||||
{!(isInPostPageView && postCid === cid) && (
|
{!(isInPostPageView && postCid === cid) && (
|
||||||
<div
|
<div
|
||||||
className={styles.postMenuItem}
|
className={styles.postMenuItem}
|
||||||
@@ -252,6 +267,9 @@ const PostMenuDesktop = ({ postMenu }: PostMenuDesktopProps) => {
|
|||||||
{hidden ? (postCid === cid ? t('unhide_thread') : t('unhide_post')) : postCid === cid ? t('hide_thread') : t('hide_post')}
|
{hidden ? (postCid === cid ? t('unhide_thread') : t('unhide_post')) : postCid === cid ? t('hide_thread') : t('hide_post')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{cid && resolvedCommunityAddress && <CopyLinkButton cid={cid} communityAddress={resolvedCommunityAddress} linkType='thread' onClose={handleClose} />}
|
||||||
|
{cid && <CopyContentIdButton cid={cid} onClose={handleClose} />}
|
||||||
|
{authorAddress && <CopyUserIdButton address={authorAddress} onClose={handleClose} />}
|
||||||
{link && isValidURL(link) && (type === 'image' || type === 'gif' || thumbnail) && url && <ImageSearchButton url={url} onClose={handleClose} />}
|
{link && isValidURL(link) && (type === 'image' || type === 'gif' || thumbnail) && url && <ImageSearchButton url={url} onClose={handleClose} />}
|
||||||
</div>
|
</div>
|
||||||
</FloatingFocusManager>,
|
</FloatingFocusManager>,
|
||||||
|
|||||||
@@ -29,7 +29,10 @@ vi.mock('react-i18next', () => ({
|
|||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('@bitsocialnet/bitsocial-react-hooks', () => ({}));
|
vi.mock('@bitsocialnet/bitsocial-react-hooks', () => ({
|
||||||
|
useAccount: () => ({ author: { address: '0xmod' }, signer: { address: '0xauthor' } }),
|
||||||
|
usePublishCommentEdit: () => ({ publishCommentEdit: vi.fn().mockResolvedValue(undefined) }),
|
||||||
|
}));
|
||||||
|
|
||||||
vi.mock('@bitsocialnet/bitsocial-react-hooks/dist/lib/localforage-lru/index.js', () => ({
|
vi.mock('@bitsocialnet/bitsocial-react-hooks/dist/lib/localforage-lru/index.js', () => ({
|
||||||
default: {
|
default: {
|
||||||
@@ -172,10 +175,10 @@ describe('PostMenuMobile', () => {
|
|||||||
container.remove();
|
container.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('opens the mobile menu, copies share metadata, and shows edit controls for privileged users', async () => {
|
it('opens the mobile menu, copies share metadata, and shows edit controls for mods', async () => {
|
||||||
testState.privileges = {
|
testState.privileges = {
|
||||||
isAccountCommentAuthor: true,
|
isAccountCommentAuthor: true,
|
||||||
isAccountMod: false,
|
isAccountMod: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
await renderMenu('/mu');
|
await renderMenu('/mu');
|
||||||
@@ -203,12 +206,16 @@ describe('PostMenuMobile', () => {
|
|||||||
expect(testState.hideMock).toHaveBeenCalled();
|
expect(testState.hideMock).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows edit controls on pseudonymous boards even without a local author-address match', async () => {
|
it('does not show edit controls on pseudonymous boards when user is not a mod', async () => {
|
||||||
testState.pseudonymityMode = 'per-post';
|
testState.pseudonymityMode = 'per-post';
|
||||||
|
testState.privileges = {
|
||||||
|
isAccountCommentAuthor: false,
|
||||||
|
isAccountMod: false,
|
||||||
|
};
|
||||||
|
|
||||||
await renderMenu('/mu');
|
await renderMenu('/mu');
|
||||||
|
|
||||||
expect(document.body.querySelector('[data-testid="edit-menu"]')?.textContent).toBe('cid-1');
|
expect(document.body.querySelector('[data-testid="edit-menu"]')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not show edit controls when pseudonymity mode is 'none' and the user lacks privileges", async () => {
|
it("does not show edit controls when pseudonymity mode is 'none' and the user lacks privileges", async () => {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { memo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import type { Comment } from '@bitsocialnet/bitsocial-react-hooks';
|
import type { ChallengeVerification, Comment } from '@bitsocialnet/bitsocial-react-hooks';
|
||||||
|
import { useAccount, usePublishCommentEdit } from '@bitsocialnet/bitsocial-react-hooks';
|
||||||
import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
|
import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
|
||||||
import styles from './post-menu-mobile.module.css';
|
import styles from './post-menu-mobile.module.css';
|
||||||
import { getCommentMediaInfo } from '../../../lib/utils/media-utils';
|
import { getCommentMediaInfo } from '../../../lib/utils/media-utils';
|
||||||
@@ -16,6 +17,9 @@ import EditMenu from '../../edit-menu/edit-menu';
|
|||||||
import { isBoardView, isPostPageView } from '../../../lib/utils/view-utils';
|
import { isBoardView, isPostPageView } from '../../../lib/utils/view-utils';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { PostMenuProps } from '../../../lib/utils/post-menu-props';
|
import { PostMenuProps } from '../../../lib/utils/post-menu-props';
|
||||||
|
import { getCommentCommunityAddress, withResolvedCommentCommunityAddress } from '../../../lib/utils/comment-utils';
|
||||||
|
import { alertChallengeVerificationFailed } from '../../../lib/utils/challenge-utils';
|
||||||
|
import useChallengesStore from '../../../stores/use-challenges-store';
|
||||||
|
|
||||||
async function copyShareLinkSafe(boardIdentifier: string, linkType: ShareLinkType, cid?: string): Promise<void> {
|
async function copyShareLinkSafe(boardIdentifier: string, linkType: ShareLinkType, cid?: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
@@ -154,6 +158,113 @@ const ImageSearchButtons = ({ url, onClose }: { url: string; onClose: () => void
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { addChallenge } = useChallengesStore.getState();
|
||||||
|
|
||||||
|
const ReportPostButton = ({ onClose }: { onClose: () => void }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const handleClick = () => {
|
||||||
|
alert("Reporting isn't available yet.");
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role='button'
|
||||||
|
tabIndex={0}
|
||||||
|
onClick={handleClick}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
e.preventDefault();
|
||||||
|
handleClick();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className={styles.postMenuItem}>{t('report_post')}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type DeletePostButtonProps = {
|
||||||
|
post: Comment;
|
||||||
|
onClose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DeletePostButton = ({ post, onClose }: DeletePostButtonProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const account = useAccount();
|
||||||
|
const resolvedPost = withResolvedCommentCommunityAddress(post);
|
||||||
|
const { author, cid } = resolvedPost || {};
|
||||||
|
const communityAddress = getCommentCommunityAddress(resolvedPost);
|
||||||
|
const { isAccountCommentAuthor } = useEditCommentPrivileges({
|
||||||
|
commentAuthorAddress: author?.address || '',
|
||||||
|
communityAddress: communityAddress || '',
|
||||||
|
postCid: resolvedPost?.postCid,
|
||||||
|
});
|
||||||
|
const signer = isAccountCommentAuthor ? account?.signer : undefined;
|
||||||
|
const latestPostRef = useRef(resolvedPost);
|
||||||
|
useEffect(() => {
|
||||||
|
latestPostRef.current = resolvedPost;
|
||||||
|
}, [resolvedPost]);
|
||||||
|
const onChallenge = useCallback(async (...args: unknown[]) => {
|
||||||
|
addChallenge([...args, latestPostRef.current]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const deleteOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
commentCid: cid,
|
||||||
|
communityAddress,
|
||||||
|
deleted: true,
|
||||||
|
...(isAccountCommentAuthor && signer
|
||||||
|
? {
|
||||||
|
signer,
|
||||||
|
author: signer?.address === author?.address ? { address: signer.address, displayName: resolvedPost?.author?.displayName } : account?.author,
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
onChallenge,
|
||||||
|
onChallengeVerification: async (challengeVerification: ChallengeVerification, publication: unknown) => {
|
||||||
|
alertChallengeVerificationFailed(challengeVerification, publication);
|
||||||
|
},
|
||||||
|
onError: (error: Error) => {
|
||||||
|
console.warn(error);
|
||||||
|
alert('Comment edit failed. ' + error.message);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[cid, communityAddress, isAccountCommentAuthor, signer, author?.address, resolvedPost?.author?.displayName, account?.author, onChallenge],
|
||||||
|
);
|
||||||
|
|
||||||
|
const { publishCommentEdit } = usePublishCommentEdit(deleteOptions);
|
||||||
|
|
||||||
|
const handleClick = async () => {
|
||||||
|
const confirmed = window.confirm(t('delete_post_confirm'));
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await publishCommentEdit();
|
||||||
|
onClose();
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
alert(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role='button'
|
||||||
|
tabIndex={0}
|
||||||
|
onClick={handleClick}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
e.preventDefault();
|
||||||
|
handleClick();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className={styles.postMenuItem}>{t('delete_post')}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const HidePostButton = ({ cid, isReply, onClose, postCid }: HideButtonProps) => {
|
const HidePostButton = ({ cid, isReply, onClose, postCid }: HideButtonProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { hide, hidden, unhide } = useHide({ cid: cid || '' });
|
const { hide, hidden, unhide } = useHide({ cid: cid || '' });
|
||||||
@@ -253,10 +364,12 @@ const PostMenuMobile = ({ postMenu, editMenuPost }: PostMenuMobileProps) => {
|
|||||||
createPortal(
|
createPortal(
|
||||||
<FloatingFocusManager context={context} modal={false}>
|
<FloatingFocusManager context={context} modal={false}>
|
||||||
<div className={styles.postMenu} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
|
<div className={styles.postMenu} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
|
||||||
|
<ReportPostButton onClose={handleClose} />
|
||||||
|
{cid && resolvedCommunityAddress && <HidePostButton cid={cid} isReply={!!parentCid} postCid={postCid} onClose={handleClose} />}
|
||||||
|
{(isAccountCommentAuthor || canAttemptAuthorDelete) && cid && <DeletePostButton post={editMenuPost} onClose={handleClose} />}
|
||||||
{cid && resolvedCommunityAddress && <CopyLinkButton cid={cid} communityAddress={resolvedCommunityAddress} linkType='thread' onClose={handleClose} />}
|
{cid && resolvedCommunityAddress && <CopyLinkButton cid={cid} communityAddress={resolvedCommunityAddress} linkType='thread' onClose={handleClose} />}
|
||||||
{cid && <CopyContentIdButton cid={cid} onClose={handleClose} />}
|
{cid && <CopyContentIdButton cid={cid} onClose={handleClose} />}
|
||||||
{authorAddress && <CopyUserIdButton address={authorAddress} onClose={handleClose} />}
|
{authorAddress && <CopyUserIdButton address={authorAddress} onClose={handleClose} />}
|
||||||
{cid && resolvedCommunityAddress && <HidePostButton cid={cid} isReply={!!parentCid} postCid={postCid} onClose={handleClose} />}
|
|
||||||
{link && isValidURL(link) && (type === 'image' || type === 'gif' || thumbnail) && url && <ImageSearchButtons url={url} onClose={handleClose} />}
|
{link && isValidURL(link) && (type === 'image' || type === 'gif' || thumbnail) && url && <ImageSearchButtons url={url} onClose={handleClose} />}
|
||||||
</div>
|
</div>
|
||||||
</FloatingFocusManager>,
|
</FloatingFocusManager>,
|
||||||
@@ -264,7 +377,7 @@ const PostMenuMobile = ({ postMenu, editMenuPost }: PostMenuMobileProps) => {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{(isAccountMod || isAccountCommentAuthor || canAttemptAuthorDelete) && cid && (
|
{isAccountMod && cid && (
|
||||||
<span className={styles.checkbox}>
|
<span className={styles.checkbox}>
|
||||||
<EditMenu post={editMenuPost} />
|
<EditMenu post={editMenuPost} />
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ const CryptoAddressSetting = () => {
|
|||||||
<div className={styles.cryptoAddressInput}>
|
<div className={styles.cryptoAddressInput}>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
placeholder='myaddress.eth'
|
placeholder='myaddress.bso'
|
||||||
value={cryptoState.cryptoAddress}
|
value={cryptoState.cryptoAddress}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setInputValue(e.target.value);
|
setInputValue(e.target.value);
|
||||||
@@ -141,18 +141,18 @@ const CryptoAddressSetting = () => {
|
|||||||
</button>
|
</button>
|
||||||
{showCryptoAddressInfo && (
|
{showCryptoAddressInfo && (
|
||||||
<div className={styles.cryptoAddressInfo}>
|
<div className={styles.cryptoAddressInfo}>
|
||||||
steps to set a .eth address as your ID:
|
steps to set a .bso account address:
|
||||||
<br />
|
<br />
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
go to{' '}
|
buy your desired .bso address as .eth on{' '}
|
||||||
<a href='https://app.ens.domains/' target='_blank' rel='noopener noreferrer'>
|
<a href='https://app.ens.domains/' target='_blank' rel='noopener noreferrer'>
|
||||||
app.ens.domains
|
app.ens.domains
|
||||||
</a>{' '}
|
</a>{' '}
|
||||||
and search the address
|
|
||||||
</li>
|
</li>
|
||||||
<li>once you own the address, go to its page, click on "records", then "edit records"</li>
|
<li>once you own the .eth address, go to its page on ENS, click on "records", then "edit records"</li>
|
||||||
<li>add a new text record with name "bitsocial" and value: {account?.signer?.address}</li>
|
<li>add a new text record with name "bitsocial" and value: {account?.signer?.address}</li>
|
||||||
|
<li>enter your .bso address in the input field above, click "check" to verify it's yours, then click "save"</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ export const isValidURL = (url: string) => {
|
|||||||
const CHAN_5_HOSTNAMES = ['5chan.app', '5chan.eth.limo', '5chan.eth.link', '5chan.eth.sucks', '5chan.netlify.app'];
|
const CHAN_5_HOSTNAMES = ['5chan.app', '5chan.eth.limo', '5chan.eth.link', '5chan.eth.sucks', '5chan.netlify.app'];
|
||||||
|
|
||||||
function getShareBaseUrl(): string {
|
function getShareBaseUrl(): string {
|
||||||
const { protocol, hostname, origin } = window.location;
|
|
||||||
if ((protocol === 'https:' || protocol === 'http:') && hostname !== 'localhost' && hostname !== '127.0.0.1') {
|
|
||||||
return origin;
|
|
||||||
}
|
|
||||||
// Electron / Capacitor / local dev fallback
|
|
||||||
return `https://${CHAN_5_HOSTNAMES[0]}`;
|
return `https://${CHAN_5_HOSTNAMES[0]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user