diff --git a/package.json b/package.json index b1f06938..f4ccafd8 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "prettier": "3.0.3", "react": "18.2.0", "react-dom": "18.2.0", - "react-draggable": "^4.4.6", + "react-draggable": "4.4.6", "react-i18next": "13.2.2", "react-markdown": "8.0.6", "react-router-dom": "6.16.0", @@ -136,9 +136,6 @@ "category": "Network" } }, - "resolutions": { - "styled-components": "^5" - }, "lint-staged": { "{src,electron}/**/*.{js,ts,tsx}": [ "prettier --write" diff --git a/public/translations/ar/default.json b/public/translations/ar/default.json index c17ccfef..fc0e9c5e 100644 --- a/public/translations/ar/default.json +++ b/public/translations/ar/default.json @@ -48,5 +48,16 @@ "name": "الاسم", "comment": "تعليق", "subject": "الموضوع", - "anonymous": "مجهول" + "anonymous": "مجهول", + "image": "صورة", + "video": "فيديو", + "audio": "صوت", + "webpage": "صفحة ويب", + "iframe": "إطار", + "rules": "القواعد", + "welcome_to_board": "مرحبًا بك في {{board}}", + "comment_too_long": "التعليق طويل جدًا. <1>اضغط هنا لعرض النص الكامل.", + "replies_omitted": "{{repliesCount}} ردود محذوفة. <1>اضغط هنا لعرضها.", + "replies_and_links_omitted": "{{repliesCount}} ردود و{{linksCount}} روابط محذوفة. <1>اضغط هنا لعرضها.", + "thread_closed_alert": "الموضوع مغلق" } \ No newline at end of file diff --git a/public/translations/bn/default.json b/public/translations/bn/default.json index 545ae876..b74f78fe 100644 --- a/public/translations/bn/default.json +++ b/public/translations/bn/default.json @@ -48,5 +48,16 @@ "name": "নাম", "comment": "মন্তব্য", "subject": "বিষয়", - "anonymous": "অজানা" + "anonymous": "অজানা", + "image": "ছবি", + "video": "ভিডিও", + "audio": "অডিও", + "webpage": "ওয়েবপেজ", + "iframe": "আইফ্রেম", + "rules": "নিয়ম", + "welcome_to_board": "স্বাগতম {{board}}", + "comment_too_long": "মন্তব্য খুব দীর্ঘ। <1>পূর্ণ পাঠ্য দেখতে এখানে ক্লিক করুন।", + "replies_omitted": "{{repliesCount}}টি উত্তর বাদ দেওয়া হয়েছে। <1>দেখতে এখানে ক্লিক করুন।", + "replies_and_links_omitted": "{{repliesCount}}টি উত্তর এবং {{linksCount}}টি লিঙ্ক বাদ দেওয়া হয়েছে। <1>দেখতে এখানে ক্লিক করুন।", + "thread_closed_alert": "থ্রেডটি বন্ধ করা হয়েছে" } \ No newline at end of file diff --git a/public/translations/cs/default.json b/public/translations/cs/default.json index 83f58984..97b0a3de 100644 --- a/public/translations/cs/default.json +++ b/public/translations/cs/default.json @@ -48,5 +48,16 @@ "name": "název", "comment": "komentář", "subject": "předmět", - "anonymous": "anonymní" + "anonymous": "anonymní", + "image": "obrázek", + "video": "video", + "audio": "audio", + "webpage": "webová stránka", + "iframe": "iframe", + "rules": "pravidla", + "welcome_to_board": "Vítejte na {{board}}", + "comment_too_long": "Komentář je příliš dlouhý. <1>Klikněte zde pro zobrazení celého textu.", + "replies_omitted": "{{repliesCount}} odpovědí vynecháno. <1>Klikněte zde pro zobrazení.", + "replies_and_links_omitted": "{{repliesCount}} odpovědí a {{linksCount}} odkazů vynecháno. <1>Klikněte zde pro zobrazení.", + "thread_closed_alert": "Vlákno je uzavřeno" } \ No newline at end of file diff --git a/public/translations/da/default.json b/public/translations/da/default.json index 35209c74..581b45ba 100644 --- a/public/translations/da/default.json +++ b/public/translations/da/default.json @@ -48,5 +48,16 @@ "name": "navn", "comment": "kommentar", "subject": "emne", - "anonymous": "anonym" + "anonymous": "anonym", + "image": "billede", + "video": "video", + "audio": "lyd", + "webpage": "websted", + "iframe": "iframe", + "rules": "regler", + "welcome_to_board": "Velkommen til {{board}}", + "comment_too_long": "Kommentaren er for lang. <1>Klik her for at se hele teksten.", + "replies_omitted": "{{repliesCount}} svar udeladt. <1>Klik her for at se dem.", + "replies_and_links_omitted": "{{repliesCount}} svar og {{linksCount}} links udeladt. <1>Klik her for at se dem.", + "thread_closed_alert": "Tråden er lukket" } \ No newline at end of file diff --git a/public/translations/de/default.json b/public/translations/de/default.json index b82a3c06..7e6df859 100644 --- a/public/translations/de/default.json +++ b/public/translations/de/default.json @@ -48,5 +48,16 @@ "name": "Name", "comment": "Kommentar", "subject": "Betreff", - "anonymous": "anonym" + "anonymous": "anonym", + "image": "Bild", + "video": "Video", + "audio": "Audio", + "webpage": "Webseite", + "iframe": "iframe", + "rules": "Regeln", + "welcome_to_board": "Willkommen bei {{board}}", + "comment_too_long": "Kommentar zu lang. <1>Klicken Sie hier, um den vollständigen Text anzuzeigen.", + "replies_omitted": "{{repliesCount}} Antworten ausgelassen. <1>Klicken Sie hier, um sie anzuzeigen.", + "replies_and_links_omitted": "{{repliesCount}} Antworten und {{linksCount}} Links ausgelassen. <1>Klicken Sie hier, um sie anzuzeigen.", + "thread_closed_alert": "Der Thread ist geschlossen" } \ No newline at end of file diff --git a/public/translations/el/default.json b/public/translations/el/default.json index 13a822a3..4927f4bb 100644 --- a/public/translations/el/default.json +++ b/public/translations/el/default.json @@ -48,5 +48,16 @@ "name": "όνομα", "comment": "σχόλιο", "subject": "θέμα", - "anonymous": "ανώνυμος" + "anonymous": "ανώνυμος", + "image": "εικόνα", + "video": "βίντεο", + "audio": "ήχος", + "webpage": "ιστοσελίδα", + "iframe": "πλαίσιο", + "rules": "κανόνες", + "welcome_to_board": "Καλώς ήρθατε στο {{board}}", + "comment_too_long": "Το σχόλιο είναι πολύ μακροσκελές. <1>Κάντε κλικ εδώ για να δείτε το πλήρες κείμενο.", + "replies_omitted": "{{repliesCount}} απαντήσεις παραλείφθηκαν. <1>Κάντε κλικ εδώ για να τις δείτε.", + "replies_and_links_omitted": "{{repliesCount}} απαντήσεις και {{linksCount}} σύνδεσμοι παραλείφθηκαν. <1>Κάντε κλικ εδώ για να τις δείτε.", + "thread_closed_alert": "Το νήμα έχει κλείσει" } \ No newline at end of file diff --git a/public/translations/en/default.json b/public/translations/en/default.json index 41965aca..431f808f 100644 --- a/public/translations/en/default.json +++ b/public/translations/en/default.json @@ -48,5 +48,16 @@ "name": "name", "comment": "comment", "subject": "subject", - "anonymous": "anonymous" + "anonymous": "anonymous", + "image": "image", + "video": "video", + "audio": "audio", + "webpage": "webpage", + "iframe": "iframe", + "rules": "rules", + "welcome_to_board": "Welcome to {{board}}", + "comment_too_long": "Comment too long. <1>Click here to view the full text.", + "replies_omitted": "{{repliesCount}} replies omitted. <1>Click here to view.", + "replies_and_links_omitted": "{{repliesCount}} replies and {{linksCount}} links omitted. <1>Click here to view.", + "thread_closed_alert": "This thread is closed" } \ No newline at end of file diff --git a/public/translations/es/default.json b/public/translations/es/default.json index 2e94b23e..ca55ff87 100644 --- a/public/translations/es/default.json +++ b/public/translations/es/default.json @@ -48,5 +48,16 @@ "name": "nombre", "comment": "comentario", "subject": "asunto", - "anonymous": "anónimo" + "anonymous": "anónimo", + "image": "imagen", + "video": "video", + "audio": "audio", + "webpage": "página web", + "iframe": "iframe", + "rules": "reglas", + "welcome_to_board": "Bienvenido a {{board}}", + "comment_too_long": "Comentario demasiado largo. <1>Haz clic aquí para ver el texto completo.", + "replies_omitted": "{{repliesCount}} respuestas omitidas. <1>Haz clic aquí para verlas.", + "replies_and_links_omitted": "{{repliesCount}} respuestas y {{linksCount}} enlaces omitidos. <1>Haz clic aquí para verlos.", + "thread_closed_alert": "El hilo está cerrado" } \ No newline at end of file diff --git a/public/translations/fa/default.json b/public/translations/fa/default.json index 21c97e7b..b8b10622 100644 --- a/public/translations/fa/default.json +++ b/public/translations/fa/default.json @@ -48,5 +48,16 @@ "name": "نام", "comment": "نظر", "subject": "موضوع", - "anonymous": "ناشناس" + "anonymous": "ناشناس", + "image": "تصویر", + "video": "ویدیو", + "audio": "صدا", + "webpage": "صفحه وب", + "iframe": "فریم", + "rules": "قوانین", + "welcome_to_board": "خوش آمدید به {{board}}", + "comment_too_long": "نظر بسیار طولانی است. <1>اینجا کلیک کنید تا متن کامل را ببینید.", + "replies_omitted": "{{repliesCount}} پاسخ حذف شده است. <1>اینجا کلیک کنید تا آنها را مشاهده کنید.", + "replies_and_links_omitted": "{{repliesCount}} پاسخ و {{linksCount}} لینک حذف شده است. <1>اینجا کلیک کنید تا آنها را مشاهده کنید.", + "thread_closed_alert": "موضوع بسته شده است" } \ No newline at end of file diff --git a/public/translations/fi/default.json b/public/translations/fi/default.json index d5bd89de..11341f19 100644 --- a/public/translations/fi/default.json +++ b/public/translations/fi/default.json @@ -48,5 +48,16 @@ "name": "nimi", "comment": "kommentti", "subject": "aihe", - "anonymous": "anonyymi" + "anonymous": "anonyymi", + "image": "kuva", + "video": "video", + "audio": "audio", + "webpage": "verkkosivu", + "iframe": "iframe", + "rules": "säännöt", + "welcome_to_board": "Tervetuloa {{board}}", + "comment_too_long": "Kommentti on liian pitkä. <1>Napsauta tästä nähdäksesi koko tekstin.", + "replies_omitted": "{{repliesCount}} vastausta jätetty pois. <1>Napsauta tästä nähdäksesi ne.", + "replies_and_links_omitted": "{{repliesCount}} vastausta ja {{linksCount}} linkkiä jätetty pois. <1>Napsauta tästä nähdäksesi ne.", + "thread_closed_alert": "Ketju on suljettu" } \ No newline at end of file diff --git a/public/translations/fil/default.json b/public/translations/fil/default.json index f1a0f020..f0fe4e70 100644 --- a/public/translations/fil/default.json +++ b/public/translations/fil/default.json @@ -48,5 +48,16 @@ "name": "pangalan", "comment": "komento", "subject": "paksa", - "anonymous": "anonimo" + "anonymous": "anonimo", + "image": "larawan", + "video": "video", + "audio": "audio", + "webpage": "pahinahon", + "iframe": "iframe", + "rules": "mga patakaran", + "welcome_to_board": "Maligayang pagdating sa {{board}}", + "comment_too_long": "Masyadong mahaba ang komento. <1>I-click dito upang makita ang buong teksto.", + "replies_omitted": "{{repliesCount}} mga tugon ang hindi ipinakita. <1>I-click dito upang makita.", + "replies_and_links_omitted": "{{repliesCount}} mga tugon at {{linksCount}} mga link ang hindi ipinakita. <1>I-click dito upang makita.", + "thread_closed_alert": "Sarado na ang thread" } \ No newline at end of file diff --git a/public/translations/fr/default.json b/public/translations/fr/default.json index fc611b16..09653643 100644 --- a/public/translations/fr/default.json +++ b/public/translations/fr/default.json @@ -48,5 +48,16 @@ "name": "nom", "comment": "commentaire", "subject": "sujet", - "anonymous": "anonyme" + "anonymous": "anonyme", + "image": "image", + "video": "vidéo", + "audio": "audio", + "webpage": "page web", + "iframe": "iframe", + "rules": "règles", + "welcome_to_board": "Bienvenue sur {{board}}", + "comment_too_long": "Commentaire trop long. <1>Cliquez ici pour voir le texte complet.", + "replies_omitted": "{{repliesCount}} réponses omises. <1>Cliquez ici pour les afficher.", + "replies_and_links_omitted": "{{repliesCount}} réponses et {{linksCount}} liens omis. <1>Cliquez ici pour les afficher.", + "thread_closed_alert": "Le fil est fermé" } \ No newline at end of file diff --git a/public/translations/he/default.json b/public/translations/he/default.json index 803ad4f2..b49af68f 100644 --- a/public/translations/he/default.json +++ b/public/translations/he/default.json @@ -48,5 +48,16 @@ "name": "שם", "comment": "תגובה", "subject": "נושא", - "anonymous": "אנונימי" + "anonymous": "אנונימי", + "image": "תמונה", + "video": "וידאו", + "audio": "שמע", + "webpage": "דף אינטרנט", + "iframe": "מסגרת", + "rules": "חוקים", + "welcome_to_board": "ברוך הבא ל{{board}}", + "comment_too_long": "התגובה ארוכה מדי. <1>לחץ כאן כדי לראות את הטקסט המלא.", + "replies_omitted": "{{repliesCount}} תגובות נשמטו. <1>לחץ כאן לצפייה.", + "replies_and_links_omitted": "{{repliesCount}} תגובות ו{{linksCount}} קישורים נשמטו. <1>לחץ כאן לצפייה.", + "thread_closed_alert": "האשכול סגור" } \ No newline at end of file diff --git a/public/translations/hi/default.json b/public/translations/hi/default.json index 3c779dc1..ec41b0ff 100644 --- a/public/translations/hi/default.json +++ b/public/translations/hi/default.json @@ -48,5 +48,16 @@ "name": "नाम", "comment": "टिप्पणी", "subject": "विषय", - "anonymous": "अनाम" + "anonymous": "अनाम", + "image": "चित्र", + "video": "वीडियो", + "audio": "ऑडियो", + "webpage": "वेबपेज", + "iframe": "आइफ्रेम", + "rules": "नियम", + "welcome_to_board": "{{board}} में आपका स्वागत है", + "comment_too_long": "टिप्पणी बहुत लंबी है। <1>पूरा टेक्स्ट देखने के लिए यहां क्लिक करें।", + "replies_omitted": "{{repliesCount}} उत्तर छोड़े गए हैं। <1>देखने के लिए यहां क्लिक करें।", + "replies_and_links_omitted": "{{repliesCount}} उत्तर और {{linksCount}} लिंक छोड़े गए हैं। <1>देखने के लिए यहां क्लिक करें।", + "thread_closed_alert": "यह थ्रेड बंद है" } \ No newline at end of file diff --git a/public/translations/hu/default.json b/public/translations/hu/default.json index 34d6ab3e..ce807949 100644 --- a/public/translations/hu/default.json +++ b/public/translations/hu/default.json @@ -48,5 +48,16 @@ "name": "név", "comment": "megjegyzés", "subject": "tárgy", - "anonymous": "névtelen" + "anonymous": "névtelen", + "image": "kép", + "video": "videó", + "audio": "hang", + "webpage": "weboldal", + "iframe": "iframe", + "rules": "szabályok", + "welcome_to_board": "Üdvözöljük a(z) {{board}} oldalon", + "comment_too_long": "A megjegyzés túl hosszú. <1>Kattintson ide a teljes szöveg megtekintéséhez.", + "replies_omitted": "{{repliesCount}} válasz kihagyva. <1>Kattintson ide a megtekintéshez.", + "replies_and_links_omitted": "{{repliesCount}} válasz és {{linksCount}} link kihagyva. <1>Kattintson ide a megtekintéshez.", + "thread_closed_alert": "A téma lezárva" } \ No newline at end of file diff --git a/public/translations/id/default.json b/public/translations/id/default.json index 92283072..d4ff253d 100644 --- a/public/translations/id/default.json +++ b/public/translations/id/default.json @@ -48,5 +48,16 @@ "name": "nama", "comment": "komentar", "subject": "subjek", - "anonymous": "anonim" + "anonymous": "anonim", + "image": "gambar", + "video": "video", + "audio": "audio", + "webpage": "halaman web", + "iframe": "iframe", + "rules": "aturan", + "welcome_to_board": "Selamat datang di {{board}}", + "comment_too_long": "Komentar terlalu panjang. <1>Klik di sini untuk melihat teks lengkap.", + "replies_omitted": "{{repliesCount}} balasan dihilangkan. <1>Klik di sini untuk melihat.", + "replies_and_links_omitted": "{{repliesCount}} balasan dan {{linksCount}} tautan dihilangkan. <1>Klik di sini untuk melihat.", + "thread_closed_alert": "Thread ini ditutup" } \ No newline at end of file diff --git a/public/translations/it/default.json b/public/translations/it/default.json index 597daf9a..272266a7 100644 --- a/public/translations/it/default.json +++ b/public/translations/it/default.json @@ -12,7 +12,7 @@ "whitepaper": "Libro bianco", "token": "Token", "download_app": "Scarica app", - "start_new_thread": "Inizia un Nuovo Thread", + "start_new_thread": "Invia un Nuovo Thread", "show_stats": "Mostra Statistiche", "hide": "Nascondi", "board_stats_hour": "Nell'ultima ora, <1>{{userCount}} utenti hanno inviato <1>{{postCount}} post", @@ -48,5 +48,16 @@ "name": "nome", "comment": "commento", "subject": "oggetto", - "anonymous": "anonimo" + "anonymous": "anonimo", + "image": "immagine", + "video": "video", + "audio": "audio", + "webpage": "pagina web", + "iframe": "iframe", + "rules": "regole", + "welcome_to_board": "Benvenuti su {{board}}", + "comment_too_long": "Commento troppo lungo. <1>Clicca qui per vedere il testo completo.", + "replies_omitted": "{{repliesCount}} risposte omesse. <1>Clicca qui per visualizzare.", + "replies_and_links_omitted": "{{repliesCount}} risposte e {{linksCount}} link omessi. <1>Clicca qui per visualizzare.", + "thread_closed_alert": "Questo thread è chiuso" } \ No newline at end of file diff --git a/public/translations/ja/default.json b/public/translations/ja/default.json index 55e490a2..1c2daef2 100644 --- a/public/translations/ja/default.json +++ b/public/translations/ja/default.json @@ -48,5 +48,16 @@ "name": "名前", "comment": "コメント", "subject": "件名", - "anonymous": "匿名" + "anonymous": "匿名", + "image": "画像", + "video": "ビデオ", + "audio": "音声", + "webpage": "ウェブページ", + "iframe": "アイフレーム", + "rules": "ルール", + "welcome_to_board": "{{board}}へようこそ", + "comment_too_long": "コメントが長すぎます。 <1>ここをクリックして全文を表示。", + "replies_omitted": "{{repliesCount}}件の返信が省略されました。 <1>ここをクリックして表示。", + "replies_and_links_omitted": "{{repliesCount}}件の返信と{{linksCount}}件のリンクが省略されました。 <1>ここをクリックして表示。", + "thread_closed_alert": "このスレッドは閉じられています" } \ No newline at end of file diff --git a/public/translations/ko/default.json b/public/translations/ko/default.json index 83956a99..bbd25d9e 100644 --- a/public/translations/ko/default.json +++ b/public/translations/ko/default.json @@ -48,5 +48,16 @@ "name": "이름", "comment": "댓글", "subject": "제목", - "anonymous": "익명" + "anonymous": "익명", + "image": "이미지", + "video": "비디오", + "audio": "오디오", + "webpage": "웹 페이지", + "iframe": "iframe", + "rules": "규칙", + "welcome_to_board": "{{board}}에 오신 것을 환영합니다", + "comment_too_long": "댓글이 너무 깁니다. <1>여기를 클릭하십시오 전체 텍스트를 보려면.", + "replies_omitted": "{{repliesCount}}개의 답글이 생략되었습니다. <1>여기를 클릭하십시오 보려면.", + "replies_and_links_omitted": "{{repliesCount}}개의 답글과 {{linksCount}}개의 링크가 생략되었습니다. <1>여기를 클릭하십시오 보려면.", + "thread_closed_alert": "이 스레드는 닫혔습니다" } \ No newline at end of file diff --git a/public/translations/mr/default.json b/public/translations/mr/default.json index 4350e851..5fd9161b 100644 --- a/public/translations/mr/default.json +++ b/public/translations/mr/default.json @@ -48,5 +48,16 @@ "name": "नाव", "comment": "टिप्पणी", "subject": "विषय", - "anonymous": "अनाम" + "anonymous": "अनाम", + "image": "चित्र", + "video": "व्हिडिओ", + "audio": "ऑडिओ", + "webpage": "वेबपेज", + "iframe": "आयफ्रेम", + "rules": "नियम", + "welcome_to_board": "{{board}} वर आपले स्वागत आहे", + "comment_too_long": "टिप्पणी खूप लांब आहे. <1>पूर्ण मजकूर पाहण्यासाठी येथे क्लिक करा.", + "replies_omitted": "{{repliesCount}} प्रतिसाद वगळले गेले आहेत. <1>पाहण्यासाठी येथे क्लिक करा.", + "replies_and_links_omitted": "{{repliesCount}} प्रतिसाद आणि {{linksCount}} दुवे वगळले गेले आहेत. <1>पाहण्यासाठी येथे क्लिक करा.", + "thread_closed_alert": "हा थ्रेड बंद आहे" } \ No newline at end of file diff --git a/public/translations/nl/default.json b/public/translations/nl/default.json index a37f56d4..cb43cd2b 100644 --- a/public/translations/nl/default.json +++ b/public/translations/nl/default.json @@ -48,5 +48,16 @@ "name": "naam", "comment": "opmerking", "subject": "onderwerp", - "anonymous": "anoniem" + "anonymous": "anoniem", + "image": "afbeelding", + "video": "video", + "audio": "audio", + "webpage": "webpagina", + "iframe": "iframe", + "rules": "regels", + "welcome_to_board": "Welkom bij {{board}}", + "comment_too_long": "Reactie te lang. <1>Klik hier om de volledige tekst te bekijken.", + "replies_omitted": "{{repliesCount}} reacties weggelaten. <1>Klik hier om ze te bekijken.", + "replies_and_links_omitted": "{{repliesCount}} reacties en {{linksCount}} links weggelaten. <1>Klik hier om ze te bekijken.", + "thread_closed_alert": "De thread is gesloten" } \ No newline at end of file diff --git a/public/translations/no/default.json b/public/translations/no/default.json index 0a895739..99306ad1 100644 --- a/public/translations/no/default.json +++ b/public/translations/no/default.json @@ -48,5 +48,16 @@ "name": "navn", "comment": "kommentar", "subject": "emne", - "anonymous": "anonym" + "anonymous": "anonym", + "image": "bilde", + "video": "video", + "audio": "lyd", + "webpage": "nettside", + "iframe": "iframe", + "rules": "regler", + "welcome_to_board": "Velkommen til {{board}}", + "comment_too_long": "Kommentaren er for lang. <1>Klikk her for å se hele teksten.", + "replies_omitted": "{{repliesCount}} svar utelatt. <1>Klikk her for å se dem.", + "replies_and_links_omitted": "{{repliesCount}} svar og {{linksCount}} lenker utelatt. <1>Klikk her for å se dem.", + "thread_closed_alert": "Tråden er stengt" } \ No newline at end of file diff --git a/public/translations/pl/default.json b/public/translations/pl/default.json index 72149964..4a3adcf9 100644 --- a/public/translations/pl/default.json +++ b/public/translations/pl/default.json @@ -48,5 +48,16 @@ "name": "nazwa", "comment": "komentarz", "subject": "temat", - "anonymous": "anonimowy" + "anonymous": "anonimowy", + "image": "obraz", + "video": "wideo", + "audio": "audio", + "webpage": "strona internetowa", + "iframe": "iframe", + "rules": "zasady", + "welcome_to_board": "Witaj na {{board}}", + "comment_too_long": "Komentarz jest za długi. <1>Kliknij tutaj, aby zobaczyć pełny tekst.", + "replies_omitted": "Pominięto {{repliesCount}} odpowiedzi. <1>Kliknij tutaj, aby je zobaczyć.", + "replies_and_links_omitted": "Pominięto {{repliesCount}} odpowiedzi i {{linksCount}} linków. <1>Kliknij tutaj, aby je zobaczyć.", + "thread_closed_alert": "Wątek jest zamknięty" } \ No newline at end of file diff --git a/public/translations/pt/default.json b/public/translations/pt/default.json index f6ab14ae..cab2ba50 100644 --- a/public/translations/pt/default.json +++ b/public/translations/pt/default.json @@ -48,5 +48,16 @@ "name": "nome", "comment": "comentário", "subject": "assunto", - "anonymous": "anônimo" + "anonymous": "anônimo", + "image": "imagem", + "video": "vídeo", + "audio": "áudio", + "webpage": "página da web", + "iframe": "iframe", + "rules": "regras", + "welcome_to_board": "Bem-vindo ao {{board}}", + "comment_too_long": "Comentário muito longo. <1>Clique aqui para ver o texto completo.", + "replies_omitted": "{{repliesCount}} respostas omitidas. <1>Clique aqui para visualizar.", + "replies_and_links_omitted": "{{repliesCount}} respostas e {{linksCount}} links omitidos. <1>Clique aqui para visualizar.", + "thread_closed_alert": "O tópico está fechado" } \ No newline at end of file diff --git a/public/translations/ro/default.json b/public/translations/ro/default.json index 7d13dd9f..d5a8947c 100644 --- a/public/translations/ro/default.json +++ b/public/translations/ro/default.json @@ -48,5 +48,16 @@ "name": "nume", "comment": "comentariu", "subject": "subiect", - "anonymous": "anonim" + "anonymous": "anonim", + "image": "imagine", + "video": "video", + "audio": "audio", + "webpage": "pagină web", + "iframe": "iframe", + "rules": "reguli", + "welcome_to_board": "Bine ați venit la {{board}}", + "comment_too_long": "Comentariul este prea lung. <1>Click aici pentru a vedea textul complet.", + "replies_omitted": "{{repliesCount}} răspunsuri omise. <1>Click aici pentru a le vizualiza.", + "replies_and_links_omitted": "{{repliesCount}} răspunsuri și {{linksCount}} linkuri omise. <1>Click aici pentru a le vizualiza.", + "thread_closed_alert": "Acest fir de discuție este închis" } \ No newline at end of file diff --git a/public/translations/ru/default.json b/public/translations/ru/default.json index 7bec8b63..9171d56f 100644 --- a/public/translations/ru/default.json +++ b/public/translations/ru/default.json @@ -48,5 +48,16 @@ "name": "имя", "comment": "комментарий", "subject": "тема", - "anonymous": "анонимный" + "anonymous": "анонимный", + "image": "изображение", + "video": "видео", + "audio": "аудио", + "webpage": "веб-страница", + "iframe": "iframe", + "rules": "правила", + "welcome_to_board": "Добро пожаловать на {{board}}", + "comment_too_long": "Комментарий слишком длинный. <1>Нажмите здесь, чтобы прочитать полный текст.", + "replies_omitted": "{{repliesCount}} ответов пропущено. <1>Нажмите здесь, чтобы посмотреть.", + "replies_and_links_omitted": "{{repliesCount}} ответов и {{linksCount}} ссылок пропущено. <1>Нажмите здесь, чтобы посмотреть.", + "thread_closed_alert": "Тема закрыта" } \ No newline at end of file diff --git a/public/translations/sq/default.json b/public/translations/sq/default.json index 2ac55e2f..646956d8 100644 --- a/public/translations/sq/default.json +++ b/public/translations/sq/default.json @@ -48,5 +48,16 @@ "name": "emri", "comment": "koment", "subject": "subjekt", - "anonymous": "anonim" + "anonymous": "anonim", + "image": "imazh", + "video": "video", + "audio": "audio", + "webpage": "faqja web", + "iframe": "iframe", + "rules": "rregullat", + "welcome_to_board": "Mirë se vini te {{board}}", + "comment_too_long": "Komenti është shumë i gjatë. <1>Kliko këtu për të parë tekstin e plotë.", + "replies_omitted": "{{repliesCount}} përgjigje janë lënë jashtë. <1>Kliko këtu për t'i shikuar.", + "replies_and_links_omitted": "{{repliesCount}} përgjigje dhe {{linksCount}} lidhje janë lënë jashtë. <1>Kliko këtu për t'i shikuar.", + "thread_closed_alert": "Temë është mbyllur" } \ No newline at end of file diff --git a/public/translations/sv/default.json b/public/translations/sv/default.json index d8878260..f4ae4592 100644 --- a/public/translations/sv/default.json +++ b/public/translations/sv/default.json @@ -48,5 +48,16 @@ "name": "namn", "comment": "kommentar", "subject": "ämne", - "anonymous": "anonym" + "anonymous": "anonym", + "image": "bild", + "video": "video", + "audio": "ljud", + "webpage": "webbsida", + "iframe": "iframe", + "rules": "regler", + "welcome_to_board": "Välkommen till {{board}}", + "comment_too_long": "Kommentaren är för lång. <1>Klicka här för att se hela texten.", + "replies_omitted": "{{repliesCount}} svar utelämnade. <1>Klicka här för att visa dem.", + "replies_and_links_omitted": "{{repliesCount}} svar och {{linksCount}} länkar utelämnade. <1>Klicka här för att visa dem.", + "thread_closed_alert": "Tråden är stängd" } \ No newline at end of file diff --git a/public/translations/te/default.json b/public/translations/te/default.json index 389768f2..aa4eabea 100644 --- a/public/translations/te/default.json +++ b/public/translations/te/default.json @@ -48,5 +48,16 @@ "name": "పేరు", "comment": "వ్యాఖ్య", "subject": "విషయం", - "anonymous": "అనామధుడు" + "anonymous": "అనామధుడు", + "image": "చిత్రం", + "video": "వీడియో", + "audio": "ఆడియో", + "webpage": "వెబ్ పేజీ", + "iframe": "iframe", + "rules": "నియమాలు", + "welcome_to_board": "{{board}} కు స్వాగతం", + "comment_too_long": "వ్యాఖ్య చాలా పొడవుగా ఉంది. <1>పూర్తి టెక్స్ట్ చూడటానికి ఇక్కడ క్లిక్ చేయండి.", + "replies_omitted": "{{repliesCount}} స్పందనలు వదిలివేయబడ్డాయి. <1>చూడటానికి ఇక్కడ క్లిక్ చేయండి.", + "replies_and_links_omitted": "{{repliesCount}} స్పందనలు మరియు {{linksCount}} లింకులు వదిలివేయబడ్డాయి. <1>చూడటానికి ఇక్కడ క్లిక్ చేయండి.", + "thread_closed_alert": "ఈ థ్రెడ్ మూసివేయబడింది" } \ No newline at end of file diff --git a/public/translations/th/default.json b/public/translations/th/default.json index ef2450b0..f04ae435 100644 --- a/public/translations/th/default.json +++ b/public/translations/th/default.json @@ -48,5 +48,16 @@ "name": "ชื่อ", "comment": "ความคิดเห็น", "subject": "หัวข้อ", - "anonymous": "นิรนาม" + "anonymous": "นิรนาม", + "image": "ภาพ", + "video": "วิดีโอ", + "audio": "เสียง", + "webpage": "หน้าเว็บ", + "iframe": "iframe", + "rules": "กฎ", + "welcome_to_board": "ยินดีต้อนรับสู่ {{board}}", + "comment_too_long": "ความคิดเห็นยาวเกินไป <1>คลิกที่นี่ เพื่อดูข้อความเต็ม.", + "replies_omitted": "ข้าม {{repliesCount}} คำตอบ <1>คลิกที่นี่ เพื่อดู.", + "replies_and_links_omitted": "ข้าม {{repliesCount}} คำตอบและ {{linksCount}} ลิงก์ <1>คลิกที่นี่ เพื่อดู.", + "thread_closed_alert": "กระทู้นี้ถูกปิด" } \ No newline at end of file diff --git a/public/translations/tr/default.json b/public/translations/tr/default.json index 181c8c48..01ea8901 100644 --- a/public/translations/tr/default.json +++ b/public/translations/tr/default.json @@ -48,5 +48,16 @@ "name": "isim", "comment": "yorum", "subject": "konu", - "anonymous": "anonim" + "anonymous": "anonim", + "image": "görüntü", + "video": "video", + "audio": "ses", + "webpage": "web sayfası", + "iframe": "iframe", + "rules": "kurallar", + "welcome_to_board": "{{board}}'a hoş geldiniz", + "comment_too_long": "Yorum çok uzun. <1>Buraya tıklayın tam metni görüntülemek için.", + "replies_omitted": "{{repliesCount}} yanıt göz ardı edildi. <1>Buraya tıklayın görüntülemek için.", + "replies_and_links_omitted": "{{repliesCount}} yanıt ve {{linksCount}} bağlantı göz ardı edildi. <1>Buraya tıklayın görüntülemek için.", + "thread_closed_alert": "Bu konu kapatılmıştır" } \ No newline at end of file diff --git a/public/translations/uk/default.json b/public/translations/uk/default.json index a4d628d3..00ccd4a2 100644 --- a/public/translations/uk/default.json +++ b/public/translations/uk/default.json @@ -48,5 +48,16 @@ "name": "ім'я", "comment": "коментар", "subject": "тема", - "anonymous": "анонім" + "anonymous": "анонім", + "image": "зображення", + "video": "відео", + "audio": "аудіо", + "webpage": "веб-сторінка", + "iframe": "iframe", + "rules": "правила", + "welcome_to_board": "Ласкаво просимо до {{board}}", + "comment_too_long": "Коментар занадто довгий. <1>Натисніть тут, щоб переглянути повний текст.", + "replies_omitted": "{{repliesCount}} відповідей пропущено. <1>Натисніть тут, щоб переглянути.", + "replies_and_links_omitted": "{{repliesCount}} відповідей та {{linksCount}} посилань пропущено. <1>Натисніть тут, щоб переглянути.", + "thread_closed_alert": "Тему закрито" } \ No newline at end of file diff --git a/public/translations/ur/default.json b/public/translations/ur/default.json index 83c35fd3..2a62c06a 100644 --- a/public/translations/ur/default.json +++ b/public/translations/ur/default.json @@ -48,5 +48,16 @@ "name": "نام", "comment": "تبصرہ", "subject": "موضوع", - "anonymous": "ناشناس" + "anonymous": "ناشناس", + "image": "تصویر", + "video": "ویڈیو", + "audio": "آڈیو", + "webpage": "ویب پیج", + "iframe": "آئی فریم", + "rules": "اصول", + "welcome_to_board": "{{board}} میں خوش آمدید", + "comment_too_long": "تبصرہ بہت طویل ہے۔ <1>مکمل متن دیکھنے کے لیے یہاں کلک کریں۔", + "replies_omitted": "{{repliesCount}} جوابات چھوڑ دیے گئے ہیں۔ <1>مکمل دیکھنے کے لیے یہاں کلک کریں۔", + "replies_and_links_omitted": "{{repliesCount}} جوابات اور {{linksCount}} لنکس چھوڑ دیے گئے ہیں۔ <1>مکمل دیکھنے کے لیے یہاں کلک کریں۔", + "thread_closed_alert": "یہ دھاگہ بند ہے" } \ No newline at end of file diff --git a/public/translations/vi/default.json b/public/translations/vi/default.json index 43b2ede6..f49d5b95 100644 --- a/public/translations/vi/default.json +++ b/public/translations/vi/default.json @@ -48,5 +48,16 @@ "name": "tên", "comment": "bình luận", "subject": "chủ đề", - "anonymous": "ẩn danh" + "anonymous": "ẩn danh", + "image": "hình ảnh", + "video": "video", + "audio": "âm thanh", + "webpage": "trang web", + "iframe": "iframe", + "rules": "quy tắc", + "welcome_to_board": "Chào mừng bạn đến với {{board}}", + "comment_too_long": "Bình luận quá dài. <1>Nhấn vào đây để xem toàn bộ văn bản.", + "replies_omitted": "{{repliesCount}} câu trả lời bị bỏ qua. <1>Nhấn vào đây để xem.", + "replies_and_links_omitted": "{{repliesCount}} câu trả lời và {{linksCount}} liên kết bị bỏ qua. <1>Nhấn vào đây để xem.", + "thread_closed_alert": "Chủ đề này đã đóng" } \ No newline at end of file diff --git a/public/translations/zh/default.json b/public/translations/zh/default.json index 0d1f1349..18f22749 100644 --- a/public/translations/zh/default.json +++ b/public/translations/zh/default.json @@ -48,5 +48,16 @@ "name": "名字", "comment": "评论", "subject": "主题", - "anonymous": "匿名" + "anonymous": "匿名", + "image": "图片", + "video": "视频", + "audio": "音频", + "webpage": "网页", + "iframe": "框架", + "rules": "规则", + "welcome_to_board": "欢迎来到{{board}}", + "comment_too_long": "评论太长。 <1>点击这里查看完整文本。", + "replies_omitted": "省略了{{repliesCount}}条回复。 <1>点击这里查看。", + "replies_and_links_omitted": "省略了{{repliesCount}}条回复和{{linksCount}}个链接。 <1>点击这里查看。", + "thread_closed_alert": "该主题已关闭" } \ No newline at end of file diff --git a/src/components/board-buttons/board-buttons.tsx b/src/components/board-buttons/board-buttons.tsx index 4ff050ce..04aac440 100644 --- a/src/components/board-buttons/board-buttons.tsx +++ b/src/components/board-buttons/board-buttons.tsx @@ -58,6 +58,7 @@ export const MobileBoardButtons = () => { const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const isInPostPage = isPostPageView(location.pathname, params); + const isInCatalogView = isCatalogView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params); return ( @@ -75,7 +76,7 @@ export const MobileBoardButtons = () => { ) : ( <> - + )} @@ -97,7 +98,7 @@ export const DesktopBoardButtons = () => {
{isInPostPage || isInPendingPostPage ? ( <> - [] [] [] [ + [] [] [] [ ] [] diff --git a/src/components/challenge-modal/challenge-modal.module.css b/src/components/challenge-modal/challenge-modal.module.css index e46f9186..64a25b19 100644 --- a/src/components/challenge-modal/challenge-modal.module.css +++ b/src/components/challenge-modal/challenge-modal.module.css @@ -74,7 +74,6 @@ } .challengeFooter button { - margin: 5px 5px 0 0; cursor: pointer; filter: var(--filter80); text-transform: capitalize; diff --git a/src/components/challenge-modal/challenge-modal.tsx b/src/components/challenge-modal/challenge-modal.tsx index 569647be..ea8c2f33 100644 --- a/src/components/challenge-modal/challenge-modal.tsx +++ b/src/components/challenge-modal/challenge-modal.tsx @@ -1,10 +1,11 @@ -import { useState } from 'react'; +import { useRef, useState } from 'react'; import Draggable from 'react-draggable'; import { useTranslation } from 'react-i18next'; import { Challenge as ChallengeType } from '@plebbit/plebbit-react-hooks'; import { getPublicationType } from '../../lib/utils/challenge-utils'; import useChallenges from '../../hooks/use-challenges'; import styles from './challenge-modal.module.css'; +import _ from 'lodash'; interface ChallengeProps { challenge: ChallengeType; @@ -50,16 +51,19 @@ const Challenge = ({ challenge, closeModal }: ChallengeProps) => { } }; + // react-draggable requires a ref to the modal node + const nodeRef = useRef(null); + return ( - -
+ +
Challenge for {publicationType}
- +
{title && (
diff --git a/src/components/comment-media/comment-media.tsx b/src/components/comment-media/comment-media.tsx index 899ca88f..55ec8e76 100644 --- a/src/components/comment-media/comment-media.tsx +++ b/src/components/comment-media/comment-media.tsx @@ -1,11 +1,11 @@ import React from 'react'; -import styles from './comment-media.module.css'; -import { CommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils'; -import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; -import Embed, { canEmbed } from '../embed'; import { useTranslation } from 'react-i18next'; -import useWindowWidth from '../../hooks/use-window-width'; +import styles from './comment-media.module.css'; +import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../lib/utils/media-utils'; import { getHostname } from '../../lib/utils/url-utils'; +import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; +import useWindowWidth from '../../hooks/use-window-width'; +import Embed, { canEmbed } from '../embed'; interface MediaProps { commentMediaInfo?: CommentMediaInfo; @@ -129,7 +129,7 @@ const Media = ({ commentMediaInfo, isReply, setShowThumbnail }: MediaProps) => { {url && url.length > 30 ? url.slice(0, 30) + '...' : url} {' '} - ({type}) + ({getDisplayMediaInfoType(type, t)})
)} {isMobile && (type === 'iframe' || type === 'video' || type === 'audio') && ( @@ -144,8 +144,10 @@ const Media = ({ commentMediaInfo, isReply, setShowThumbnail }: MediaProps) => { }; const CommentMedia = ({ commentMediaInfo, isOutOfFeed, isReply, linkHeight, linkWidth, showThumbnail, setShowThumbnail }: MediaProps) => { + const { t } = useTranslation(); const isMobile = useWindowWidth() < 640; const { type, url } = commentMediaInfo || {}; + return ( @@ -160,7 +162,7 @@ const CommentMedia = ({ commentMediaInfo, isOutOfFeed, isReply, linkHeight, link setShowThumbnail={setShowThumbnail} /> )} - {isMobile && type &&
{type}
} + {isMobile && type &&
{getDisplayMediaInfoType(type, t)}
}
{!showThumbnail && }
diff --git a/src/components/loading-ellipsis/loading-ellipsis.module.css b/src/components/loading-ellipsis/loading-ellipsis.module.css index 69049ce1..d840bd8e 100644 --- a/src/components/loading-ellipsis/loading-ellipsis.module.css +++ b/src/components/loading-ellipsis/loading-ellipsis.module.css @@ -1,24 +1,22 @@ -.ellipsis { - display: inline-block; -} - .ellipsis:after { - content: '...'; - position: absolute; - -webkit-animation: ellipsis steps(4, end) 1200ms infinite; - animation: ellipsis steps(4, end) 1500ms infinite; - width: 0px; overflow: hidden; + display: inline-block; + position: absolute; + vertical-align: bottom; + -webkit-animation: ellipsis steps(4,end) 1500ms infinite; + animation: ellipsis steps(4,end) 1500ms infinite; + content: "\2026"; /* ascii code for the ellipsis character */ + width: 0px; } @keyframes ellipsis { to { - width: 1.3em; + width: 1.25em; } } @-webkit-keyframes ellipsis { to { - width: 1.3em; + width: 1.25em; } } \ No newline at end of file diff --git a/src/components/post/post.tsx b/src/components/post/post.tsx index ff426650..ec5ce85d 100644 --- a/src/components/post/post.tsx +++ b/src/components/post/post.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { Link, useLocation, useParams } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; -import { Role, useSubplebbit } from '@plebbit/plebbit-react-hooks'; +import { Trans, useTranslation } from 'react-i18next'; +import { Role, useAccount, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils'; import { getFormattedDate } from '../../lib/utils/time-utils'; @@ -11,10 +11,12 @@ import useReplies from '../../hooks/use-replies'; import useStateString from '../../hooks/use-state-string'; import useWindowWidth from '../../hooks/use-window-width'; import styles from './post.module.css'; -import LoadingEllipsis from '../loading-ellipsis'; -import Markdown from '../markdown'; import CommentMedia from '../comment-media'; import { canEmbed } from '../embed'; +import LoadingEllipsis from '../loading-ellipsis'; +import Markdown from '../markdown'; +import _ from 'lodash'; +import { getDisplayMediaInfoType } from '../../lib/utils/media-utils'; interface PostProps { index?: number; @@ -22,9 +24,10 @@ interface PostProps { reply?: any; roles?: Role[]; showAllReplies?: boolean; + openReplyModal?: (cid: string) => void; } -const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { +const PostDesktop = ({ openReplyModal, post, roles, showAllReplies }: PostProps) => { const { t } = useTranslation(); const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, postCid, replyCount, shortCid, state, subplebbitAddress, timestamp, title } = post || {}; const { address, displayName, shortAddress } = author || {}; @@ -46,13 +49,17 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { const [showThumbnail, setShowThumbnail] = useState(true); const replies = useReplies(post); - const visibleLinkCount = useCountLinksInReplies(post, 5); - const totalLinkCount = useCountLinksInReplies(post); + const visiblelinksCount = useCountLinksInReplies(post, 5); + const totallinksCount = useCountLinksInReplies(post); const repliesCount = pinned ? replyCount : replyCount - 5; - const linkCount = pinned ? totalLinkCount : totalLinkCount - visibleLinkCount; + const linksCount = pinned ? totallinksCount : totallinksCount - visiblelinksCount; const [menuBtnRotated, setMenuBtnRotated] = useState(false); + // pending reply by account is not yet published + const account = useAccount(); + const accountShortAddress = account?.author?.shortAddress; + return (
@@ -70,7 +77,7 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { {url.length > 30 ? url.slice(0, 30) + '...' : url} {' '} - ({type}) + ({type && getDisplayMediaInfoType(type, t)}) {!showThumbnail && (type === 'iframe' || type === 'video' || type === 'audio') && ( {' '} @@ -112,10 +119,10 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { {title && {displayTitle} } - {displayName || 'Anonymous'} + {displayName || _.capitalize(t('anonymous'))} {authorRole && ` ## Board ${authorRole}`}{' '} - {!(isDescription || isRules) && (u/{shortAddress}) } + {!(isDescription || isRules) && (u/{shortAddress || accountShortAddress}) } {getFormattedDate(timestamp)} @@ -124,13 +131,13 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { {!(isDescription || isRules) && ( - !cid && e.preventDefault()}> + !cid && e.preventDefault()}> c/ {!cid ? ( {state === 'failed' ? 'Failed' : 'Pending'} ) : ( - + openReplyModal && openReplyModal(cid)}> {shortCid} )} @@ -168,7 +175,7 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { {content.length > 1000 && !isInPostPage && (
- Comment too long. Click here to view the full text. + }} />
)} @@ -178,24 +185,30 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { - - {repliesCount} replies {linkCount > 0 && `and ${linkCount} links`} omitted.{' '} - - Click here to view. + {linksCount > 0 ? ( + }} + values={{ repliesCount, linksCount }} + /> + ) : ( + }} values={{ repliesCount }} /> + )} )} {!(pinned && !isInPostPage) && replies && (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => ( -
- +
+
))}
); }; -const ReplyDesktop = ({ reply, roles }: PostProps) => { +const ReplyDesktop = ({ reply, roles, openReplyModal }: PostProps) => { const { t } = useTranslation(); const { author, cid, content, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, state, subplebbitAddress, timestamp } = reply || {}; const { address, displayName, shortAddress } = author || {}; @@ -216,6 +229,10 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => {
{stateString !== 'Failed' ? : stateString}
); + // pending reply by account is not yet published + const account = useAccount(); + const accountShortAddress = account?.author?.shortAddress; + return (
{'>>'}
@@ -226,21 +243,21 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => { - {displayName || 'Anonymous'} + {displayName || _.capitalize(t('anonymous'))} {authorRole && ` ## Board ${authorRole}`}{' '} - (u/{shortAddress}) + (u/{shortAddress || accountShortAddress}) {getFormattedDate(timestamp)} - !cid && e.preventDefault()}> + !cid && e.preventDefault()}> c/ {!cid ? ( {state === 'failed' ? 'Failed' : 'Pending'} ) : ( - + openReplyModal && openReplyModal(cid)}> {shortCid} )} @@ -268,7 +285,8 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => { {t('link')}:{' '} {link.length > 30 ? link?.slice(0, 30) + '...' : link} - + {' '} + ({type && getDisplayMediaInfoType(type, t)}) {!showThumbnail && (type === 'iframe' || type === 'video' || type === 'audio') && ( {' '} @@ -313,7 +331,7 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => { )} - {!cid && ( + {!cid && state === 'pending' && ( <>
{loadingString} @@ -326,7 +344,7 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => { ); }; -const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { +const PostMobile = ({ openReplyModal, post, roles, showAllReplies }: PostProps) => { const { t } = useTranslation(); const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, replyCount, shortCid, state, subplebbitAddress, timestamp, title } = post || {}; const { address, displayName, shortAddress } = author || {}; @@ -338,7 +356,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { const location = useLocation(); const isInPostPage = isPostPageView(location.pathname, params); - const linkCount = useCountLinksInReplies(post); + const linksCount = useCountLinksInReplies(post); const displayTitle = title && title.length > 30 ? title?.slice(0, 30) + '(...)' : title; const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) : content; @@ -348,6 +366,10 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { const replies = useReplies(post); + // pending reply by account is not yet published + const account = useAccount(); + const accountShortAddress = account?.author?.shortAddress; + return (
@@ -362,10 +384,10 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { - {displayName || 'Anonymous'} + {displayName || _.capitalize(t('anonymous'))} {authorRole && ` ## Board ${authorRole}`}{' '} - {!(isDescription || isRules) && (u/{shortAddress || address?.slice(0, 12) + '...'})} + {!(isDescription || isRules) && (u/{shortAddress || accountShortAddress})} {pinned && ( @@ -393,7 +415,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { {!cid ? ( {state === 'failed' ? 'Failed' : 'Pending'} ) : ( - + openReplyModal && openReplyModal(cid)}> {shortCid} )} @@ -418,7 +440,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { {content.length > 1000 && !isInPostPage && (
- Comment too long. Click here to view the full text. + }} />
)} @@ -428,7 +450,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => {
{replyCount > 0 && `${replyCount} Replies`} - {linkCount > 0 && ` / ${linkCount} Links`} + {linksCount > 0 && ` / ${linksCount} Links`} {t('view_thread')} @@ -440,7 +462,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { replies && (showAllReplies ? replies : replies.slice(-5)).map((reply, index) => (
- +
))}
@@ -448,7 +470,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { ); }; -const ReplyMobile = ({ reply, roles }: PostProps) => { +const ReplyMobile = ({ reply, roles, openReplyModal }: PostProps) => { const { t } = useTranslation(); const { author, content, cid, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, state, subplebbitAddress, timestamp } = reply || {}; const { address, displayName, shortAddress } = author || {}; @@ -460,6 +482,15 @@ const ReplyMobile = ({ reply, roles }: PostProps) => { const isReplyingToReply = postCid !== parentCid; + // pending reply by account is not yet published + const account = useAccount(); + const accountShortAddress = account?.author?.shortAddress; + + const stateString = useStateString(reply); + const loadingString = stateString && ( +
{stateString !== 'Failed' ? : stateString}
+ ); + return (
@@ -468,10 +499,10 @@ const ReplyMobile = ({ reply, roles }: PostProps) => { ... - {displayName || 'Anonymous'} + {displayName || _.capitalize(t('anonymous'))} {authorRole && ` ## Board ${authorRole}`}{' '} - (u/{shortAddress}) + (u/{shortAddress || accountShortAddress}) {pinned && ( @@ -488,7 +519,7 @@ const ReplyMobile = ({ reply, roles }: PostProps) => { {!cid ? ( {state === 'failed' ? 'Failed' : 'Pending'} ) : ( - + openReplyModal && openReplyModal(cid)}> {shortCid} )} @@ -515,6 +546,12 @@ const ReplyMobile = ({ reply, roles }: PostProps) => { )} + {!cid && state === 'pending' && ( + <> +
+ {loadingString} + + )} )}
@@ -523,16 +560,17 @@ const ReplyMobile = ({ reply, roles }: PostProps) => { ); }; -const Post = ({ post, showAllReplies = false }: PostProps) => { +const Post = ({ post, showAllReplies = false, openReplyModal }: PostProps) => { const subplebbit = useSubplebbit({ subplebbitAddress: post?.subplebbitAddress }); const isMobile = useWindowWidth() < 640; + return (
{isMobile ? ( - + ) : ( - + )}
diff --git a/src/components/reply-modal/index.ts b/src/components/reply-modal/index.ts new file mode 100644 index 00000000..b6861856 --- /dev/null +++ b/src/components/reply-modal/index.ts @@ -0,0 +1 @@ +export { default } from './reply-modal'; diff --git a/src/components/reply-modal/reply-modal.module.css b/src/components/reply-modal/reply-modal.module.css new file mode 100644 index 00000000..5acd55f6 --- /dev/null +++ b/src/components/reply-modal/reply-modal.module.css @@ -0,0 +1,60 @@ +.container { + position: fixed; + top: calc(50% - 150px); + left: calc(50% - 150px); + display: block; + padding: 2px; + font-size: 10pt; + border-left: none; + border-top: none; + z-index: 1000; + background-color: var(--challenge-modal-background-color); + border: var(--challenge-modal-border); +} + +.title { + font-size: var(--challenge-modal-title-font-size); + text-align: center; + margin-bottom: 1px; + padding: 0; + height: 18px; + line-height: 18px; + cursor: move; + font-weight: var(--challenge-modal-title-font-weight); + background-color: var(--challenge-modal-title-background-color); + color: var(--challenge-modal-title-text-color); + border: var(--challenge-modal-title-border); +} + +.closeIcon { + all: unset; + float: right; + cursor: pointer; + margin-bottom: -4px; + width: 18px; + height: 18px; + border: none; + image-rendering: pixelated; + background-image: var(--close-button-background-image); +} + +.container input, .container textarea { + border: 1px solid #aaa; + font-family: Arial, Helvetica, sans-serif; + font-size: 10pt; + outline: medium none; + width: 298px; + filter: var(--filter80); + padding: 2px; + margin-bottom: 1px; +} + +.content textarea { + vertical-align: top; +} + +.footer button { + text-transform: capitalize; + float: right; + cursor: pointer; +} \ No newline at end of file diff --git a/src/components/reply-modal/reply-modal.tsx b/src/components/reply-modal/reply-modal.tsx new file mode 100644 index 00000000..eda69f8d --- /dev/null +++ b/src/components/reply-modal/reply-modal.tsx @@ -0,0 +1,80 @@ +import { useEffect, useRef } from 'react'; +import { useParams } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import Draggable from 'react-draggable'; +import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; +import { useAccount } from '@plebbit/plebbit-react-hooks'; +import { isValidURL } from '../../lib/utils/url-utils'; +import useReply from '../../hooks/use-reply'; +import styles from './reply-modal.module.css'; +import _ from 'lodash'; + +interface ReplyModalProps { + closeModal: () => void; + parentCid: string; +} + +const ReplyModal = ({ closeModal, parentCid }: ReplyModalProps) => { + const { t } = useTranslation(); + const { subplebbitAddress } = useParams() as { subplebbitAddress: string }; + const { setContent, resetContent, replyIndex, publishReply } = useReply({ cid: parentCid, subplebbitAddress }); + + const account = useAccount(); + const { displayName } = account?.author || {}; + + const textRef = useRef(null); + const urlRef = useRef(null); + + const onPublishReply = () => { + const currentContent = textRef.current?.value || ''; + const currentUrl = urlRef.current?.value || ''; + + if (!currentContent.trim() && !currentUrl) { + alert(`Cannot post empty comment`); + return; + } + + if (currentUrl && !isValidURL(currentUrl)) { + alert('The provided link is not a valid URL.'); + return; + } + publishReply(); + }; + + useEffect(() => { + if (typeof replyIndex === 'number') { + closeModal(); + resetContent(); + } + }, [replyIndex, resetContent, closeModal]); + + // react-draggable requires a ref to the modal node + const nodeRef = useRef(null); + + return ( + +
+
+ Reply to c/{parentCid && Plebbit.getShortCid(parentCid)} +
+
+
+ +
+
+ setContent.link(e.target.value)} /> +
+
+