Merge pull request #346 from plebbit/development

Development
This commit is contained in:
Tom (plebeius.eth)
2024-04-28 18:06:15 +02:00
committed by GitHub
52 changed files with 987 additions and 200 deletions
+1
View File
@@ -28,6 +28,7 @@
"prettier": "3.0.3", "prettier": "3.0.3",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-draggable": "^4.4.6",
"react-i18next": "13.2.2", "react-i18next": "13.2.2",
"react-markdown": "8.0.6", "react-markdown": "8.0.6",
"react-router-dom": "6.16.0", "react-router-dom": "6.16.0",
+1 -1
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta name="description" content="serverless, adminless, decentralized 4chan alternative" /> <meta name="description" content="serverless, adminless, decentralized 4chan alternative" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" />
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "الرد على هذه المشاركة", "reply_to_post": "الرد على هذه المشاركة",
"sticky": "مثبت", "sticky": "مثبت",
"closed": "مغلق", "closed": "مغلق",
"reply": "رد", "reply": "الرد",
"link": "رابط", "link": "رابط",
"close": "إغلاق", "close": "إغلاق",
"post_a_reply": "أضف ردًا", "post_a_reply": "أضف ردًا",
@@ -43,5 +43,10 @@
"bottom": "القاع", "bottom": "القاع",
"top": "أعلى", "top": "أعلى",
"thread_closed": "تم إغلاق الموضوع.", "thread_closed": "تم إغلاق الموضوع.",
"may_not_reply": "قد لا تتم الرد في هذا الوقت." "may_not_reply": "قد لا تتم الرد في هذا الوقت.",
"post": "نشر",
"name": "الاسم",
"comment": "تعليق",
"subject": "الموضوع",
"anonymous": "مجهول"
} }
+6 -1
View File
@@ -43,5 +43,10 @@
"bottom": "নীচে", "bottom": "নীচে",
"top": "শীর্ষ", "top": "শীর্ষ",
"thread_closed": "থ্রেড বন্ধ হয়েছে।", "thread_closed": "থ্রেড বন্ধ হয়েছে।",
"may_not_reply": "এই সময়ে আপনি প্রতিক্রিয়া দিতে পারবেন না।" "may_not_reply": "এই সময়ে আপনি প্রতিক্রিয়া দিতে পারবেন না।",
"post": "পোস্ট",
"name": "নাম",
"comment": "মন্তব্য",
"subject": "বিষয়",
"anonymous": "অজানা"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Odpovědět na tento příspěvek", "reply_to_post": "Odpovědět na tento příspěvek",
"sticky": "Připnutý", "sticky": "Připnutý",
"closed": "Zavřeno", "closed": "Zavřeno",
"reply": "Odpovědět", "reply": "odpovědět",
"link": "Odkaz", "link": "Odkaz",
"close": "Zavřít", "close": "Zavřít",
"post_a_reply": "Zveřejnit Odpověď", "post_a_reply": "Zveřejnit Odpověď",
@@ -43,5 +43,10 @@
"bottom": "Dno", "bottom": "Dno",
"top": "Nahoře", "top": "Nahoře",
"thread_closed": "Vlákno uzavřeno.", "thread_closed": "Vlákno uzavřeno.",
"may_not_reply": "V tuto chvíli nemůžete odpovědět." "may_not_reply": "V tuto chvíli nemůžete odpovědět.",
"post": "odeslat",
"name": "název",
"comment": "komentář",
"subject": "předmět",
"anonymous": "anonymní"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Svar på dette indlæg", "reply_to_post": "Svar på dette indlæg",
"sticky": "Fikseret", "sticky": "Fikseret",
"closed": "Lukket", "closed": "Lukket",
"reply": "Svar", "reply": "besvar",
"link": "Link", "link": "Link",
"close": "Luk", "close": "Luk",
"post_a_reply": "Indsend Et Svar", "post_a_reply": "Indsend Et Svar",
@@ -43,5 +43,10 @@
"bottom": "Bund", "bottom": "Bund",
"top": "Top", "top": "Top",
"thread_closed": "Tråd lukket.", "thread_closed": "Tråd lukket.",
"may_not_reply": "Du kan muligvis ikke svare på dette tidspunkt." "may_not_reply": "Du kan muligvis ikke svare på dette tidspunkt.",
"post": "send",
"name": "navn",
"comment": "kommentar",
"subject": "emne",
"anonymous": "anonym"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Antworten auf diesen Beitrag", "reply_to_post": "Antworten auf diesen Beitrag",
"sticky": "Angeheftet", "sticky": "Angeheftet",
"closed": "Geschlossen", "closed": "Geschlossen",
"reply": "Antworten", "reply": "antworten",
"link": "Link", "link": "Link",
"close": "Schließen", "close": "Schließen",
"post_a_reply": "Eine Antwort Posten", "post_a_reply": "Eine Antwort Posten",
@@ -43,5 +43,10 @@
"bottom": "Unten", "bottom": "Unten",
"top": "Oben", "top": "Oben",
"thread_closed": "Thread geschlossen.", "thread_closed": "Thread geschlossen.",
"may_not_reply": "Sie können möglicherweise zu diesem Zeitpunkt nicht antworten." "may_not_reply": "Sie können möglicherweise zu diesem Zeitpunkt nicht antworten.",
"post": "posten",
"name": "Name",
"comment": "Kommentar",
"subject": "Betreff",
"anonymous": "anonym"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Απάντηση σε αυτήν την ανάρτηση", "reply_to_post": "Απάντηση σε αυτήν την ανάρτηση",
"sticky": "Κολλημένος", "sticky": "Κολλημένος",
"closed": "Κλειστό", "closed": "Κλειστό",
"reply": "Απάντηση", "reply": "απάντηση",
"link": "Σύνδεσμος", "link": "Σύνδεσμος",
"close": "Κλείσιμο", "close": "Κλείσιμο",
"post_a_reply": "Δημοσίευση Απάντησης", "post_a_reply": "Δημοσίευση Απάντησης",
@@ -43,5 +43,10 @@
"bottom": "Κάτω", "bottom": "Κάτω",
"top": "Κορυφή", "top": "Κορυφή",
"thread_closed": "Το νήμα έκλεισε.", "thread_closed": "Το νήμα έκλεισε.",
"may_not_reply": "Μπορεί να μην μπορείτε να απαντήσετε αυτή τη στιγμή." "may_not_reply": "Μπορεί να μην μπορείτε να απαντήσετε αυτή τη στιγμή.",
"post": "δημοσίευση",
"name": "όνομα",
"comment": "σχόλιο",
"subject": "θέμα",
"anonymous": "ανώνυμος"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Reply to this post", "reply_to_post": "Reply to this post",
"sticky": "Sticky", "sticky": "Sticky",
"closed": "Closed", "closed": "Closed",
"reply": "Reply", "reply": "reply",
"link": "Link", "link": "Link",
"close": "Close", "close": "Close",
"post_a_reply": "Post a Reply", "post_a_reply": "Post a Reply",
@@ -43,5 +43,10 @@
"bottom": "Bottom", "bottom": "Bottom",
"top": "Top", "top": "Top",
"thread_closed": "Thread closed.", "thread_closed": "Thread closed.",
"may_not_reply": "You may not reply at this time." "may_not_reply": "You may not reply at this time.",
"post": "post",
"name": "name",
"comment": "comment",
"subject": "subject",
"anonymous": "anonymous"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Responder a esta publicación", "reply_to_post": "Responder a esta publicación",
"sticky": "Fijado", "sticky": "Fijado",
"closed": "Cerrado", "closed": "Cerrado",
"reply": "Responder", "reply": "responder",
"link": "Enlace", "link": "Enlace",
"close": "Cerrar", "close": "Cerrar",
"post_a_reply": "Publicar una Respuesta", "post_a_reply": "Publicar una Respuesta",
@@ -43,5 +43,10 @@
"bottom": "Fondo", "bottom": "Fondo",
"top": "Arriba", "top": "Arriba",
"thread_closed": "Hilo cerrado.", "thread_closed": "Hilo cerrado.",
"may_not_reply": "Es posible que no puedas responder en este momento." "may_not_reply": "Es posible que no puedas responder en este momento.",
"post": "publicar",
"name": "nombre",
"comment": "comentario",
"subject": "asunto",
"anonymous": "anónimo"
} }
+6 -1
View File
@@ -43,5 +43,10 @@
"bottom": "پایین", "bottom": "پایین",
"top": "بالا", "top": "بالا",
"thread_closed": "موضوع بسته شده است.", "thread_closed": "موضوع بسته شده است.",
"may_not_reply": "شما ممکن است در این زمان پاسخ ندهید." "may_not_reply": "شما ممکن است در این زمان پاسخ ندهید.",
"post": "پست",
"name": "نام",
"comment": "نظر",
"subject": "موضوع",
"anonymous": "ناشناس"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Vastaa tähän viestiin", "reply_to_post": "Vastaa tähän viestiin",
"sticky": "Tikki", "sticky": "Tikki",
"closed": "Suljettu", "closed": "Suljettu",
"reply": "Vastaa", "reply": "vastata",
"link": "Linkki", "link": "Linkki",
"close": "Sulje", "close": "Sulje",
"post_a_reply": "Lähetä Vastaus", "post_a_reply": "Lähetä Vastaus",
@@ -43,5 +43,10 @@
"bottom": "Pohja", "bottom": "Pohja",
"top": "Ylös", "top": "Ylös",
"thread_closed": "Keskustelu suljettu.", "thread_closed": "Keskustelu suljettu.",
"may_not_reply": "Et ehkä voi vastata tällä hetkellä." "may_not_reply": "Et ehkä voi vastata tällä hetkellä.",
"post": "lähetä",
"name": "nimi",
"comment": "kommentti",
"subject": "aihe",
"anonymous": "anonyymi"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Tumugon sa post na ito", "reply_to_post": "Tumugon sa post na ito",
"sticky": "Malagkit", "sticky": "Malagkit",
"closed": "Sarado", "closed": "Sarado",
"reply": "Tumugon", "reply": "sumagot",
"link": "Link", "link": "Link",
"close": "Isara", "close": "Isara",
"post_a_reply": "Mag-post ng Isang Tugon", "post_a_reply": "Mag-post ng Isang Tugon",
@@ -43,5 +43,10 @@
"bottom": "Ilalim", "bottom": "Ilalim",
"top": "Itaas", "top": "Itaas",
"thread_closed": "Thread na isara.", "thread_closed": "Thread na isara.",
"may_not_reply": "Hindi ka maaaring mag-reply sa oras na ito." "may_not_reply": "Hindi ka maaaring mag-reply sa oras na ito.",
"post": "mag-post",
"name": "pangalan",
"comment": "komento",
"subject": "paksa",
"anonymous": "anonimo"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Répondre à ce message", "reply_to_post": "Répondre à ce message",
"sticky": "Épinglé", "sticky": "Épinglé",
"closed": "Fermé", "closed": "Fermé",
"reply": "Répondre", "reply": "répondre",
"link": "Lien", "link": "Lien",
"close": "Fermer", "close": "Fermer",
"post_a_reply": "Publier une Réponse", "post_a_reply": "Publier une Réponse",
@@ -43,5 +43,10 @@
"bottom": "Bas", "bottom": "Bas",
"top": "Haut", "top": "Haut",
"thread_closed": "Fil fermé.", "thread_closed": "Fil fermé.",
"may_not_reply": "Vous ne pouvez peut-être pas répondre en ce moment." "may_not_reply": "Vous ne pouvez peut-être pas répondre en ce moment.",
"post": "poster",
"name": "nom",
"comment": "commentaire",
"subject": "sujet",
"anonymous": "anonyme"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "הגבה להודעה זו", "reply_to_post": "הגבה להודעה זו",
"sticky": "מדבקה", "sticky": "מדבקה",
"closed": "סגור", "closed": "סגור",
"reply": "הגב", "reply": "להגיב",
"link": "קישור", "link": "קישור",
"close": "סגור", "close": "סגור",
"post_a_reply": "פרסם תגובה", "post_a_reply": "פרסם תגובה",
@@ -43,5 +43,10 @@
"bottom": "תחתית", "bottom": "תחתית",
"top": "עליון", "top": "עליון",
"thread_closed": "השרשור נסגר.", "thread_closed": "השרשור נסגר.",
"may_not_reply": "אולי אינך יכול להגיב כרגע." "may_not_reply": "אולי אינך יכול להגיב כרגע.",
"post": "לפרסם",
"name": "שם",
"comment": "תגובה",
"subject": "נושא",
"anonymous": "אנונימי"
} }
+6 -1
View File
@@ -43,5 +43,10 @@
"bottom": "नीचे", "bottom": "नीचे",
"top": "ऊपर", "top": "ऊपर",
"thread_closed": "थ्रेड बंद हो गया।", "thread_closed": "थ्रेड बंद हो गया।",
"may_not_reply": "इस समय आप जवाब नहीं दे सकते।" "may_not_reply": "इस समय आप जवाब नहीं दे सकते।",
"post": "पोस्ट",
"name": "नाम",
"comment": "टिप्पणी",
"subject": "विषय",
"anonymous": "अनाम"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Válasz erre a hozzászólásra", "reply_to_post": "Válasz erre a hozzászólásra",
"sticky": "Rögzített", "sticky": "Rögzített",
"closed": "Zárt", "closed": "Zárt",
"reply": "Válaszolás", "reply": "válasz",
"link": "Hivatkozás", "link": "Hivatkozás",
"close": "Bezárás", "close": "Bezárás",
"post_a_reply": "Válasz Postázása", "post_a_reply": "Válasz Postázása",
@@ -43,5 +43,10 @@
"bottom": "Alja", "bottom": "Alja",
"top": "Felső", "top": "Felső",
"thread_closed": "A téma lezárult.", "thread_closed": "A téma lezárult.",
"may_not_reply": "Jelenleg nem válaszolhatsz erre." "may_not_reply": "Jelenleg nem válaszolhatsz erre.",
"post": "posta",
"name": "név",
"comment": "megjegyzés",
"subject": "tárgy",
"anonymous": "névtelen"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Balas ke pos ini", "reply_to_post": "Balas ke pos ini",
"sticky": "Menempel", "sticky": "Menempel",
"closed": "Tutup", "closed": "Tutup",
"reply": "Balas", "reply": "balas",
"link": "Tautan", "link": "Tautan",
"close": "Tutup", "close": "Tutup",
"post_a_reply": "Kirim Balasan", "post_a_reply": "Kirim Balasan",
@@ -43,5 +43,10 @@
"bottom": "Bawah", "bottom": "Bawah",
"top": "Atas", "top": "Atas",
"thread_closed": "Benang ditutup.", "thread_closed": "Benang ditutup.",
"may_not_reply": "Anda mungkin tidak bisa membalas pada saat ini." "may_not_reply": "Anda mungkin tidak bisa membalas pada saat ini.",
"post": "posting",
"name": "nama",
"comment": "komentar",
"subject": "subjek",
"anonymous": "anonim"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Commenta questo post", "reply_to_post": "Commenta questo post",
"sticky": "Incollato", "sticky": "Incollato",
"closed": "Chiuso", "closed": "Chiuso",
"reply": "Commenta", "reply": "rispondi",
"link": "Link", "link": "Link",
"close": "Chiudi", "close": "Chiudi",
"post_a_reply": "Invia un Commento", "post_a_reply": "Invia un Commento",
@@ -43,5 +43,10 @@
"bottom": "Vai sotto", "bottom": "Vai sotto",
"top": "Vai sopra", "top": "Vai sopra",
"thread_closed": "Thread chiuso.", "thread_closed": "Thread chiuso.",
"may_not_reply": "Non puoi rispondere in questo momento." "may_not_reply": "Non puoi rispondere in questo momento.",
"post": "invia",
"name": "nome",
"comment": "commento",
"subject": "oggetto",
"anonymous": "anonimo"
} }
+6 -1
View File
@@ -43,5 +43,10 @@
"bottom": "下へ", "bottom": "下へ",
"top": "上へ", "top": "上へ",
"thread_closed": "スレッドが閉じられました。", "thread_closed": "スレッドが閉じられました。",
"may_not_reply": "現在、返信することはできません。" "may_not_reply": "現在、返信することはできません。",
"post": "投稿",
"name": "名前",
"comment": "コメント",
"subject": "件名",
"anonymous": "匿名"
} }
+6 -1
View File
@@ -43,5 +43,10 @@
"bottom": "하단", "bottom": "하단",
"top": "맨 위로", "top": "맨 위로",
"thread_closed": "스레드가 닫혔습니다.", "thread_closed": "스레드가 닫혔습니다.",
"may_not_reply": "현재 시간에는 답글을 달 수 없습니다." "may_not_reply": "현재 시간에는 답글을 달 수 없습니다.",
"post": "게시",
"name": "이름",
"comment": "댓글",
"subject": "제목",
"anonymous": "익명"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "या पोस्टवर प्रतिसाद द्या", "reply_to_post": "या पोस्टवर प्रतिसाद द्या",
"sticky": "स्टिकी", "sticky": "स्टिकी",
"closed": "बंद", "closed": "बंद",
"reply": "प्रतिसाद", "reply": "प्रत्युत्तर",
"link": "लिंक", "link": "लिंक",
"close": "बंद करा", "close": "बंद करा",
"post_a_reply": "उत्तर पोस्ट करा", "post_a_reply": "उत्तर पोस्ट करा",
@@ -43,5 +43,10 @@
"bottom": "खाली", "bottom": "खाली",
"top": "वर", "top": "वर",
"thread_closed": "सूत्र बंद झाला.", "thread_closed": "सूत्र बंद झाला.",
"may_not_reply": "हा वेळ उत्तर देण्यास शक्य नाही." "may_not_reply": "हा वेळ उत्तर देण्यास शक्य नाही.",
"post": "पोस्ट",
"name": "नाव",
"comment": "टिप्पणी",
"subject": "विषय",
"anonymous": "अनाम"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Reageren op dit bericht", "reply_to_post": "Reageren op dit bericht",
"sticky": "Vastgemaakt", "sticky": "Vastgemaakt",
"closed": "Gesloten", "closed": "Gesloten",
"reply": "Antwoord", "reply": "antwoorden",
"link": "Link", "link": "Link",
"close": "Sluiten", "close": "Sluiten",
"post_a_reply": "Een Antwoord Plaatsen", "post_a_reply": "Een Antwoord Plaatsen",
@@ -43,5 +43,10 @@
"bottom": "Onderkant", "bottom": "Onderkant",
"top": "Boven", "top": "Boven",
"thread_closed": "Thread gesloten.", "thread_closed": "Thread gesloten.",
"may_not_reply": "U kunt op dit moment mogelijk niet antwoorden." "may_not_reply": "U kunt op dit moment mogelijk niet antwoorden.",
"post": "plaatsen",
"name": "naam",
"comment": "opmerking",
"subject": "onderwerp",
"anonymous": "anoniem"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Svar på dette innlegget", "reply_to_post": "Svar på dette innlegget",
"sticky": "Klistret", "sticky": "Klistret",
"closed": "Stengt", "closed": "Stengt",
"reply": "Svar", "reply": "svare",
"link": "Lenke", "link": "Lenke",
"close": "Lukk", "close": "Lukk",
"post_a_reply": "Legg Inn Et Svar", "post_a_reply": "Legg Inn Et Svar",
@@ -43,5 +43,10 @@
"bottom": "Bunnen", "bottom": "Bunnen",
"top": "Topp", "top": "Topp",
"thread_closed": "Tråd stengt.", "thread_closed": "Tråd stengt.",
"may_not_reply": "Du kan kanskje ikke svare på dette tidspunktet." "may_not_reply": "Du kan kanskje ikke svare på dette tidspunktet.",
"post": "poste",
"name": "navn",
"comment": "kommentar",
"subject": "emne",
"anonymous": "anonym"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Odpowiedz na ten post", "reply_to_post": "Odpowiedz na ten post",
"sticky": "Przyklejony", "sticky": "Przyklejony",
"closed": "Zamknięty", "closed": "Zamknięty",
"reply": "Odpowiedz", "reply": "odpowiedź",
"link": "Link", "link": "Link",
"close": "Zamknij", "close": "Zamknij",
"post_a_reply": "Opublikuj Odpowiedź", "post_a_reply": "Opublikuj Odpowiedź",
@@ -43,5 +43,10 @@
"bottom": "Dół", "bottom": "Dół",
"top": "Góra", "top": "Góra",
"thread_closed": "Wątek zamknięty.", "thread_closed": "Wątek zamknięty.",
"may_not_reply": "Może nie możesz teraz odpowiedzieć." "may_not_reply": "Może nie możesz teraz odpowiedzieć.",
"post": "postać",
"name": "nazwa",
"comment": "komentarz",
"subject": "temat",
"anonymous": "anonimowy"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Responder a esta postagem", "reply_to_post": "Responder a esta postagem",
"sticky": "Fixado", "sticky": "Fixado",
"closed": "Fechado", "closed": "Fechado",
"reply": "Responder", "reply": "responder",
"link": "Link", "link": "Link",
"close": "Fechar", "close": "Fechar",
"post_a_reply": "Publicar uma Resposta", "post_a_reply": "Publicar uma Resposta",
@@ -43,5 +43,10 @@
"bottom": "Fundo", "bottom": "Fundo",
"top": "Topo", "top": "Topo",
"thread_closed": "Tópico fechado.", "thread_closed": "Tópico fechado.",
"may_not_reply": "Você pode não conseguir responder neste momento." "may_not_reply": "Você pode não conseguir responder neste momento.",
"post": "postar",
"name": "nome",
"comment": "comentário",
"subject": "assunto",
"anonymous": "anônimo"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Răspunde la acest mesaj", "reply_to_post": "Răspunde la acest mesaj",
"sticky": "Lipit", "sticky": "Lipit",
"closed": "Închis", "closed": "Închis",
"reply": "Răspunde", "reply": "răspunde",
"link": "Legătură", "link": "Legătură",
"close": "Închide", "close": "Închide",
"post_a_reply": "Postează un Răspuns", "post_a_reply": "Postează un Răspuns",
@@ -43,5 +43,10 @@
"bottom": "Partea de jos", "bottom": "Partea de jos",
"top": "Sus", "top": "Sus",
"thread_closed": "Thread închis.", "thread_closed": "Thread închis.",
"may_not_reply": "Poate că nu puteți răspunde în acest moment." "may_not_reply": "Poate că nu puteți răspunde în acest moment.",
"post": "posta",
"name": "nume",
"comment": "comentariu",
"subject": "subiect",
"anonymous": "anonim"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Ответить на это сообщение", "reply_to_post": "Ответить на это сообщение",
"sticky": "Прикреплено", "sticky": "Прикреплено",
"closed": "Закрыто", "closed": "Закрыто",
"reply": "Ответить", "reply": "ответить",
"link": "Ссылка", "link": "Ссылка",
"close": "Закрыть", "close": "Закрыть",
"post_a_reply": "Опубликовать Ответ", "post_a_reply": "Опубликовать Ответ",
@@ -43,5 +43,10 @@
"bottom": "Низ", "bottom": "Низ",
"top": "Верх", "top": "Верх",
"thread_closed": "Тема закрыта.", "thread_closed": "Тема закрыта.",
"may_not_reply": "Вы можете не ответить в это время." "may_not_reply": "Вы можете не ответить в это время.",
"post": "разместить",
"name": "имя",
"comment": "комментарий",
"subject": "тема",
"anonymous": "анонимный"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Përgjigju në këtë postim", "reply_to_post": "Përgjigju në këtë postim",
"sticky": "Ngjitës", "sticky": "Ngjitës",
"closed": "Mbyllur", "closed": "Mbyllur",
"reply": "Përgjigju", "reply": "përgjigju",
"link": "Lidhje", "link": "Lidhje",
"close": "Mbylle", "close": "Mbylle",
"post_a_reply": "Posto një Përgjigje", "post_a_reply": "Posto një Përgjigje",
@@ -43,5 +43,10 @@
"bottom": "Fund", "bottom": "Fund",
"top": "Sipër", "top": "Sipër",
"thread_closed": "Fjala është e mbyllur.", "thread_closed": "Fjala është e mbyllur.",
"may_not_reply": "Nuk mund të përgjigjeni në këtë kohë." "may_not_reply": "Nuk mund të përgjigjeni në këtë kohë.",
"post": "postë",
"name": "emri",
"comment": "koment",
"subject": "subjekt",
"anonymous": "anonim"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Svara på detta inlägg", "reply_to_post": "Svara på detta inlägg",
"sticky": "Klistrad", "sticky": "Klistrad",
"closed": "Stängd", "closed": "Stängd",
"reply": "Svara", "reply": "svara",
"link": "Länk", "link": "Länk",
"close": "Stäng", "close": "Stäng",
"post_a_reply": "Posta Ett Svar", "post_a_reply": "Posta Ett Svar",
@@ -43,5 +43,10 @@
"bottom": "Botten", "bottom": "Botten",
"top": "Topp", "top": "Topp",
"thread_closed": "Tråd stängd.", "thread_closed": "Tråd stängd.",
"may_not_reply": "Du kanske inte kan svara vid den här tiden." "may_not_reply": "Du kanske inte kan svara vid den här tiden.",
"post": "skicka",
"name": "namn",
"comment": "kommentar",
"subject": "ämne",
"anonymous": "anonym"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "ఈ పోస్టుకు మరియుని జవాబు ఇవ్వండి", "reply_to_post": "ఈ పోస్టుకు మరియుని జవాబు ఇవ్వండి",
"sticky": "స్టికీ", "sticky": "స్టికీ",
"closed": "మూసివేయబడినది", "closed": "మూసివేయబడినది",
"reply": "స్పందించు", "reply": "సమాధానం",
"link": "లింక్", "link": "లింక్",
"close": "మూసి", "close": "మూసి",
"post_a_reply": "స్పందించండి", "post_a_reply": "స్పందించండి",
@@ -43,5 +43,10 @@
"bottom": "కిందకు", "bottom": "కిందకు",
"top": "మేలే", "top": "మేలే",
"thread_closed": "థ్రెడ్ మూసివేయబడింది.", "thread_closed": "థ్రెడ్ మూసివేయబడింది.",
"may_not_reply": "ఈ సమయంలో మీరు ప్రతిసారం ఇవ్వలేరు." "may_not_reply": "ఈ సమయంలో మీరు ప్రతిసారం ఇవ్వలేరు.",
"post": "పోస్ట్",
"name": "పేరు",
"comment": "వ్యాఖ్య",
"subject": "విషయం",
"anonymous": "అనామధుడు"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "ตอบกลับไปยังโพสต์นี้", "reply_to_post": "ตอบกลับไปยังโพสต์นี้",
"sticky": "ปักหมุด", "sticky": "ปักหมุด",
"closed": "ปิด", "closed": "ปิด",
"reply": "ตอบ", "reply": "ตอบกลับ",
"link": "ลิงก์", "link": "ลิงก์",
"close": "ปิด", "close": "ปิด",
"post_a_reply": "โพสต์คำตอบ", "post_a_reply": "โพสต์คำตอบ",
@@ -43,5 +43,10 @@
"bottom": "ด้านล่าง", "bottom": "ด้านล่าง",
"top": "ด้านบน", "top": "ด้านบน",
"thread_closed": "เธรดถูกปิด", "thread_closed": "เธรดถูกปิด",
"may_not_reply": "คุณอาจไม่สามารถตอบกลับได้ในขณะนี้" "may_not_reply": "คุณอาจไม่สามารถตอบกลับได้ในขณะนี้",
"post": "โพสต์",
"name": "ชื่อ",
"comment": "ความคิดเห็น",
"subject": "หัวข้อ",
"anonymous": "นิรนาม"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Bu gönderiye yanıtla", "reply_to_post": "Bu gönderiye yanıtla",
"sticky": "Yapışkan", "sticky": "Yapışkan",
"closed": "Kapalı", "closed": "Kapalı",
"reply": "Yanıtla", "reply": "yanıtla",
"link": "Bağlantı", "link": "Bağlantı",
"close": "Kapat", "close": "Kapat",
"post_a_reply": "Yanıtı Yayınla", "post_a_reply": "Yanıtı Yayınla",
@@ -43,5 +43,10 @@
"bottom": "Alt", "bottom": "Alt",
"top": "Üst", "top": "Üst",
"thread_closed": "Konu kapatıldı.", "thread_closed": "Konu kapatıldı.",
"may_not_reply": "Şu anda cevap veremeyebilirsiniz." "may_not_reply": "Şu anda cevap veremeyebilirsiniz.",
"post": "posta",
"name": "isim",
"comment": "yorum",
"subject": "konu",
"anonymous": "anonim"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Відповісти на це повідомлення", "reply_to_post": "Відповісти на це повідомлення",
"sticky": "Прикріплений", "sticky": "Прикріплений",
"closed": "Закрито", "closed": "Закрито",
"reply": "Відповісти", "reply": "відповісти",
"link": "Посилання", "link": "Посилання",
"close": "Закрити", "close": "Закрити",
"post_a_reply": "Опублікувати Відповідь", "post_a_reply": "Опублікувати Відповідь",
@@ -43,5 +43,10 @@
"bottom": "Низ", "bottom": "Низ",
"top": "Верхній", "top": "Верхній",
"thread_closed": "Тема закрита.", "thread_closed": "Тема закрита.",
"may_not_reply": "Можливо, ви не зможете відповісти зараз." "may_not_reply": "Можливо, ви не зможете відповісти зараз.",
"post": "пост",
"name": "ім'я",
"comment": "коментар",
"subject": "тема",
"anonymous": "анонім"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "اس پوسٹ کا جواب دیں", "reply_to_post": "اس پوسٹ کا جواب دیں",
"sticky": "چسپی", "sticky": "چسپی",
"closed": "بند", "closed": "بند",
"reply": "جواب دیں", "reply": "جواب",
"link": "لنک", "link": "لنک",
"close": "بند کریں", "close": "بند کریں",
"post_a_reply": "ایک جواب بھیجیں", "post_a_reply": "ایک جواب بھیجیں",
@@ -43,5 +43,10 @@
"bottom": "نیچے", "bottom": "نیچے",
"top": "اوپر", "top": "اوپر",
"thread_closed": "موضوع بند کر دیا گیا ہے۔", "thread_closed": "موضوع بند کر دیا گیا ہے۔",
"may_not_reply": "آپ اس وقت جواب نہیں دے سکتے۔" "may_not_reply": "آپ اس وقت جواب نہیں دے سکتے۔",
"post": "پوسٹ",
"name": "نام",
"comment": "تبصرہ",
"subject": "موضوع",
"anonymous": "ناشناس"
} }
+7 -2
View File
@@ -34,7 +34,7 @@
"reply_to_post": "Trả lời bài viết này", "reply_to_post": "Trả lời bài viết này",
"sticky": "Dán", "sticky": "Dán",
"closed": "Đóng", "closed": "Đóng",
"reply": "Trả lời", "reply": "trả lời",
"link": "Liên kết", "link": "Liên kết",
"close": "Đóng", "close": "Đóng",
"post_a_reply": "Đăng Một Câu Trả Lời", "post_a_reply": "Đăng Một Câu Trả Lời",
@@ -43,5 +43,10 @@
"bottom": "Đáy", "bottom": "Đáy",
"top": "Đầu", "top": "Đầu",
"thread_closed": "Chủ đề đã đóng.", "thread_closed": "Chủ đề đã đóng.",
"may_not_reply": "Bạn có thể không thể trả lời vào thời điểm này." "may_not_reply": "Bạn có thể không thể trả lời vào thời điểm này.",
"post": "đăng",
"name": "tên",
"comment": "bình luận",
"subject": "chủ đề",
"anonymous": "ẩn danh"
} }
+6 -1
View File
@@ -43,5 +43,10 @@
"bottom": "底部", "bottom": "底部",
"top": "顶部", "top": "顶部",
"thread_closed": "主题已关闭。", "thread_closed": "主题已关闭。",
"may_not_reply": "您现在可能无法回复。" "may_not_reply": "您现在可能无法回复。",
"post": "发布",
"name": "名字",
"comment": "评论",
"subject": "主题",
"anonymous": "匿名"
} }
+7 -1
View File
@@ -18,18 +18,24 @@ import PostForm from './components/post-form';
const BoardLayout = () => { const BoardLayout = () => {
const { subplebbitAddress } = useParams(); const { subplebbitAddress } = useParams();
const location = useLocation();
// force rerender of post form when navigating between pages
const key = `${subplebbitAddress}-${location.pathname}`;
return ( return (
<> <>
<BoardNav /> <BoardNav />
<BoardBanner /> <BoardBanner />
<MobileBoardButtons /> <MobileBoardButtons />
<PostForm key={subplebbitAddress} /> <PostForm key={key} />
<SubplebbitStats /> <SubplebbitStats />
<DesktopBoardButtons /> <DesktopBoardButtons />
<Outlet /> <Outlet />
</> </>
); );
}; };
const App = () => { const App = () => {
const location = useLocation(); const location = useLocation();
const isInHomeView = isHomeView(location.pathname); const isInHomeView = isHomeView(location.pathname);
@@ -0,0 +1,81 @@
.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;
}
.challengeAnswer {
font-size: 11px !important;
padding: 0px 2px;
font-family: monospace !important;
}
.challengeMediaWrapper {
display: flex;
justify-content: center;
align-items: center;
margin: 5px 0;
}
.challengeFooter {
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
}
.challengeFooter button {
margin: 5px 5px 0 0;
cursor: pointer;
filter: var(--filter80);
text-transform: capitalize;
}
@@ -0,0 +1,125 @@
import { 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';
interface ChallengeProps {
challenge: ChallengeType;
closeModal: () => void;
}
const Challenge = ({ challenge, closeModal }: ChallengeProps) => {
const { t } = useTranslation();
const challenges = challenge?.[0]?.challenges;
const publication = challenge?.[1];
const publicationType = getPublicationType(publication);
const { author, content, link, title } = publication || {};
const { displayName } = author || {};
const [currentChallengeIndex, setCurrentChallengeIndex] = useState(0);
const [answers, setAnswers] = useState<string[]>([]);
const isTextChallenge = challenges[currentChallengeIndex].type === 'text/plain';
const isImageChallenge = challenges[currentChallengeIndex].type === 'image/png';
const onAnswersChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setAnswers((prevAnswers) => {
const updatedAnswers = [...prevAnswers];
updatedAnswers[currentChallengeIndex] = e.target.value;
return updatedAnswers;
});
};
const onSubmit = () => {
publication.publishChallengeAnswers(answers);
setAnswers([]);
closeModal();
};
const onEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key !== 'Enter') return;
if (challenges[currentChallengeIndex + 1]) {
setCurrentChallengeIndex((prev) => prev + 1);
} else {
onSubmit();
}
};
return (
<Draggable handle='.challengeHandle'>
<div className={styles.container}>
<div className={`challengeHandle ${styles.title}`}>
Challenge for {publicationType}
<button className={styles.closeIcon} onClick={closeModal} title='close' />
</div>
<div className={styles.publication}>
<div className={styles.name}>
<input type='text' value={displayName || 'Anonymous'} disabled />
</div>
{title && (
<div className={styles.subject}>
<input type='text' value={title} disabled />
</div>
)}
{content && (
<div className={styles.content}>
<textarea value={content} disabled cols={48} rows={4} wrap='soft' />
</div>
)}
{link && (
<div className={styles.link}>
<input type='text' value={link} disabled />
</div>
)}
<div className={styles.challengeContainer}>
<input
className={styles.challengeAnswer}
type='text'
autoComplete='off'
autoCorrect='off'
spellCheck='false'
placeholder='TYPE THE ANSWER HERE AND PRESS ENTER'
onKeyDown={onEnterKey}
onChange={onAnswersChange}
value={answers[currentChallengeIndex] || ''}
autoFocus
/>
<div className={styles.challengeMediaWrapper}>
{isTextChallenge && <div className={styles.challengeMedia}>{challenges[currentChallengeIndex]?.challenge}</div>}
{isImageChallenge && (
<img alt={t('loading')} className={styles.challengeMedia} src={`data:image/png;base64,${challenges[currentChallengeIndex]?.challenge}`} />
)}
</div>
</div>
<div className={styles.challengeFooter}>
<div className={styles.counter}>{t('challenge_counter', { index: currentChallengeIndex + 1, total: challenges?.length })}</div>
<span className={styles.buttons}>
{!challenges[currentChallengeIndex + 1] && <button onClick={onSubmit}>{t('submit')}</button>}
{challenges.length > 1 && (
<button disabled={!challenges[currentChallengeIndex - 1]} onClick={() => setCurrentChallengeIndex((prev) => prev - 1)}>
{t('previous')}
</button>
)}
{challenges[currentChallengeIndex + 1] && <button onClick={() => setCurrentChallengeIndex((prev) => prev + 1)}>{t('next')}</button>}
</span>
</div>
</div>
</div>
</Draggable>
);
};
const ChallengeModal = () => {
const { challenges, removeChallenge } = useChallenges();
const isOpen = !!challenges.length;
const closeModal = () => removeChallenge();
return isOpen && <Challenge challenge={challenges[0]} closeModal={closeModal} />;
};
export default ChallengeModal;
+1
View File
@@ -0,0 +1 @@
export { default } from './challenge-modal';
+2 -6
View File
@@ -8,12 +8,8 @@
text-decoration: var(--post-content-link-text-decoration-hover); text-decoration: var(--post-content-link-text-decoration-hover);
} }
.markdown ol { .markdown li {
padding-left: 15px; list-style-position: inside;
}
.markdown ul {
padding-left: 40px;
} }
.hrWrapper { .hrWrapper {
@@ -40,6 +40,7 @@
padding: var(--post-form-field-title-padding); padding: var(--post-form-field-title-padding);
font-size: var(--post-form-field-title-font-size); font-size: var(--post-form-field-title-font-size);
width: 80px; width: 80px;
text-transform: capitalize;
} }
.postFormTable td { .postFormTable td {
@@ -78,7 +79,11 @@
.postFormTable button { .postFormTable button {
margin-left: 2px; margin-left: 2px;
bottom: 0px;
filter: var(--filter80); filter: var(--filter80);
position: absolute;
cursor: pointer;
text-transform: capitalize;
} }
.linkType { .linkType {
+171 -28
View File
@@ -1,11 +1,57 @@
import { useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useLocation, useParams } from 'react-router-dom'; import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useAccount, useComment } from '@plebbit/plebbit-react-hooks'; import { PublishCommentOptions, setAccount, useAccount, useAccountComment, useComment, usePublishComment } from '@plebbit/plebbit-react-hooks';
import { create } from 'zustand';
import styles from './post-form.module.css';
import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils';
import { getLinkMediaInfo } from '../../lib/utils/media-utils'; import { getLinkMediaInfo } from '../../lib/utils/media-utils';
import { isValidURL } from '../../lib/utils/url-utils'; import { isValidURL } from '../../lib/utils/url-utils';
import { isDescriptionView, isPostPageView, isRulesView } from '../../lib/utils/view-utils'; import { isDescriptionView, isPostPageView, isRulesView } from '../../lib/utils/view-utils';
import styles from './post-form.module.css'; import challengesStore from '../../hooks/use-challenges';
import useReply from '../../hooks/use-reply';
import _ from 'lodash';
type SubmitState = {
subplebbitAddress: string | undefined;
title: string | undefined;
content: string | undefined;
link: string | undefined;
publishCommentOptions: PublishCommentOptions;
setSubmitStore: (data: Partial<SubmitState>) => void;
resetSubmitStore: () => void;
};
const { addChallenge } = challengesStore.getState();
const useSubmitStore = create<SubmitState>((set) => ({
subplebbitAddress: undefined,
title: undefined,
content: undefined,
link: undefined,
publishCommentOptions: {},
setSubmitStore: ({ subplebbitAddress, title, content, link }) =>
set((state) => {
const nextState = { ...state };
if (subplebbitAddress !== undefined) nextState.subplebbitAddress = subplebbitAddress;
if (title !== undefined) nextState.title = title || undefined;
if (content !== undefined) nextState.content = content || undefined;
if (link !== undefined) nextState.link = link || undefined;
nextState.publishCommentOptions = {
...nextState,
onChallenge: (...args: any) => addChallenge(args),
onChallengeVerification: alertChallengeVerificationFailed,
onError: (error: Error) => {
console.error(error);
let errorMessage = error.message;
alert(errorMessage);
},
};
return nextState;
}),
resetSubmitStore: () => set({ subplebbitAddress: undefined, title: undefined, content: undefined, link: undefined, publishCommentOptions: {} }),
}));
const LinkTypePreviewer = ({ link }: { link: string }) => { const LinkTypePreviewer = ({ link }: { link: string }) => {
const mediaInfo = getLinkMediaInfo(link); const mediaInfo = getLinkMediaInfo(link);
@@ -13,41 +59,140 @@ const LinkTypePreviewer = ({ link }: { link: string }) => {
}; };
const PostFormTable = () => { const PostFormTable = () => {
const { t } = useTranslation();
const account = useAccount(); const account = useAccount();
const { displayName } = account || {}; const { displayName } = account?.author || {};
const [link, setLink] = useState(''); const [url, setUrl] = useState('');
const { title, content, link, publishCommentOptions, setSubmitStore, resetSubmitStore } = useSubmitStore();
const { index, publishComment } = usePublishComment(publishCommentOptions);
const onPublishPost = () => {
if (!title && !content && !link) {
alert(`Cannot post empty comment`);
return;
}
if (link && !isValidURL(link)) {
alert(`Invalid link`);
return;
}
publishComment();
};
const params = useParams();
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
useEffect(() => {
if (subplebbitAddress) {
setSubmitStore({ subplebbitAddress });
}
}, [subplebbitAddress, setSubmitStore]);
// redirect to pending page when pending comment is created
const navigate = useNavigate();
useEffect(() => {
if (typeof index === 'number') {
resetSubmitStore();
navigate(`/profile/${index}`);
}
}, [index, resetSubmitStore, navigate]);
// in post page, publish a reply to the post
const location = useLocation();
const isInPostPage = isPostPageView(location.pathname, params);
const cid = params?.commentCid as string;
const { setContent, resetContent, replyIndex, publishReply } = useReply({ cid, subplebbitAddress });
const textRef = useRef<HTMLTextAreaElement>(null);
const urlRef = useRef<HTMLInputElement>(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') {
resetContent();
window.scrollTo(0, document.body.scrollHeight);
}
}, [replyIndex, resetContent]);
return ( return (
<table className={styles.postFormTable}> <table className={styles.postFormTable}>
<tbody> <tbody>
<tr> <tr>
<td>Name</td> <td>{t('name')}</td>
<td> <td>
<input type='text' placeholder={!displayName ? 'Anonymous' : undefined} defaultValue={displayName || undefined} /> <input
type='text'
placeholder={!displayName ? _.capitalize(t('anonymous')) : undefined}
defaultValue={displayName || undefined}
onChange={(e) => setAccount({ ...account, author: { ...account?.author, displayName: e.target.value } })}
/>
{isInPostPage && <button onClick={onPublishReply}>{t('post')}</button>}
</td>
</tr>
{!isInPostPage && (
<tr>
<td>{t('subject')}</td>
<td>
<input
type='text'
onChange={(e) => {
setSubmitStore({ title: e.target.value });
}}
/>
<button onClick={onPublishPost}>{t('post')}</button>
</td>
</tr>
)}
<tr>
<td>{t('comment')}</td>
<td>
<textarea
cols={48}
rows={4}
wrap='soft'
ref={textRef}
onChange={(e) => {
isInPostPage ? setContent.content(e.target.value) : setSubmitStore({ content: e.target.value });
}}
/>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Subject</td> <td>{t('link')}</td>
<td> <td>
<input type='text' /> <input
<button>Post</button> type='text'
</td> autoCorrect='off'
</tr> autoComplete='off'
<tr> spellCheck='false'
<td>Comment</td> ref={urlRef}
<td> onChange={(e) => {
<textarea cols={48} rows={4} wrap='soft' /> setUrl(e.target.value);
</td> isInPostPage ? setContent.link(e.target.value) : setSubmitStore({ link: e.target.value });
</tr> }}
<tr> />
<td>Link</td>
<td>
<input type='text' onChange={(e) => setLink(e.target.value)} />
<span className={styles.linkType}> <span className={styles.linkType}>
{link && ( {url && (
<> <>
(<LinkTypePreviewer link={link} />) (<LinkTypePreviewer link={url} />)
</> </>
)} )}
</span> </span>
@@ -66,9 +211,7 @@ const PostForm = () => {
const isInDescriptionView = isDescriptionView(location.pathname, params); const isInDescriptionView = isDescriptionView(location.pathname, params);
const isInRulesView = isRulesView(location.pathname, params); const isInRulesView = isRulesView(location.pathname, params);
const { subplebbitAddress, commentCid } = params || {}; const comment = useComment({ commentCid: useParams().commentCid });
const comment = useComment({ commentCid });
const { deleted, locked, removed } = comment || {}; const { deleted, locked, removed } = comment || {};
const isThreadClosed = deleted || locked || removed || isInDescriptionView || isInRulesView; const isThreadClosed = deleted || locked || removed || isInDescriptionView || isInRulesView;
+10
View File
@@ -303,6 +303,11 @@
text-align: right; text-align: right;
} }
.postMobile .postNumLink a {
color: unset;
text-decoration: unset;
}
.postMobile .postMessage { .postMobile .postMessage {
padding: 10px; padding: 10px;
font-size: var(--post-mobile-content-font-size); font-size: var(--post-mobile-content-font-size);
@@ -416,6 +421,11 @@
text-transform: capitalize; text-transform: capitalize;
} }
.pendingCid {
color: red !important;
font-weight: 700 !important;
}
@media (max-width: 640px) { @media (max-width: 640px) {
.postDesktop { .postDesktop {
display: none; display: none;
+66 -21
View File
@@ -8,8 +8,10 @@ import { getFormattedDate } from '../../lib/utils/time-utils';
import { isPostPageView } from '../../lib/utils/view-utils'; import { isPostPageView } from '../../lib/utils/view-utils';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies'; import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import useReplies from '../../hooks/use-replies'; import useReplies from '../../hooks/use-replies';
import useStateString from '../../hooks/use-state-string';
import useWindowWidth from '../../hooks/use-window-width'; import useWindowWidth from '../../hooks/use-window-width';
import styles from './post.module.css'; import styles from './post.module.css';
import LoadingEllipsis from '../loading-ellipsis';
import Markdown from '../markdown'; import Markdown from '../markdown';
import CommentMedia from '../comment-media'; import CommentMedia from '../comment-media';
import { canEmbed } from '../embed'; import { canEmbed } from '../embed';
@@ -24,13 +26,15 @@ interface PostProps {
const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => { const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, postCid, replyCount, shortCid, subplebbitAddress, timestamp, title } = post || {}; const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, postCid, replyCount, shortCid, state, subplebbitAddress, timestamp, title } = post || {};
const { address, displayName, shortAddress } = author || {}; const { address, displayName, shortAddress } = author || {};
const authorRole = roles?.[address]?.role; const authorRole = roles?.[address]?.role;
const { isDescription, isRules } = post || {}; // custom properties, not from api const { isDescription, isRules } = post || {}; // custom properties, not from api
const isInPostPage = isPostPageView(useLocation().pathname, useParams()); const params = useParams();
const location = useLocation();
const isInPostPage = isPostPageView(location.pathname, params);
const displayTitle = title && title.length > 75 ? title?.slice(0, 75) + '...' : title; const displayTitle = title && title.length > 75 ? title?.slice(0, 75) + '...' : title;
const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) + '(...)' : content; const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) + '(...)' : content;
@@ -120,12 +124,16 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => {
<span className={styles.postNum}> <span className={styles.postNum}>
{!(isDescription || isRules) && ( {!(isDescription || isRules) && (
<span className={styles.postNumLink}> <span className={styles.postNumLink}>
<Link to={`/p/${subplebbitAddress}/${cid}`} className={styles.linkToPost} title={t('link_to_post')}> <Link to={`/p/${subplebbitAddress}/${cid}`} className={styles.linkToPost} title={t('link_to_post')} onClick={(e) => !cid && e.preventDefault()}>
c/ c/
</Link> </Link>
<span className={styles.replyToPost} title={t('reply_to_post')}> {!cid ? (
{shortCid} <span className={styles.pendingCid}>{state === 'failed' ? 'Failed' : 'Pending'}</span>
</span> ) : (
<span className={styles.replyToPost} title={t('reply_to_post')}>
{shortCid}
</span>
)}
</span> </span>
)} )}
{pinned && ( {pinned && (
@@ -189,7 +197,7 @@ const PostDesktop = ({ post, roles, showAllReplies }: PostProps) => {
const ReplyDesktop = ({ reply, roles }: PostProps) => { const ReplyDesktop = ({ reply, roles }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, content, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, subplebbitAddress, timestamp } = reply || {}; const { author, cid, content, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, state, subplebbitAddress, timestamp } = reply || {};
const { address, displayName, shortAddress } = author || {}; const { address, displayName, shortAddress } = author || {};
const authorRole = roles?.[address]?.role; const authorRole = roles?.[address]?.role;
@@ -203,6 +211,11 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => {
const [menuBtnRotated, setMenuBtnRotated] = useState(false); const [menuBtnRotated, setMenuBtnRotated] = useState(false);
const stateString = useStateString(reply);
const loadingString = stateString && (
<div className={`${styles.stateString} ${styles.ellipsis}`}>{stateString !== 'Failed' ? <LoadingEllipsis string={stateString} /> : stateString}</div>
);
return ( return (
<div className={styles.replyDesktop}> <div className={styles.replyDesktop}>
<div className={styles.sideArrows}>{'>>'}</div> <div className={styles.sideArrows}>{'>>'}</div>
@@ -221,12 +234,16 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => {
<span className={styles.dateTime}>{getFormattedDate(timestamp)} </span> <span className={styles.dateTime}>{getFormattedDate(timestamp)} </span>
<span className={styles.postNum}> <span className={styles.postNum}>
<span className={styles.postNumLink}> <span className={styles.postNumLink}>
<Link to={`/p/${subplebbitAddress}/c/${reply.cid}`} className={styles.linkToPost} title='Link to post'> <Link to={`/p/${subplebbitAddress}/${cid}`} className={styles.linkToPost} title={t('link_to_post')} onClick={(e) => !cid && e.preventDefault()}>
c/ c/
</Link> </Link>
<span className={styles.replyToPost} title='Reply to post'> {!cid ? (
{shortCid} <span className={styles.pendingCid}>{state === 'failed' ? 'Failed' : 'Pending'}</span>
</span> ) : (
<span className={styles.replyToPost} title={t('reply_to_post')}>
{shortCid}
</span>
)}
</span> </span>
{pinned && ( {pinned && (
<span className={styles.stickyIconWrapper}> <span className={styles.stickyIconWrapper}>
@@ -296,6 +313,12 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => {
</> </>
)} )}
<Markdown content={content} /> <Markdown content={content} />
{!cid && (
<>
<br />
{loadingString}
</>
)}
</blockquote> </blockquote>
)} )}
</div> </div>
@@ -305,14 +328,17 @@ const ReplyDesktop = ({ reply, roles }: PostProps) => {
const PostMobile = ({ post, roles, showAllReplies }: PostProps) => { const PostMobile = ({ post, roles, showAllReplies }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, replyCount, shortCid, subplebbitAddress, timestamp, title } = post || {}; const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, replyCount, shortCid, state, subplebbitAddress, timestamp, title } = post || {};
const { address, displayName, shortAddress } = author || {}; const { address, displayName, shortAddress } = author || {};
const authorRole = roles?.[address]?.role; const authorRole = roles?.[address]?.role;
const { isDescription, isRules } = post || {}; // custom properties, not from api const { isDescription, isRules } = post || {}; // custom properties, not from api
const params = useParams();
const location = useLocation();
const isInPostPage = isPostPageView(location.pathname, params);
const linkCount = useCountLinksInReplies(post); const linkCount = useCountLinksInReplies(post);
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
const displayTitle = title && title.length > 30 ? title?.slice(0, 30) + '(...)' : title; const displayTitle = title && title.length > 30 ? title?.slice(0, 30) + '(...)' : title;
const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) : content; const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) : content;
@@ -335,7 +361,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => {
... ...
</span> </span>
<span className={styles.nameBlock}> <span className={styles.nameBlock}>
<span className={`${styles.name} ${authorRole && styles.capcodeMod}`}> <span className={`${styles.name} ${(isDescription || isRules || authorRole) && styles.capcodeMod}`}>
{displayName || 'Anonymous'} {displayName || 'Anonymous'}
{authorRole && ` ## Board ${authorRole}`}{' '} {authorRole && ` ## Board ${authorRole}`}{' '}
</span> </span>
@@ -360,10 +386,18 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => {
<span className={styles.dateTimePostNum}> <span className={styles.dateTimePostNum}>
{getFormattedDate(timestamp)}{' '} {getFormattedDate(timestamp)}{' '}
{!(isDescription || isRules) && ( {!(isDescription || isRules) && (
<> <span className={styles.postNumLink}>
<span className={styles.linkToPost}>c/</span> <Link to={`/p/${subplebbitAddress}/c/${cid}`} className={styles.linkToPost} title={t('link_to_post')} onClick={(e) => !cid && e.preventDefault()}>
<span className={styles.replyToPost}>{shortCid}</span> c/
</> </Link>
{!cid ? (
<span className={styles.pendingCid}>{state === 'failed' ? 'Failed' : 'Pending'}</span>
) : (
<span className={styles.replyToPost} title={t('reply_to_post')}>
{shortCid}
</span>
)}
</span>
)} )}
</span> </span>
</div> </div>
@@ -416,7 +450,7 @@ const PostMobile = ({ post, roles, showAllReplies }: PostProps) => {
const ReplyMobile = ({ reply, roles }: PostProps) => { const ReplyMobile = ({ reply, roles }: PostProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { author, content, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, subplebbitAddress, timestamp } = reply || {}; const { author, content, cid, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, state, subplebbitAddress, timestamp } = reply || {};
const { address, displayName, shortAddress } = author || {}; const { address, displayName, shortAddress } = author || {};
const authorRole = roles?.[address]?.role; const authorRole = roles?.[address]?.role;
@@ -445,8 +479,19 @@ const ReplyMobile = ({ reply, roles }: PostProps) => {
)} )}
</span> </span>
<span className={styles.dateTimePostNum}> <span className={styles.dateTimePostNum}>
{getFormattedDate(timestamp)} <span className={styles.linkToPost}>c/</span> {getFormattedDate(timestamp)}{' '}
<span className={styles.replyToPost}>{shortCid}</span> <span className={styles.postNumLink}>
<Link to={`/p/${subplebbitAddress}/c/${cid}`} title={t('link_to_post')} onClick={(e) => !cid && e.preventDefault()}>
c/
</Link>
</span>
{!cid ? (
<span className={styles.pendingCid}>{state === 'failed' ? 'Failed' : 'Pending'}</span>
) : (
<span className={styles.replyToPost} title={t('reply_to_post')}>
{shortCid}
</span>
)}
</span> </span>
</div> </div>
{(hasThumbnail || link) && ( {(hasThumbnail || link) && (
+24
View File
@@ -0,0 +1,24 @@
import { create } from 'zustand';
import { Challenge } from '@plebbit/plebbit-react-hooks';
interface State {
challenges: Challenge[];
addChallenge: (challenge: Challenge) => void;
removeChallenge: () => void;
}
const useChallengesStore = create<State>((set) => ({
challenges: [],
addChallenge: (challenge: Challenge) => {
set((state) => ({ challenges: [...state.challenges, challenge] }));
},
removeChallenge: () => {
set((state) => {
const challenges = [...state.challenges];
challenges.shift();
return { challenges };
});
},
}));
export default useChallengesStore;
+115
View File
@@ -0,0 +1,115 @@
import { useMemo } from 'react';
import { ChallengeVerification, Comment, PublishCommentOptions, usePublishComment } from '@plebbit/plebbit-react-hooks';
import { create } from 'zustand';
import useChallengesStore from './use-challenges';
import { alertChallengeVerificationFailed } from '../lib/utils/challenge-utils';
type SetReplyStoreData = {
subplebbitAddress: string;
parentCid: string;
content: string | undefined;
link: string | undefined;
spoiler: boolean;
};
type ReplyState = {
content: { [parentCid: string]: string | undefined };
link: { [parentCid: string]: string | undefined };
spoiler: { [parentCid: string]: boolean | undefined };
publishCommentOptions: PublishCommentOptions;
setReplyStore: (data: SetReplyStoreData) => void;
resetReplyStore: (parentCid: string) => void;
};
const { addChallenge } = useChallengesStore.getState();
const useReplyStore = create<ReplyState>((set) => ({
content: {},
link: {},
spoiler: {},
publishCommentOptions: {},
setReplyStore: (data: SetReplyStoreData) =>
set((state) => {
const { subplebbitAddress, parentCid, content, link, spoiler } = data;
const publishCommentOptions = {
subplebbitAddress,
parentCid,
content,
link,
spoiler,
onChallenge: (...args: any) => addChallenge(args),
onChallengeVerification: (challengeVerification: ChallengeVerification, comment: Comment) => {
alertChallengeVerificationFailed(challengeVerification, comment);
},
onError: (error: Error) => {
console.error(error);
alert(error.message);
},
};
return {
content: { ...state.content, [parentCid]: content },
link: { ...state.link, [parentCid]: link },
spoiler: { ...state.spoiler, [parentCid]: spoiler },
publishCommentOptions: { ...state.publishCommentOptions, [parentCid]: publishCommentOptions },
};
}),
resetReplyStore: (parentCid) =>
set((state) => ({
content: { ...state.content, [parentCid]: undefined },
link: { ...state.link, [parentCid]: undefined },
spoiler: { ...state.spoiler, [parentCid]: undefined },
publishCommentOptions: { ...state.publishCommentOptions, [parentCid]: undefined },
})),
}));
const useReply = ({ cid, subplebbitAddress }: { cid: string; subplebbitAddress: string }) => {
const parentCid = cid;
const { content, link, spoiler, publishCommentOptions } = useReplyStore((state) => ({
content: state.content[parentCid],
link: state.link[parentCid],
spoiler: state.spoiler[parentCid],
publishCommentOptions: state.publishCommentOptions[parentCid],
}));
const setReplyStore = useReplyStore((state) => state.setReplyStore);
const resetReplyStore = useReplyStore((state) => state.resetReplyStore);
const setContent = useMemo(
() => ({
content: (newContent: string) =>
setReplyStore({
subplebbitAddress,
parentCid,
content: newContent === '' ? undefined : newContent,
link: link || undefined,
spoiler: spoiler || false,
}),
link: (newLink: string) =>
setReplyStore({
subplebbitAddress,
parentCid,
content: content,
link: newLink || undefined,
spoiler: spoiler || false,
}),
spoiler: (newSpoiler: boolean) =>
setReplyStore({
subplebbitAddress,
parentCid,
content: content,
link: link || undefined,
spoiler: newSpoiler,
}),
}),
[subplebbitAddress, parentCid, setReplyStore, content, link, spoiler],
);
const resetContent = useMemo(() => () => resetReplyStore(parentCid), [parentCid, resetReplyStore]);
const { index, publishComment } = usePublishComment(publishCommentOptions);
return { setContent, resetContent, replyIndex: index, publishReply: publishComment };
};
export default useReply;
+63
View File
@@ -0,0 +1,63 @@
import { ChallengeVerification } from '@plebbit/plebbit-react-hooks';
export const alertChallengeVerificationFailed = (challengeVerification: ChallengeVerification, publication: any) => {
if (challengeVerification?.challengeSuccess === false) {
console.warn(challengeVerification, publication);
alert(`p/${publication?.subplebbitAddress} challenge error: ${[...(challengeVerification?.challengeErrors || []), challengeVerification?.reason].join(' ')}`);
} else {
console.log(challengeVerification, publication);
}
};
export const getPublicationType = (publication: any) => {
if (!publication) {
return;
}
if (typeof publication.vote === 'number') {
return 'vote';
}
if (publication.parentCid) {
return 'reply';
}
if (publication.commentCid) {
return 'edit';
}
return 'post';
};
export const getVotePreview = (publication: any) => {
if (typeof publication?.vote !== 'number') {
return '';
}
let votePreview = '';
if (publication.vote === -1) {
votePreview += ' -1';
} else {
votePreview += ` +${publication.vote}`;
}
return votePreview;
};
export const getPublicationPreview = (publication: any) => {
if (!publication) {
return '';
}
let publicationPreview = '';
if (publication.title) {
publicationPreview += publication.title;
}
if (publication.content) {
if (publicationPreview) {
publicationPreview += ': ';
}
publicationPreview += publication.content;
}
if (!publicationPreview && publication.link) {
publicationPreview += publication.link;
}
if (publicationPreview.length > 50) {
publicationPreview = publicationPreview.substring(0, 50) + '...';
}
return publicationPreview;
};
+2
View File
@@ -6,3 +6,5 @@ declare module '*.module.css' {
declare module 'ext-name'; declare module 'ext-name';
declare module 'lodash'; declare module 'lodash';
declare module 'react-draggable';
+61 -1
View File
@@ -30,9 +30,19 @@
--catalog-post-menu-btn-opacity: 0.5; --catalog-post-menu-btn-opacity: 0.5;
--catalog-post-menu-btn-hover-opacity: 1; --catalog-post-menu-btn-hover-opacity: 1;
/* challenge modal */
--challenge-modal-background-color: #f0e0d6;
--challenge-modal-border: 1px solid #d9bfb7;
--challenge-modal-title-background-color: #ea8;
--challenge-modal-title-text-color: #800;
--challenge-modal-title-border: 1px solid #800;
--challenge-modal-title-font-size: 10pt;
--challenge-modal-title-font-weight: 700;
/* desktop buttons */ /* desktop buttons */
--button-desktop-text-color: #00e; --button-desktop-text-color: #00e;
--button-desktop-text-color-hover: red; --button-desktop-text-color-hover: red;
--close-button-background-image: url("/public/assets/buttons/cross-red.png");
/* mobile buttons */ /* mobile buttons */
--button-font-size-mobile: 10pt; --button-font-size-mobile: 10pt;
@@ -173,6 +183,15 @@
--catalog-post-menu-btn-opacity: 0.5; --catalog-post-menu-btn-opacity: 0.5;
--catalog-post-menu-btn-hover-opacity: 1; --catalog-post-menu-btn-hover-opacity: 1;
/* challenge modal */
--challenge-modal-background-color: #d6daf0;
--challenge-modal-border: 1px solid #b7c5d9;
--challenge-modal-title-background-color: #98e;
--challenge-modal-title-text-color: #000;
--challenge-modal-title-border: 1px solid #000;
--challenge-modal-title-font-size: 10pt;
--challenge-modal-title-font-weight: 700;
/* homepage */ /* homepage */
--homepage-infobox-text-color: #000; --homepage-infobox-text-color: #000;
--homepage-infobox-bar-text-color: #000; --homepage-infobox-bar-text-color: #000;
@@ -192,6 +211,7 @@
/* desktop buttons */ /* desktop buttons */
--button-desktop-text-color: #34345c; --button-desktop-text-color: #34345c;
--button-desktop-text-color-hover: #d00; --button-desktop-text-color-hover: #d00;
--close-button-background-image: url("/public/assets/buttons/cross-blue.png");
/* mobile buttons */ /* mobile buttons */
--button-font-size-mobile: 10pt; --button-font-size-mobile: 10pt;
@@ -310,10 +330,20 @@
--catalog-post-menu-btn-opacity: 0.5; --catalog-post-menu-btn-opacity: 0.5;
--catalog-post-menu-btn-hover-opacity: 1; --catalog-post-menu-btn-hover-opacity: 1;
/* challenge modal */
--challenge-modal-background-color: #f0e0d6;
--challenge-modal-border: 1px solid #d9bfb7;
--challenge-modal-title-background-color: #ea8;
--challenge-modal-title-text-color: #800;
--challenge-modal-title-border: 1px solid #800;
--challenge-modal-title-font-size: 12pt;
--challenge-modal-title-font-weight: 700;
/* desktop buttons */ /* desktop buttons */
--button-desktop-text-color: #00e; --button-desktop-text-color: #00e;
--button-desktop-text-color-hover: red; --button-desktop-text-color-hover: red;
--button-text-decoration: underline; --button-text-decoration: underline;
--close-button-background-image: url("/public/assets/buttons/cross-red.png");
/* mobile buttons */ /* mobile buttons */
--button-font-size-mobile: 11pt; --button-font-size-mobile: 11pt;
@@ -420,6 +450,15 @@
--body-font-family: times new roman, serif; --body-font-family: times new roman, serif;
--body-font-size: 12pt; --body-font-size: 12pt;
/* challenge modal */
--challenge-modal-background-color: #d6daf0;
--challenge-modal-border: 1px solid #b7c5d9;
--challenge-modal-title-background-color: #98e;
--challenge-modal-title-text-color: #000;
--challenge-modal-title-border: 1px solid #000;
--challenge-modal-title-font-size: 12pt;
--challenge-modal-title-font-weight: 700;
/* homepage */ /* homepage */
--homepage-infobox-text-color: #000; --homepage-infobox-text-color: #000;
--homepage-infobox-bar-text-color: #000; --homepage-infobox-bar-text-color: #000;
@@ -440,6 +479,7 @@
--button-desktop-text-color: #34345c; --button-desktop-text-color: #34345c;
--button-text-decoration: underline; --button-text-decoration: underline;
--button-desktop-text-color-hover: #d00; --button-desktop-text-color-hover: #d00;
--close-button-background-image: url("/public/assets/buttons/cross-blue.png");
/* mobile buttons */ /* mobile buttons */
--button-font-size-mobile: 11pt; --button-font-size-mobile: 11pt;
@@ -559,9 +599,19 @@
--catalog-post-menu-btn-opacity: 0.5; --catalog-post-menu-btn-opacity: 0.5;
--catalog-post-menu-btn-hover-opacity: 1; --catalog-post-menu-btn-hover-opacity: 1;
/* challenge modal */
--challenge-modal-background-color: #282a2e;
--challenge-modal-border: 1px solid #111;
--challenge-modal-title-background-color: #282a2e;
--challenge-modal-title-text-color: #c5c8c6;
--challenge-modal-title-border: unset;
--challenge-modal-title-font-size: 10pt;
--challenge-modal-title-font-weight: 700;
/* desktop buttons */ /* desktop buttons */
--button-desktop-text-color: #81a2be; --button-desktop-text-color: #81a2be;
--button-desktop-text-color-hover: #5f89ac; --button-desktop-text-color-hover: #5f89ac;
--close-button-background-image: url("/public/assets/buttons/cross-dark.png");
/* filter for inputs */ /* filter for inputs */
--filter80: brightness(85%); --filter80: brightness(85%);
@@ -691,9 +741,19 @@
--catalog-post-menu-btn-opacity: 0.5; --catalog-post-menu-btn-opacity: 0.5;
--catalog-post-menu-btn-hover-opacity: 1; --catalog-post-menu-btn-hover-opacity: 1;
/* challenge modal */
--challenge-modal-background-color: #ddd;
--challenge-modal-border: 1px solid #ccc;
--challenge-modal-title-background-color: #ddd;
--challenge-modal-title-text-color: #333;
--challenge-modal-title-border: unset;
--challenge-modal-title-font-size: 10pt;
--challenge-modal-title-font-weight: 700;
/* desktop buttons */ /* desktop buttons */
--button-desktop-text-color: #f60; --button-desktop-text-color: #f60;
--button-desktop-text-color-hover: #f30; --button-desktop-text-color-hover: #f30;
--close-button-background-image: url("/public/assets/buttons/cross-photon.png");
/* mobile buttons */ /* mobile buttons */
--button-font-size-mobile: 10pt; --button-font-size-mobile: 10pt;
@@ -735,7 +795,7 @@
--post-mobile-info-border-top: 1px solid #ccc; --post-mobile-info-border-top: 1px solid #ccc;
--post-mobile-info-border-bottom: 1px solid #ccc; --post-mobile-info-border-bottom: 1px solid #ccc;
--post-mobile-info-background-color: #ddd; --post-mobile-info-background-color: #ddd;
--post-mobile-info-text-color: #707070; --post-mobile-info-text-color: #333;
--post-mobile-menu-button-color: #f60; --post-mobile-menu-button-color: #f60;
--post-mobile-name-text-color: #004a99; --post-mobile-name-text-color: #004a99;
--post-mobile-name-font-weight: 700; --post-mobile-name-font-weight: 700;
+13 -78
View File
@@ -3347,68 +3347,6 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@plebbit/plebbit-js@https://github.com/plebbit/plebbit-js.git#073d5f501ccf9521942d93f6522d1125058c196a":
version "0.0.3"
resolved "https://github.com/plebbit/plebbit-js.git#073d5f501ccf9521942d93f6522d1125058c196a"
dependencies:
"@bonfida/spl-name-service" "2.3.8"
"@chainsafe/libp2p-gossipsub" "12.0.0"
"@chainsafe/libp2p-noise" "15.0.0"
"@chainsafe/libp2p-yamux" "6.0.2"
"@ensdomains/eth-ens-namehash" "2.0.15"
"@keyv/sqlite" "3.6.7"
"@libp2p/autonat" "1.0.12"
"@libp2p/bootstrap" "10.0.15"
"@libp2p/circuit-relay-v2" "^1.0.15"
"@libp2p/identify" "1.0.14"
"@libp2p/kad-dht" "12.0.7"
"@libp2p/mplex" "10.0.15"
"@libp2p/peer-id-factory" "4.0.6"
"@libp2p/webrtc" "4.0.19"
"@libp2p/webtransport" "4.0.19"
"@plebbit/plebbit-logger" "github:plebbit/plebbit-logger#355a96d7659ed820047980049dfa627d30d83a69"
"@plebbit/proper-lockfile" "github:plebbit/node-proper-lockfile#7fd6332117340c1d3d98dd0afee2d31cc06f72b8"
"@types/proper-lockfile" "4.1.2"
"@types/uuid" "8.3.4"
assert "2.1.0"
better-sqlite3 "9.3.0"
buffer "6.0.3"
captcha-canvas "3.2.1"
cbor "9.0.1"
debounce "1.2.1"
err-code "3.0.1"
ethers "6.10.0"
ext-name "5.0.0"
file-type "16.5.4"
hpagent "1.2.0"
ipfs-only-hash "4.0.0"
jose "4.11.0"
js-sha256 "0.9.0"
keyv "4.5.4"
knex "3.1.0"
kubo-rpc-client "3.0.3"
libp2p "1.2.1"
libp2p-crypto "0.21.2"
limiter-es6-compat "2.1.2"
localforage "1.10.0"
lodash-es "4.17.21"
lru-cache "10.1.0"
open-graph-scraper "6.3.3"
p-limit "4.0.0"
p-timeout "6.1.2"
peer-id "0.16.0"
probe-image-size "7.2.3"
retry "0.13.1"
rpc-websockets "7.9.0"
safe-stable-stringify "2.4.3"
sha1-uint8array "0.10.7"
skia-canvas "1.0.0"
tiny-typed-emitter "2.1.0"
tinycache "1.1.2"
ts-custom-error "3.3.1"
uuid "9.0.1"
viem "1.5.2"
"@plebbit/plebbit-js@https://github.com/plebbit/plebbit-js.git#347579798478c27eea4808b923ab6f21799fce89": "@plebbit/plebbit-js@https://github.com/plebbit/plebbit-js.git#347579798478c27eea4808b923ab6f21799fce89":
version "0.0.3" version "0.0.3"
resolved "https://github.com/plebbit/plebbit-js.git#347579798478c27eea4808b923ab6f21799fce89" resolved "https://github.com/plebbit/plebbit-js.git#347579798478c27eea4808b923ab6f21799fce89"
@@ -3484,22 +3422,6 @@
dependencies: dependencies:
debug "4.3.4" debug "4.3.4"
"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#00aabcce2276c671c0f4a371d459c93eb39c936a":
version "0.0.1"
resolved "https://github.com/plebbit/plebbit-react-hooks.git#00aabcce2276c671c0f4a371d459c93eb39c936a"
dependencies:
"@plebbit/plebbit-js" "https://github.com/plebbit/plebbit-js.git#073d5f501ccf9521942d93f6522d1125058c196a"
"@plebbit/plebbit-logger" "https://github.com/plebbit/plebbit-logger.git"
assert "2.0.0"
ethers "5.6.9"
localforage "1.10.0"
lodash.isequal "4.5.0"
memoizee "0.4.15"
quick-lru "5.1.1"
uint8arrays "3.1.1"
uuid "8.3.2"
zustand "4.0.0"
"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#6d0d38ad52ce77715cb05be6cec55d691f5f013d": "@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#6d0d38ad52ce77715cb05be6cec55d691f5f013d":
version "0.0.1" version "0.0.1"
resolved "https://github.com/plebbit/plebbit-react-hooks.git#6d0d38ad52ce77715cb05be6cec55d691f5f013d" resolved "https://github.com/plebbit/plebbit-react-hooks.git#6d0d38ad52ce77715cb05be6cec55d691f5f013d"
@@ -6224,6 +6146,11 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
clsx@^1.1.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
co@^4.6.0: co@^4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -14777,6 +14704,14 @@ react-dom@18.2.0:
loose-envify "^1.1.0" loose-envify "^1.1.0"
scheduler "^0.23.0" scheduler "^0.23.0"
react-draggable@^4.4.6:
version "4.4.6"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.6.tgz#63343ee945770881ca1256a5b6fa5c9f5983fe1e"
integrity sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==
dependencies:
clsx "^1.1.1"
prop-types "^15.8.1"
react-error-overlay@^6.0.11: react-error-overlay@^6.0.11:
version "6.0.11" version "6.0.11"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"