Merge pull request #333 from plebbit/development

Development
This commit is contained in:
Tom (plebeius.eth)
2024-04-07 18:37:51 +02:00
committed by GitHub
52 changed files with 679 additions and 249 deletions
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "الصفحة الرئيسية",
"subscribe": "اشتراك",
"unsubscribe": "إلغاء الاشتراك",
"close_post_form": "إغلاق نموذج المشاركة",
"close_post_form": "إغلاق نموذج المنشور",
"catalog": "فهرس",
"all": "الكل",
"subscriptions": "الاشتراكات",
@@ -36,5 +36,10 @@
"closed": "مغلق",
"reply": "رد",
"link": "رابط",
"close": "إغلاق"
"close": "إغلاق",
"post_a_reply": "أضف ردًا",
"view_thread": "عرض الموضوع",
"return": "العودة",
"bottom": "القاع",
"top": "أعلى"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "হোম",
"subscribe": "সাবস্ক্রাইব",
"unsubscribe": "অনুসংধান করতে পারবেন না",
"close_post_form": "পোস্ট ফরম বন্ধ করুন",
"close_post_form": "পোস্ট ফরম বন্ধ করুন",
"catalog": "ক্যাটালগ",
"all": "সব",
"subscriptions": "সাবস্ক্রিপশন",
@@ -36,5 +36,10 @@
"closed": "বন্ধ",
"reply": "উত্তর",
"link": "লিংক",
"close": "বন্ধ করুন"
"close": "বন্ধ করুন",
"post_a_reply": "একটি জবাব পোস্ট করুন",
"view_thread": "থ্রেড দেখুন",
"return": "ফিরে যাও",
"bottom": "নীচে",
"top": "শীর্ষ"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Domovská stránka",
"subscribe": "Přihlásit se k odběru",
"unsubscribe": "Odebrat odběr",
"close_post_form": "Zavřít formulář příspěvku",
"close_post_form": "Zavřít Formulář Příspěvku",
"catalog": "Katalog",
"all": "Vše",
"subscriptions": "Předplatné",
@@ -36,5 +36,10 @@
"closed": "Zavřeno",
"reply": "Odpovědět",
"link": "Odkaz",
"close": "Zavřít"
"close": "Zavřít",
"post_a_reply": "Zveřejnit Odpověď",
"view_thread": "Zobrazit Vlákno",
"return": "Návrat",
"bottom": "Dno",
"top": "Nahoře"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Hjem",
"subscribe": "Abonner",
"unsubscribe": "Afmeld",
"close_post_form": "Luk postformularen",
"close_post_form": "Luk Indlægsformular",
"catalog": "Katalog",
"all": "Alle",
"subscriptions": "Abonnementer",
@@ -36,5 +36,10 @@
"closed": "Lukket",
"reply": "Svar",
"link": "Link",
"close": "Luk"
"close": "Luk",
"post_a_reply": "Indsend Et Svar",
"view_thread": "Vis Tråd",
"return": "Vende tilbage",
"bottom": "Bund",
"top": "Top"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Startseite",
"subscribe": "Abonnieren",
"unsubscribe": "Abbestellen",
"close_post_form": "Postformular schließen",
"close_post_form": "Schließen Sie das Beitrag-Formular",
"catalog": "Katalog",
"all": "Alle",
"subscriptions": "Abonnements",
@@ -36,5 +36,10 @@
"closed": "Geschlossen",
"reply": "Antworten",
"link": "Link",
"close": "Schließen"
"close": "Schließen",
"post_a_reply": "Eine Antwort Posten",
"view_thread": "Thread Anzeigen",
"return": "Zurück",
"bottom": "Unten",
"top": "Oben"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Αρχική σελίδα",
"subscribe": "Εγγραφή",
"unsubscribe": "Διακοπή συνδρομής",
"close_post_form": "Κλείστε τη φόρμα δημοσίευσης",
"close_post_form": "Κλείστε τη Φόρμα Δημοσίευσης",
"catalog": "Κατάλογος",
"all": "Όλα",
"subscriptions": "Συνδρομές",
@@ -36,5 +36,10 @@
"closed": "Κλειστό",
"reply": "Απάντηση",
"link": "Σύνδεσμος",
"close": "Κλείσιμο"
"close": "Κλείσιμο",
"post_a_reply": "Δημοσίευση Απάντησης",
"view_thread": "Προβολή Νήματος",
"return": "Επιστροφή",
"bottom": "Κάτω",
"top": "Κορυφή"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Home",
"subscribe": "Subscribe",
"unsubscribe": "Unsubscribe",
"close_post_form": "Close post form",
"close_post_form": "Close Post Form",
"catalog": "Catalog",
"all": "All",
"subscriptions": "Subscriptions",
@@ -36,5 +36,10 @@
"closed": "Closed",
"reply": "Reply",
"link": "Link",
"close": "Close"
"close": "Close",
"post_a_reply": "Post a Reply",
"view_thread": "View Thread",
"return": "Return",
"bottom": "Bottom",
"top": "Top"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Inicio",
"subscribe": "Suscribirse",
"unsubscribe": "Cancelar suscripción",
"close_post_form": "Cerrar formulario de publicación",
"close_post_form": "Cerrar Formulario de Publicación",
"catalog": "Catálogo",
"all": "Todo",
"subscriptions": "Suscripciones",
@@ -36,5 +36,10 @@
"closed": "Cerrado",
"reply": "Responder",
"link": "Enlace",
"close": "Cerrar"
"close": "Cerrar",
"post_a_reply": "Publicar una Respuesta",
"view_thread": "Ver Hilo",
"return": "Regresar",
"bottom": "Fondo",
"top": "Arriba"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "خانه",
"subscribe": "اشتراک",
"unsubscribe": "لغو اشتراک",
"close_post_form": "بستن فرم پست",
"close_post_form": "بستن فرم ارسال",
"catalog": "کاتالوگ",
"all": "همه",
"subscriptions": "اشتراک‌ها",
@@ -36,5 +36,10 @@
"closed": "بسته",
"reply": "پاسخ",
"link": "لینک",
"close": "بستن"
"close": "بستن",
"post_a_reply": "ارسال یک پاسخ",
"view_thread": "مشاهده نخ",
"return": "برگشت",
"bottom": "پایین",
"top": "بالا"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Koti",
"subscribe": "Tilaa",
"unsubscribe": "Peruuta tilaus",
"close_post_form": "Sulje postilomake",
"close_post_form": "Sulje Julkaisulomake",
"catalog": "Luettelo",
"all": "Kaikki",
"subscriptions": "Tilaukset",
@@ -36,5 +36,10 @@
"closed": "Suljettu",
"reply": "Vastaa",
"link": "Linkki",
"close": "Sulje"
"close": "Sulje",
"post_a_reply": "Lähetä Vastaus",
"view_thread": "Näytä Ketju",
"return": "Palata",
"bottom": "Pohja",
"top": "Ylös"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Bahay",
"subscribe": "Mag-subscribe",
"unsubscribe": "Huwag mag-subscribe",
"close_post_form": "Isara ang porma ng post",
"close_post_form": "Isara ang Porma ng Post",
"catalog": "Katalogo",
"all": "Lahat",
"subscriptions": "Mga Subscription",
@@ -36,5 +36,10 @@
"closed": "Sarado",
"reply": "Tumugon",
"link": "Link",
"close": "Isara"
"close": "Isara",
"post_a_reply": "Mag-post ng Isang Tugon",
"view_thread": "Tingnan ang Thread",
"return": "Bumalik",
"bottom": "Ilalim",
"top": "Itaas"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Accueil",
"subscribe": "S'abonner",
"unsubscribe": "Se désabonner",
"close_post_form": "Fermer le formulaire de publication",
"close_post_form": "Fermer le Formulaire de Publication",
"catalog": "Catalogue",
"all": "Tous",
"subscriptions": "Abonnements",
@@ -36,5 +36,10 @@
"closed": "Fermé",
"reply": "Répondre",
"link": "Lien",
"close": "Fermer"
"close": "Fermer",
"post_a_reply": "Publier une Réponse",
"view_thread": "Voir le Fil",
"return": "Retour",
"bottom": "Bas",
"top": "Haut"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "סגור",
"reply": "הגב",
"link": "קישור",
"close": "סגור"
"close": "סגור",
"post_a_reply": "פרסם תגובה",
"view_thread": "הצג אשכול",
"return": "חזור",
"bottom": "תחתית",
"top": "עליון"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "बंद",
"reply": "जवाब दें",
"link": "लिंक",
"close": "बंद करें"
"close": "बंद करें",
"post_a_reply": "एक उत्तर पोस्ट करें",
"view_thread": "थ्रेड देखें",
"return": "वापस",
"bottom": "नीचे",
"top": "ऊपर"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Kezdőlap",
"subscribe": "Feliratkozás",
"unsubscribe": "Leiratkozás",
"close_post_form": "Bejegyzés űrlap bezárása",
"close_post_form": "Bejegyzés Űrlap Bezárása",
"catalog": "Katalógus",
"all": "Összes",
"subscriptions": "Előfizetések",
@@ -36,5 +36,10 @@
"closed": "Zárt",
"reply": "Válaszolás",
"link": "Hivatkozás",
"close": "Bezárás"
"close": "Bezárás",
"post_a_reply": "Válasz Postázása",
"view_thread": "Téma Megtekintése",
"return": "Visszatérés",
"bottom": "Alja",
"top": "Felső"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Beranda",
"subscribe": "Berlangganan",
"unsubscribe": "Berhenti berlangganan",
"close_post_form": "Tutup formulir kiriman",
"close_post_form": "Tutup Formulir Kiriman",
"catalog": "Katalog",
"all": "Semua",
"subscriptions": "Langganan",
@@ -36,5 +36,10 @@
"closed": "Tutup",
"reply": "Balas",
"link": "Tautan",
"close": "Tutup"
"close": "Tutup",
"post_a_reply": "Kirim Balasan",
"view_thread": "Lihat Thread",
"return": "Kembali",
"bottom": "Bawah",
"top": "Atas"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Home",
"subscribe": "Iscriviti",
"unsubscribe": "Lascia",
"close_post_form": "Chiudi modulo d'invio",
"close_post_form": "Chiudi Modulo d'Invio",
"catalog": "Catalogo",
"all": "Tutti",
"subscriptions": "Iscrizioni",
@@ -36,5 +36,10 @@
"closed": "Chiuso",
"reply": "Commenta",
"link": "Link",
"close": "Chiudi"
"close": "Chiudi",
"post_a_reply": "Invia un Commento",
"view_thread": "Visualizza Thread",
"return": "Indietro",
"bottom": "Vai sotto",
"top": "Vai sopra"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "閉鎖",
"reply": "返信",
"link": "リンク",
"close": "閉じる"
"close": "閉じる",
"post_a_reply": "返信を投稿する",
"view_thread": "スレッドを見る",
"return": "戻る",
"bottom": "下へ",
"top": "上へ"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "닫힘",
"reply": "답장",
"link": "링크",
"close": "닫기"
"close": "닫기",
"post_a_reply": "답글 게시",
"view_thread": "스레드 보기",
"return": "돌아 가기",
"bottom": "하단",
"top": "맨 위로"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "बंद",
"reply": "प्रतिसाद",
"link": "लिंक",
"close": "बंद करा"
"close": "बंद करा",
"post_a_reply": "उत्तर पोस्ट करा",
"view_thread": "थ्रेड पहा",
"return": "परत जा",
"bottom": "खाली",
"top": "वर"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Home",
"subscribe": "Abonneren",
"unsubscribe": "Afmelden",
"close_post_form": "Sluit postformulier",
"close_post_form": "Sluit Postformulier",
"catalog": "Catalogus",
"all": "Alles",
"subscriptions": "Abonnementen",
@@ -36,5 +36,10 @@
"closed": "Gesloten",
"reply": "Antwoord",
"link": "Link",
"close": "Sluiten"
"close": "Sluiten",
"post_a_reply": "Een Antwoord Plaatsen",
"view_thread": "Bekijk Thread",
"return": "Terugkeer",
"bottom": "Onderkant",
"top": "Boven"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Hjem",
"subscribe": "Abonner",
"unsubscribe": "Avslutt abonnement",
"close_post_form": "Lukk postskjema",
"close_post_form": "Lukk Innleggsformular",
"catalog": "Katalog",
"all": "Alle",
"subscriptions": "Abonnementer",
@@ -36,5 +36,10 @@
"closed": "Stengt",
"reply": "Svar",
"link": "Lenke",
"close": "Lukk"
"close": "Lukk",
"post_a_reply": "Legg Inn Et Svar",
"view_thread": "Vis Tråd",
"return": "Retur",
"bottom": "Bunnen",
"top": "Topp"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Strona główna",
"subscribe": "Subskrybuj",
"unsubscribe": "Wypisz się",
"close_post_form": "Zamknij formularz postu",
"close_post_form": "Zamknij Formularz Postu",
"catalog": "Katalog",
"all": "Wszystkie",
"subscriptions": "Subskrypcje",
@@ -36,5 +36,10 @@
"closed": "Zamknięty",
"reply": "Odpowiedz",
"link": "Link",
"close": "Zamknij"
"close": "Zamknij",
"post_a_reply": "Opublikuj Odpowiedź",
"view_thread": "Zobacz Wątek",
"return": "Powrót",
"bottom": "Dół",
"top": "Góra"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Início",
"subscribe": "Subscrever",
"unsubscribe": "Cancelar subscrição",
"close_post_form": "Fechar formulário de postagem",
"close_post_form": "Fechar Formulário de Publicação",
"catalog": "Catálogo",
"all": "Todos",
"subscriptions": "Inscrições",
@@ -36,5 +36,10 @@
"closed": "Fechado",
"reply": "Responder",
"link": "Link",
"close": "Fechar"
"close": "Fechar",
"post_a_reply": "Publicar uma Resposta",
"view_thread": "Ver Tópico",
"return": "Retorno",
"bottom": "Fundo",
"top": "Topo"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Acasă",
"subscribe": "Abonare",
"unsubscribe": "Dezabonare",
"close_post_form": "Închideți formularul de postare",
"close_post_form": "Închideți Formularul de Postare",
"catalog": "Catalog",
"all": "Toate",
"subscriptions": "Abonamente",
@@ -36,5 +36,10 @@
"closed": "Închis",
"reply": "Răspunde",
"link": "Legătură",
"close": "Închide"
"close": "Închide",
"post_a_reply": "Postează un Răspuns",
"view_thread": "Vizualizați Firul",
"return": "Întoarcere",
"bottom": "Partea de jos",
"top": "Sus"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Главная",
"subscribe": "Подписаться",
"unsubscribe": "Отписаться",
"close_post_form": "Закрыть форму публикации",
"close_post_form": "Закрыть Форму Публикации",
"catalog": "Каталог",
"all": "Все",
"subscriptions": "Подписки",
@@ -36,5 +36,10 @@
"closed": "Закрыто",
"reply": "Ответить",
"link": "Ссылка",
"close": "Закрыть"
"close": "Закрыть",
"post_a_reply": "Опубликовать Ответ",
"view_thread": "Посмотреть Тему",
"return": "Возвращение",
"bottom": "Низ",
"top": "Верх"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Faqja kryesore",
"subscribe": "Pajtohu",
"unsubscribe": "Hiq pajtimin",
"close_post_form": "Mbyllni formularin e postës",
"close_post_form": "Mbyll Formularin e Postës",
"catalog": "Katalog",
"all": "Të gjitha",
"subscriptions": "Abonimet",
@@ -36,5 +36,10 @@
"closed": "Mbyllur",
"reply": "Përgjigju",
"link": "Lidhje",
"close": "Mbylle"
"close": "Mbylle",
"post_a_reply": "Posto një Përgjigje",
"view_thread": "Shiko Thread",
"return": "Kthimi",
"bottom": "Fund",
"top": "Sipër"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Hem",
"subscribe": "Prenumerera",
"unsubscribe": "Avsluta prenumeration",
"close_post_form": "Stäng inläggsformuläret",
"close_post_form": "Stäng Inläggsformuläret",
"catalog": "Katalog",
"all": "Allt",
"subscriptions": "Prenumerationer",
@@ -36,5 +36,10 @@
"closed": "Stängd",
"reply": "Svara",
"link": "Länk",
"close": "Stäng"
"close": "Stäng",
"post_a_reply": "Posta Ett Svar",
"view_thread": "Visa Tråd",
"return": "Återgång",
"bottom": "Botten",
"top": "Topp"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "హోమ్",
"subscribe": "చేరండి",
"unsubscribe": "సబ్‌స్క్రిప్షన్ రద్దు చేయండి",
"close_post_form": "పోస్ట ఫారమ్ మూసేయి",
"close_post_form": "పోస్ట ఫార మూసించు",
"catalog": "కాటలాగ్",
"all": "అన్ని",
"subscriptions": "సబ్‌స్క్రిప్షన్‌లు",
@@ -36,5 +36,10 @@
"closed": "మూసివేయబడినది",
"reply": "స్పందించు",
"link": "లింక్",
"close": "మూసి"
"close": "మూసి",
"post_a_reply": "స్పందించండి",
"view_thread": "థ్రెడ్‌ను చూడండి",
"return": "రిటర్న్",
"bottom": "కిందకు",
"top": "మేలే"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "ปิด",
"reply": "ตอบ",
"link": "ลิงก์",
"close": "ปิด"
"close": "ปิด",
"post_a_reply": "โพสต์คำตอบ",
"view_thread": "ดูกระทู้",
"return": "กลับ",
"bottom": "ด้านล่าง",
"top": "ด้านบน"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Anasayfa",
"subscribe": "Abone Ol",
"unsubscribe": "Abonelikten çık",
"close_post_form": "Gönderi formunu kapat",
"close_post_form": "Yazı Formunu Kapat",
"catalog": "Katalog",
"all": "Tümü",
"subscriptions": "Abonelikler",
@@ -36,5 +36,10 @@
"closed": "Kapalı",
"reply": "Yanıtla",
"link": "Bağlantı",
"close": "Kapat"
"close": "Kapat",
"post_a_reply": "Yanıtı Yayınla",
"view_thread": "Konuyu Görüntüle",
"return": "Dönüş",
"bottom": "Alt",
"top": "Üst"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Головна",
"subscribe": "Підписатися",
"unsubscribe": "Відмовитися від підписки",
"close_post_form": "Закрити форму публікації",
"close_post_form": "Закрити Форму Публікації",
"catalog": "Каталог",
"all": "Всі",
"subscriptions": "Підписки",
@@ -36,5 +36,10 @@
"closed": "Закрито",
"reply": "Відповісти",
"link": "Посилання",
"close": "Закрити"
"close": "Закрити",
"post_a_reply": "Опублікувати Відповідь",
"view_thread": "Переглянути Тему",
"return": "Повернення",
"bottom": "Низ",
"top": "Верхній"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "بند",
"reply": "جواب دیں",
"link": "لنک",
"close": "بند کریں"
"close": "بند کریں",
"post_a_reply": "ایک جواب بھیجیں",
"view_thread": "تھریڈ دیکھیں",
"return": "واپس",
"bottom": "نیچے",
"top": "اوپر"
}
+7 -2
View File
@@ -25,7 +25,7 @@
"home": "Trang chủ",
"subscribe": "Đăng ký",
"unsubscribe": "Hủy đăng ký",
"close_post_form": "Đóng biểu mẫu đăng bài",
"close_post_form": "Đóng Biểu Mẫu Bài Viết",
"catalog": "Catalog",
"all": "Tất cả",
"subscriptions": "Đăng ký",
@@ -36,5 +36,10 @@
"closed": "Đóng",
"reply": "Trả lời",
"link": "Liên kết",
"close": "Đóng"
"close": "Đóng",
"post_a_reply": "Đăng Một Câu Trả Lời",
"view_thread": "Xem Chủ Đề",
"return": "Trở lại",
"bottom": "Đáy",
"top": "Đầu"
}
+6 -1
View File
@@ -36,5 +36,10 @@
"closed": "关闭",
"reply": "回复",
"link": "链接",
"close": "关闭"
"close": "关闭",
"post_a_reply": "发表回复",
"view_thread": "查看线程",
"return": "返回",
"bottom": "底部",
"top": "顶部"
}
+8 -6
View File
@@ -1,11 +1,12 @@
import { useEffect } from 'react';
import React, { useEffect } from 'react';
import { Outlet, Route, Routes, useLocation, useParams } from 'react-router-dom';
import { isHomeView } from './lib/utils/view-utils';
import { Subplebbit as SubplebbitType, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { Subplebbit as SubplebbitType, useSubplebbit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { useDefaultSubplebbitAddresses } from './hooks/use-default-subplebbits';
import useTheme from './hooks/use-theme';
import styles from './app.module.css';
import Home from './views/home';
import PostPage from './views/post-page';
import Settings from './views/settings';
import Subplebbit from './views/subplebbit';
import BoardNav from './components/board-nav';
@@ -19,9 +20,9 @@ interface BoardLayoutProps {
subplebbits: (SubplebbitType | undefined)[];
}
const BoardLayout = ({ subplebbits }: BoardLayoutProps) => {
const BoardLayout = React.memo(({ subplebbits }: BoardLayoutProps) => {
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
const subplebbit = subplebbits.find((s) => s?.address === subplebbitAddress);
const subplebbit = useSubplebbit({ subplebbitAddress });
const { address, createdAt, title } = subplebbit || {};
return (
@@ -39,7 +40,7 @@ const BoardLayout = ({ subplebbits }: BoardLayoutProps) => {
<Outlet />
</>
);
};
});
const App = () => {
const [theme] = useTheme();
@@ -66,7 +67,8 @@ const App = () => {
<Routes>
<Route path='/' element={<Home subplebbits={subplebbits} />} />
<Route element={<BoardLayout subplebbits={subplebbits} />}>
<Route path='/p/:subplebbitAddress' element={<Subplebbit subplebbits={subplebbits} />} />
<Route path='/p/:subplebbitAddress' element={<Subplebbit />} />
<Route path='/p/:subplebbitAddress/c/:commentCid' element={<PostPage />} />
</Route>
<Route path='/settings' element={<Settings />} />
</Routes>
@@ -5,6 +5,16 @@
.mobileBoardButtons button {
margin: 0 2px;
text-transform: capitalize;
}
.mobileBoardButtons a, .desktopBoardButtons a {
all: unset;
}
.mobilePostPageButtonsSecondRow {
padding-top: 5px;
padding-bottom: 20px;
}
@media (max-width: 640px) {
+61 -14
View File
@@ -1,6 +1,8 @@
import { useTranslation } from 'react-i18next';
import { Link, useLocation, useParams } from 'react-router-dom';
import { useSubscribe } from '@plebbit/plebbit-react-hooks';
import styles from './board-buttons.module.css';
import { useTranslation } from 'react-i18next';
import { isPostPageView } from '../../lib/utils/view-utils';
interface BoardButtonsProps {
address: string;
@@ -11,9 +13,13 @@ const OptionsButton = () => {
return <button className='button'>{t('options')}</button>;
};
const CatalogButton = () => {
const CatalogButton = ({ address }: BoardButtonsProps) => {
const { t } = useTranslation();
return <button className='button'>{t('catalog')}</button>;
return (
<button className='button'>
<Link to={`/p/${address}/catalog`}>{t('catalog')}</Link>
</button>
);
};
const SubscribeButton = ({ address }: BoardButtonsProps) => {
@@ -27,28 +33,69 @@ const SubscribeButton = ({ address }: BoardButtonsProps) => {
);
};
const ReturnButton = ({ address }: BoardButtonsProps) => {
const { t } = useTranslation();
return (
<button className='button'>
<Link to={`/p/${address}`}>{t('return')}</Link>
</button>
);
};
const BottomButton = () => {
const { t } = useTranslation();
return (
<button className='button' onClick={() => window.scrollTo(0, document.body.scrollHeight)}>
{t('bottom')}
</button>
);
};
export const MobileBoardButtons = ({ address }: BoardButtonsProps) => {
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
return (
<div className={styles.mobileBoardButtons}>
<OptionsButton />
<CatalogButton />
<SubscribeButton address={address} />
{isInPostPage ? (
<div className={styles.mobilePostPageButtons}>
<ReturnButton address={address} />
<CatalogButton address={address} />
<BottomButton />
<div className={styles.mobilePostPageButtonsSecondRow}>
<OptionsButton />
<SubscribeButton address={address} />
</div>
</div>
) : (
<>
<OptionsButton />
<CatalogButton address={address} />
<SubscribeButton address={address} />
</>
)}
</div>
);
};
export const DesktopBoardButtons = ({ address }: BoardButtonsProps) => {
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
return (
<div className={styles.desktopBoardButtons}>
<hr />
[
<OptionsButton />
] [
<CatalogButton />]
<span className={styles.subscribeButton}>
[
<SubscribeButton address={address} />]
</span>
{isInPostPage ? (
<>
[<ReturnButton address={address} />] [<CatalogButton address={address} />] [<BottomButton />] [<OptionsButton />]
<span className={styles.subscribeButton}>
[<SubscribeButton address={address} />]
</span>
</>
) : (
<>
[<OptionsButton />] [<CatalogButton address={address} />]
<span className={styles.subscribeButton}>
[<SubscribeButton address={address} />]
</span>
</>
)}
</div>
);
};
+2 -2
View File
@@ -1,4 +1,4 @@
import { useMemo } from 'react';
import React, { useMemo } from 'react';
import styles from './markdown.module.css';
import ReactMarkdown from 'react-markdown';
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
@@ -77,4 +77,4 @@ const Markdown = ({ content }: MarkdownProps) => {
);
};
export default Markdown;
export default React.memo(Markdown);
+2 -2
View File
@@ -1,5 +1,5 @@
.thumbnailBig {
background-color: var(--post-thumbnail-background-color);
background-color: var(--media-thumbnail-background-color);
width: var(--width);
height: var(--height);
margin: 3px 20px 5px 0;
@@ -9,7 +9,7 @@
}
.thumbnailSmall {
background-color: var(--post-thumbnail-background-color);
background-color: var(--media-thumbnail-background-color);
width: var(--width);
height: var(--height);
margin: 3px 10px 5px 5px;
+6 -3
View File
@@ -1,6 +1,8 @@
import { useState } from 'react';
import styles from './post-form.module.css';
import { useTranslation } from 'react-i18next';
import styles from './post-form.module.css';
import { isPostPageView } from '../../lib/utils/view-utils';
import { useLocation, useParams } from 'react-router-dom';
export interface PostFormProps {
address: string | undefined;
@@ -9,19 +11,20 @@ export interface PostFormProps {
const PostForm = ({ address }: PostFormProps) => {
const { t } = useTranslation();
const [showForm, setShowForm] = useState(false);
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
return (
<>
<div className={styles.postFormButtonDesktop}>
[
<button className='button' onClick={() => setShowForm(true)}>
{t('start_new_thread')}
{isInPostPage ? t('post_a_reply') : t('start_new_thread')}
</button>
]
</div>
<div className={styles.postFormButtonMobile}>
<button className='button' onClick={() => setShowForm(!showForm)}>
{showForm ? t('close_post_form') : t('start_new_thread')}
{showForm ? t('close_post_form') : isInPostPage ? t('post_a_reply') : t('start_new_thread')}
</button>
</div>
</>
+35 -5
View File
@@ -10,12 +10,12 @@
padding: 0.5em 0; /* instead of using margin, wrap with padding */
}
.threadHideButtonWrapper {
.hideButtonWrapper {
padding-right: 5px;
float: left;
}
.postDesktop .threadHideButton {
.postDesktop .hideButton {
background-repeat: no-repeat;
background-position: center;
width: 18px;
@@ -23,9 +23,10 @@
display: inline-block;
image-rendering: pixelated;
cursor: pointer;
transform: translateY(-1px);
}
/* clearfix to the container of the floatied elements to contain them */
/* clearfix to contain float elements */
.postDesktop::after {
content: "";
display: table;
@@ -155,9 +156,17 @@
.postDesktop .summary {
padding-top: 10px;
padding-left: 23px;
position: relative;
color: var(--post-mobile-abbr-text-color);
}
.postDesktop .summary .expandButtonWrapper {
position: absolute;
top: 8px;
left: 2px;
}
.postDesktop .summary .expandButton {
background-image: var(--post-replies-expand-button-background-image);
background-repeat: no-repeat;
@@ -166,7 +175,6 @@
height: 18px;
display: inline-block;
image-rendering: pixelated;
margin: 0 3px -4px 2px;
cursor: pointer;
}
@@ -180,6 +188,13 @@
text-decoration: var(--post-content-link-text-decoration-hover);
}
/* clearfix to contain float elements */
.postMobile .postOp::after {
content: "";
display: table;
clear: both;
}
.postMobile hr {
padding-bottom: 30px;
}
@@ -202,7 +217,9 @@
.postMobile .postInfo {
overflow: hidden;
border-bottom: var(--post-mobile-info-border-bottom);
border-top: var(--post-mobile-info-border-top);
background-color: var(--post-mobile-info-background-color);
color: var(--post-mobile-info-text-color);
padding: 5px;
clear: left;
}
@@ -303,15 +320,26 @@
padding: 3px 3px 0 0;
}
.quoteLink {
color: var(--post-quotelink-text-color);
text-decoration: var(--post-quotelink-text-decoration);
}
.quoteLink:hover {
color: var(--post-quotelink-text-color-hover);
text-decoration: var(--post-quotelink-text-decoration-hover);
}
.replyMobile {
padding-top: 7px;
}
.replyMobile .replyContainer {
background-color: var(--post-mobile-background-color);
border-bottom: var(--post-mobile-border-bottom);
}
/* clearfix to the container of the floatied elements to contain them */
/* clearfix to contain float elements */
.replyMobile .replyContainer::after {
content: "";
display: table;
@@ -320,8 +348,10 @@
.replyMobile .postInfo {
padding: 5px;
border-top: var(--post-mobile-info-border-top);
border-bottom: var(--post-mobile-info-border-bottom);
background-color: var(--post-mobile-info-background-color);
color: var(--post-mobile-info-text-color);
}
.replyMobile .postInfo .postMenuBtn {
+167 -127
View File
@@ -1,103 +1,116 @@
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { Link, useLocation, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Comment } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
import { getCommentMediaInfoMemoized, getHasThumbnail } from '../../lib/utils/media-utils';
import { getFormattedDate } from '../../lib/utils/time-utils';
import { isPostPageView } from '../../lib/utils/view-utils';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import useReplies from '../../hooks/use-replies';
import styles from './post.module.css';
import Markdown from '../markdown';
import Media from '../media';
const ReplyDesktop = ({ index, reply }: { index: number; reply: Comment }) => {
const ReplyDesktop = ({ reply }: Comment) => {
const { t } = useTranslation();
const { author, content, link, linkHeight, linkWidth, pinned, shortCid, subplebbitAddress, timestamp } = reply || {};
const { author, content, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, subplebbitAddress, timestamp } = reply || {};
const { displayName, shortAddress } = author || {};
const commentMediaInfo = getCommentMediaInfoMemoized(reply);
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
const [showThumbnail, setShowThumbnail] = useState(true);
const isReplyingToReply = postCid !== parentCid;
return (
index < 5 && (
<div className={styles.replyDesktop}>
<div className={styles.sideArrows}>{'>>'}</div>
<div className={styles.reply}>
<div className={styles.postInfo}>
<span className={styles.checkbox}>
<input type='checkbox' />
</span>
<span className={styles.nameBlock}>
<span className={styles.name}>{displayName || 'Anonymous'} </span>
<span className={styles.userAddress}>(u/{shortAddress}) </span>
</span>
<span className={styles.dateTime}>{getFormattedDate(timestamp)} </span>
<span className={styles.postNum}>
<span className={styles.postNumLink}>
<Link to={`/p/${subplebbitAddress}/c/${reply.cid}`} className={styles.linkToPost} title='Link to post'>
c/
</Link>
<span className={styles.replyToPost} title='Reply to post'>
{shortCid}
</span>
<div className={styles.replyDesktop}>
<div className={styles.sideArrows}>{'>>'}</div>
<div className={styles.reply}>
<div className={styles.postInfo}>
<span className={styles.checkbox}>
<input type='checkbox' />
</span>
<span className={styles.nameBlock}>
<span className={styles.name}>{displayName || 'Anonymous'} </span>
<span className={styles.userAddress}>(u/{shortAddress}) </span>
</span>
<span className={styles.dateTime}>{getFormattedDate(timestamp)} </span>
<span className={styles.postNum}>
<span className={styles.postNumLink}>
<Link to={`/p/${subplebbitAddress}/c/${reply.cid}`} className={styles.linkToPost} title='Link to post'>
c/
</Link>
<span className={styles.replyToPost} title='Reply to post'>
{shortCid}
</span>
{pinned && (
<span className={styles.stickyIconWrapper}>
<img src='assets/icons/sticky.gif' alt='' className={styles.stickyIcon} title={t('sticky')} />
</span>
)}
</span>
<span className={styles.postMenuBtn}></span>
</div>
{link && (
<div className={styles.file}>
<div className={styles.fileText}>
{t('link')}:{' '}
<a href={link} target='_blank' rel='noopener noreferrer'>
{link.length > 30 ? link.slice(0, 30) + '...' : link}
</a>
{!showThumbnail && (commentMediaInfo?.type === 'iframe' || commentMediaInfo?.type === 'video') && (
<span>
{' '}
[
<span className={styles.closeMedia} onClick={() => setShowThumbnail(true)}>
{t('close')}
</span>
]
{pinned && (
<span className={styles.stickyIconWrapper}>
<img src='assets/icons/sticky.gif' alt='' className={styles.stickyIcon} title={t('sticky')} />
</span>
)}
</span>
<span className={styles.postMenuBtn}></span>
</div>
{link && (
<div className={styles.file}>
<div className={styles.fileText}>
{t('link')}:{' '}
<a href={link} target='_blank' rel='noopener noreferrer'>
{link.length > 30 ? link?.slice(0, 30) + '...' : link}
</a>
{!showThumbnail && (commentMediaInfo?.type === 'iframe' || commentMediaInfo?.type === 'video') && (
<span>
{' '}
[
<span className={styles.closeMedia} onClick={() => setShowThumbnail(true)}>
{t('close')}
</span>
)}
</div>
{hasThumbnail && (
<Media
commentMediaInfo={commentMediaInfo}
isMobile={false}
isReply={true}
linkHeight={linkHeight}
linkWidth={linkWidth}
showThumbnail={showThumbnail}
setShowThumbnail={setShowThumbnail}
/>
]
</span>
)}
</div>
)}
{content && (
<blockquote className={styles.postMessage}>
<Markdown content={content} />
</blockquote>
)}
</div>
{hasThumbnail && (
<Media
commentMediaInfo={commentMediaInfo}
isMobile={false}
isReply={true}
linkHeight={linkHeight}
linkWidth={linkWidth}
showThumbnail={showThumbnail}
setShowThumbnail={setShowThumbnail}
/>
)}
</div>
)}
{content && (
<blockquote className={styles.postMessage}>
{isReplyingToReply && (
<>
<Link to={`/p/${subplebbitAddress}/c/${parentCid}`} className={styles.quoteLink}>
{`c/${Plebbit.getShortCid(parentCid)}`}
</Link>
<br />
</>
)}
<Markdown content={content} />
</blockquote>
)}
</div>
)
</div>
);
};
const PostDesktop = ({ post }: Comment) => {
const PostDesktop = ({ post, showAllReplies }: { post: Comment; showAllReplies: boolean }) => {
const { t } = useTranslation();
const { author, cid, content, link, linkHeight, linkWidth, locked, pinned, postCid, replyCount, shortCid, subplebbitAddress, timestamp, title } = post || {};
const { displayName, shortAddress } = author || {};
const displayTitle = title && title.length > 75 ? title.slice(0, 75) + '...' : title;
const displayContent = content && content.length > 1000 ? content.slice(0, 1000) + '(...)' : content;
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
const displayTitle = title && title.length > 75 ? title?.slice(0, 75) + '...' : title;
const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) + '(...)' : content;
const commentMediaInfo = getCommentMediaInfoMemoized(post);
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
@@ -114,15 +127,17 @@ const PostDesktop = ({ post }: Comment) => {
<div className={styles.hrWrapper}>
<hr />
</div>
<span className={styles.threadHideButtonWrapper}>
<span className={`${styles.threadHideButton} ${styles.hideThread}`} />
</span>
{!isInPostPage && (
<span className={styles.hideButtonWrapper}>
<span className={`${styles.hideButton} ${styles.hideThread}`} />
</span>
)}
{commentMediaInfo?.url && (
<div className={styles.file}>
<div className={styles.fileText}>
{t('link')}:{' '}
<a href={commentMediaInfo?.url} target='_blank' rel='noopener noreferrer'>
{commentMediaInfo.url.length > 30 ? commentMediaInfo?.url.slice(0, 30) + '...' : commentMediaInfo?.url}
{commentMediaInfo.url.length > 30 ? commentMediaInfo?.url?.slice(0, 30) + '...' : commentMediaInfo?.url}
</a>{' '}
({commentMediaInfo?.type})
{!showThumbnail && (commentMediaInfo?.type === 'iframe' || commentMediaInfo?.type === 'video') && (
@@ -188,7 +203,7 @@ const PostDesktop = ({ post }: Comment) => {
{content && (
<blockquote className={styles.postMessage}>
<Markdown content={displayContent} />
{content.length > 1000 && (
{content.length > 1000 && !isInPostPage && (
<span className={styles.abbr}>
<br />
Comment too long. <Link to={`/p/${subplebbitAddress}/c/${cid}`}>Click here</Link> to view the full text.
@@ -196,17 +211,20 @@ const PostDesktop = ({ post }: Comment) => {
)}
</blockquote>
)}
{(replies.length > 5 || pinned) && (
{(replies.length > 5 || pinned) && !isInPostPage && (
<span className={styles.summary}>
<span className={styles.expandButton} />
<span className={styles.expandButtonWrapper}>
<span className={styles.expandButton} />
</span>
<span>
{repliesCount} replies {linkCount > 0 && `and ${linkCount} links`} omitted.{' '}
</span>
<Link to={`/p/${subplebbitAddress}/c/${cid}`}>Click here</Link> to view.
</span>
)}
{!pinned &&
replies.map((reply, index) => (
{!(pinned && !isInPostPage) &&
replies &&
replies.slice(0, showAllReplies ? replies.length : 5).map((reply, index) => (
<div key={reply.cid} className={styles.replyContainer}>
<ReplyDesktop index={index} reply={reply} />
</div>
@@ -215,57 +233,70 @@ const PostDesktop = ({ post }: Comment) => {
);
};
const ReplyMobile = ({ index, reply }: { index: number; reply: Comment }) => {
const { author, content, link, linkHeight, linkWidth, pinned, shortCid, subplebbitAddress, timestamp } = reply || {};
const ReplyMobile = ({ reply }: Comment) => {
const { author, content, link, linkHeight, linkWidth, parentCid, pinned, postCid, shortCid, subplebbitAddress, timestamp } = reply || {};
const { displayName, shortAddress } = author || {};
const commentMediaInfo = getCommentMediaInfoMemoized(reply);
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
const [showThumbnail, setShowThumbnail] = useState(true);
const isReplyingToReply = postCid !== parentCid;
return (
index < 5 && (
<div className={styles.replyMobile}>
<div className={styles.reply}>
<div className={styles.replyContainer}>
<div className={styles.postInfo}>
<span className={styles.postMenuBtn}>...</span>
<span className={styles.nameBlock}>
<span className={styles.name}>{displayName || 'Anonymous'} </span>
<span className={styles.address}>(u/{shortAddress})</span>
</span>
<span className={styles.dateTimePostNum}>
{getFormattedDate(timestamp)} <span className={styles.linkToPost}>c/</span>
<span className={styles.replyToPost}>{shortCid}</span>
</span>
</div>
{hasThumbnail && (
<Media
commentMediaInfo={commentMediaInfo}
isMobile={true}
isReply={false}
linkHeight={linkHeight}
linkWidth={linkWidth}
showThumbnail={showThumbnail}
setShowThumbnail={setShowThumbnail}
/>
)}
<div className={styles.replyMobile}>
<div className={styles.reply}>
<div className={styles.replyContainer}>
<div className={styles.postInfo}>
<span className={styles.postMenuBtn}>...</span>
<span className={styles.nameBlock}>
<span className={styles.name}>{displayName || 'Anonymous'} </span>
<span className={styles.address}>(u/{shortAddress})</span>
</span>
<span className={styles.dateTimePostNum}>
{getFormattedDate(timestamp)} <span className={styles.linkToPost}>c/</span>
<span className={styles.replyToPost}>{shortCid}</span>
</span>
</div>
{hasThumbnail && (
<Media
commentMediaInfo={commentMediaInfo}
isMobile={true}
isReply={false}
linkHeight={linkHeight}
linkWidth={linkWidth}
showThumbnail={showThumbnail}
setShowThumbnail={setShowThumbnail}
/>
)}
{content && (
<blockquote className={styles.postMessage}>
{isReplyingToReply && (
<>
<Link to={`/p/${subplebbitAddress}/c/${parentCid}`} className={styles.quoteLink}>
{`c/${Plebbit.getShortCid(parentCid)}`}
</Link>
<br />
</>
)}
<Markdown content={content} />
</blockquote>
</div>
)}
</div>
</div>
)
</div>
);
};
const PostMobile = ({ post }: Comment) => {
const PostMobile = ({ post, showAllReplies }: { post: Comment; showAllReplies: boolean }) => {
const { t } = useTranslation();
const { author, cid, content, link, linkHeight, linkWidth, pinned, replyCount, shortCid, subplebbitAddress, timestamp, title } = post || {};
const { address, displayName, shortAddress } = author || {};
const linkCount = useCountLinksInReplies(post);
const displayTitle = title && title.length > 30 ? title.slice(0, 30) + '(...)' : title;
const displayContent = content && content.length > 1000 ? content.slice(0, 1000) : content;
const isInPostPage = isPostPageView(useLocation().pathname, useParams());
const displayTitle = title && title.length > 30 ? title?.slice(0, 30) + '(...)' : title;
const displayContent = content && !isInPostPage && content.length > 1000 ? content?.slice(0, 1000) : content;
const commentMediaInfo = getCommentMediaInfoMemoized(post);
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
@@ -287,7 +318,7 @@ const PostMobile = ({ post }: Comment) => {
</span>
<span className={styles.nameBlock}>
<span className={styles.name}>{displayName || 'Anonymous'} </span>
<span className={styles.address}>(u/{shortAddress || address.slice(0, 12) + '...'})</span>
<span className={styles.address}>(u/{shortAddress || address?.slice(0, 12) + '...'})</span>
{title && (
<>
<br />
@@ -314,7 +345,7 @@ const PostMobile = ({ post }: Comment) => {
{content && (
<blockquote className={`${styles.postMessage} ${styles.clampLines}`}>
<Markdown content={displayContent} />
{content.length > 1000 && (
{content.length > 1000 && !isInPostPage && (
<span className={styles.abbr}>
<br />
Comment too long. <Link to={`/p/${subplebbitAddress}/c/${cid}`}>Click here</Link> to view the full text.
@@ -323,18 +354,21 @@ const PostMobile = ({ post }: Comment) => {
</blockquote>
)}
</div>
<div className={styles.postLink}>
<span className={styles.info}>
{replyCount} Replies
{linkCount > 0 && ` / ${linkCount} Links`}
</span>
<Link to={`/p/${subplebbitAddress}/c/${cid}`} className='button'>
View Thread
</Link>
</div>
{!isInPostPage && (
<div className={styles.postLink}>
<span className={styles.info}>
{replyCount} Replies
{linkCount > 0 && ` / ${linkCount} Links`}
</span>
<Link to={`/p/${subplebbitAddress}/c/${cid}`} className='button'>
{t('view_thread')}
</Link>
</div>
)}
</div>
{!pinned &&
replies.map((reply, index) => (
{!(pinned && !isInPostPage) &&
replies &&
replies.slice(0, showAllReplies ? replies.length : 5).map((reply, index) => (
<div key={reply.cid} className={styles.replyContainer}>
<ReplyMobile index={index} reply={reply} />
</div>
@@ -344,12 +378,18 @@ const PostMobile = ({ post }: Comment) => {
);
};
const Post = ({ post }: Comment) => {
interface PostProps {
index?: number;
post: Comment;
showAllReplies?: boolean;
}
const Post = ({ post, showAllReplies = false }: PostProps) => {
return (
<div className={styles.thread}>
<div className={styles.postContainer}>
<PostDesktop post={post} />
<PostMobile post={post} />
<PostDesktop post={post} showAllReplies={showAllReplies} />
<PostMobile post={post} showAllReplies={showAllReplies} />
</div>
</div>
);
+6 -4
View File
@@ -1,27 +1,29 @@
import { useMemo, useCallback } from 'react';
import { Comment, useAccountComments } from '@plebbit/plebbit-react-hooks';
import { flattenCommentsPages } from '@plebbit/plebbit-react-hooks/dist/lib/utils';
const useRepliesAndAccountReplies = (comment: Comment) => {
// filter only the parent cid
const filter = useCallback((accountComment: Comment) => accountComment.parentCid === (comment?.cid || 'n/a'), [comment?.cid]);
const { accountComments } = useAccountComments({ filter });
const flattenedReplies = useMemo(() => flattenCommentsPages(comment.replies), [comment.replies]);
// the account's replies have a delay before getting published, so get them locally from accountComments instead
const accountRepliesNotYetPublished = useMemo(() => {
const replies = comment?.replies?.pages?.topAll?.comments || [];
const replies = flattenedReplies || [];
const replyCids = new Set(replies.map((reply: Comment) => reply?.cid));
// filter out the account comments already in comment.replies, so they don't appear twice
return accountComments.filter((accountReply) => !replyCids.has(accountReply?.cid));
}, [comment?.replies?.pages?.topAll?.comments, accountComments]);
}, [flattenedReplies, accountComments]);
const repliesAndNotYetPublishedReplies = useMemo(() => {
return [
// put the author's unpublished replies at the top, latest first (reverse)
...accountRepliesNotYetPublished.reverse(),
// put the published replies after,
...(comment?.replies?.pages?.topAll?.comments || []),
...(flattenedReplies || []),
];
}, [comment?.replies?.pages?.topAll?.comments, accountRepliesNotYetPublished]);
}, [flattenedReplies, accountRepliesNotYetPublished]);
return repliesAndNotYetPublishedReplies;
};
-1
View File
@@ -24,7 +24,6 @@ hr {
@media (max-width: 640px) {
.button {
text-transform: capitalize;
font-size: var(--button-font-size-mobile);
font-weight: var(--button-font-weight-mobile);
font-family: var(--button-font-family-mobile);
+11
View File
@@ -1,3 +1,14 @@
export type ParamsType = {
commentCid?: string;
subplebbitAddress?: string;
};
export const isHomeView = (pathname: string): boolean => {
return pathname === '/';
};
export const isPostPageView = (pathname: string, params: ParamsType): boolean => {
// some subs might use emojis in their address, so we need to decode the pathname
const decodedPathname = decodeURIComponent(pathname);
return params.subplebbitAddress && params.commentCid ? decodedPathname.startsWith(`/p/${params.subplebbitAddress}/c/${params.commentCid}`) : false;
};
+101 -7
View File
@@ -68,6 +68,9 @@
--post-content-link-text-decoration: none;
--post-content-link-text-decoration-hover: none;
/* media */
--media-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post desktop */
--post-hide-button-background-image: url("/public/assets/buttons/post-expand-minus-red.png");
--post-unhide-button-background-image: url("/public/assets/buttons/post-expand-plus-red.png");
@@ -97,7 +100,11 @@
--post-mobile-file-info-text-color: #707070;
--post-mobile-content-font-size: 11pt;
--post-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* quotelink */
--post-quotelink-text-color: navy;
--post-quotelink-text-color-hover: red;
--post-quotelink-text-decoration: underline;
--post-quotelink-text-decoration-hover: underline;
/* reply desktop */
--side-arrows-color: #e0bfb7;
@@ -180,6 +187,9 @@
--post-content-link-text-decoration: none;
--post-content-link-text-decoration-hover: none;
/* media */
--media-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post */
--post-hide-button-background-image: url("/public/assets/buttons/post-expand-minus-blue.png");
--post-unhide-button-background-image: url("/public/assets/buttons/post-expand-plus-blue.png");
@@ -197,7 +207,7 @@
--post-mobile-info-border-bottom: 1px solid #b7c5d9;
--post-mobile-info-background-color: #c9cde8;
--post-mobile-menu-button-color: #34345c;
--post-mobile-name-text-color: purple;
--post-mobile-name-text-color: #117743;
--post-mobile-name-font-weight: 700;
--post-mobile-subject-text-color: #0f0c5d;
--post-mobile-subject-font-weight: 700;
@@ -208,7 +218,11 @@
--post-mobile-abbr-font-size: 10pt;
--post-mobile-content-font-size: 11pt;
--post-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* quotelink */
--post-quotelink-text-color: #d00;
--post-quotelink-text-color-hover: #d00;
--post-quotelink-text-decoration: underline;
--post-quotelink-text-decoration-hover: underline;
/* reply desktop */
--side-arrows-color: #b7c5d9;
@@ -271,6 +285,9 @@
--post-content-link-text-decoration: underline;
--post-content-link-text-decoration-hover: underline;
/* media */
--media-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post */
--post-subject-text-color: #cc1105;
--post-subject-font-weight: 700;
@@ -297,7 +314,11 @@
--post-mobile-abbr-font-size: 12pt;
--post-mobile-content-font-size: 13pt;
--post-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* quotelink */
--post-quotelink-text-color: navy;
--post-quotelink-text-color-hover: red;
--post-quotelink-text-decoration: underline;
--post-quotelink-text-decoration-hover: underline;
/* reply desktop */
--side-arrows-color: #e0bfb7;
@@ -373,6 +394,9 @@
--post-content-link-text-decoration: none;
--post-content-link-text-decoration-hover: none;
/* media */
--media-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post */
--post-subject-text-color: #0f0c5d;
--post-subject-font-weight: 700;
@@ -383,7 +407,27 @@
--post-greentext-color: #789922;
--post-replies-expand-button-background-image: url("/public/assets/buttons/post-expand-plus-blue.png");
--post-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post mobile */
--post-mobile-background-color: #d6daf0;
--post-mobile-info-border-bottom: 1px solid #b7c5d9;
--post-mobile-info-background-color: #c9cde8;
--post-mobile-menu-button-color: #34345c;
--post-mobile-name-text-color: #117743;
--post-mobile-name-font-weight: 700;
--post-mobile-subject-text-color: #0f0c5d;
--post-mobile-subject-font-weight: 700;
--post-mobile-link-background-color: #c9cde8;
--post-mobile-link-border-top: 1px solid #b7c5d9;
--post-mobile-link-info-text-color: #34345c;
--post-mobile-abbr-text-color: #707070;
--post-mobile-abbr-font-size: 12pt;
--post-mobile-content-font-size: 13pt;
/* quotelink */
--post-quotelink-text-color: #d00;
--post-quotelink-text-color-hover: #d00;
--post-quotelink-text-decoration: underline;
--post-quotelink-text-decoration-hover: underline;
/* reply desktop */
--side-arrows-color: #b7c5d9;
@@ -455,6 +499,9 @@
--post-content-link-text-decoration: none;
--post-content-link-text-decoration-hover: none;
/* media */
--media-thumbnail-background-color: rgba(255, 255, 255, 0.01);
/* post */
--post-subject-text-color: #b294bb;
--post-subject-font-weight: 700;
@@ -465,7 +512,28 @@
--post-greentext-color: #b5bd68;
--post-replies-expand-button-background-image: url("/public/assets/buttons/post-expand-plus-dark.png");
--post-thumbnail-background-color: rgba(255, 255, 255, 0.01);
/* post mobile */
--post-mobile-background-color: #282A2E;
--post-mobile-info-border-bottom: 1px solid #2D2F33;
--post-mobile-info-background-color: #212326;
--post-mobile-info-text-color: #707070;
--post-mobile-menu-button-color: #81A2BE;
--post-mobile-name-text-color: #117743;
--post-mobile-name-font-weight: 700;
--post-mobile-subject-text-color: #B294BB;
--post-mobile-subject-font-weight: 700;
--post-mobile-link-background-color: #212326;
--post-mobile-link-border-top: 1px solid #2D2F33;
--post-mobile-link-info-text-color: #707070;
--post-mobile-abbr-text-color: #707070;
--post-mobile-abbr-font-size: 10pt;
--post-mobile-content-font-size: 11pt;
/* quotelink */
--post-quotelink-text-color: #5f89ac;
--post-quotelink-text-color-hover: #81a2be;
--post-quotelink-text-decoration: underline;
--post-quotelink-text-decoration-hover: underline;
/* reply desktop */
--side-arrows-color: #c5c8c6;
@@ -532,6 +600,9 @@
--post-content-link-text-decoration: none;
--post-content-link-text-decoration-hover: none;
/* media */
--media-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post */
--post-subject-text-color: #111;
--post-subject-font-weight: 700;
@@ -542,7 +613,30 @@
--post-greentext-color: #789922;
--post-replies-expand-button-background-image: url("/public/assets/buttons/post-expand-plus-photon.png");
--post-thumbnail-background-color: rgba(0, 0, 0, 0.05);
/* post mobile */
--post-mobile-background-color: #eee;
--post-mobile-info-border-bottom: 1px solid #ccc;
--post-mobile-info-border-top: 1px solid #ccc;
--post-mobile-info-background-color: #ddd;
--post-mobile-info-text-color: #707070;
--post-mobile-menu-button-color: #f60;
--post-mobile-name-text-color: #004a99;
--post-mobile-name-font-weight: 700;
--post-mobile-subject-text-color: #111;
--post-mobile-subject-font-weight: 700;
--post-mobile-link-background-color: #ddd;
--post-mobile-link-border-top: 1px solid #ccc;
--post-mobile-link-info-text-color: #333;
--post-mobile-abbr-text-color: #333;
--post-mobile-abbr-font-size: 10pt;
--post-mobile-content-font-size: 11pt;
--post-mobile-border-bottom: 1px solid #ccc;
/* quotelink */
--post-quotelink-text-color: #f60;
--post-quotelink-text-color-hover: #f30;
--post-quotelink-text-decoration: underline;
--post-quotelink-text-decoration-hover: underline;
/* reply desktop */
--side-arrows-color: #333;
+1
View File
@@ -0,0 +1 @@
export { default } from './post-page';
+24
View File
@@ -0,0 +1,24 @@
import { useEffect } from 'react';
import { useComment } from '@plebbit/plebbit-react-hooks';
import { useParams } from 'react-router-dom';
import Post from '../../components/post/post';
import styles from './post-page.module.css';
const PostPage = () => {
const params = useParams();
const { commentCid } = params;
const post = useComment({ commentCid });
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<div className={styles.content}>
<Post post={post} showAllReplies={true} />
</div>
);
};
export default PostPage;
+3 -8
View File
@@ -59,14 +59,9 @@ const Settings = () => {
</a>
)}
{commitRef && (
<>
{' '}
(
<a href={`https://github.com/plebbit/plebchan/commit/${commitRef}`} target='_blank' rel='noopener noreferrer'>
{commitRef.slice(0, 7)}
</a>
)
</>
<a href={`https://github.com/plebbit/plebchan/commit/${commitRef}`} target='_blank' rel='noopener noreferrer'>
{commitRef.slice(0, 7)}
</a>
)}
</div>
<div>
+4 -7
View File
@@ -1,26 +1,23 @@
import { useEffect, useMemo, useRef } from 'react';
import { useParams } from 'react-router-dom';
import { Subplebbit as SubplebbitType, useFeed } from '@plebbit/plebbit-react-hooks';
import { useFeed, useSubplebbit } from '@plebbit/plebbit-react-hooks';
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
import { useTranslation } from 'react-i18next';
import styles from './subplebbit.module.css';
import useFeedStateString from '../../hooks/use-feed-state-string';
import LoadingEllipsis from '../../components/loading-ellipsis';
import Post from '../../components/post';
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
interface SubplebbitProps {
subplebbits: (SubplebbitType | undefined)[];
}
const Subplebbit = ({ subplebbits }: SubplebbitProps) => {
const Subplebbit = () => {
const { t } = useTranslation();
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
const subplebbitAddresses = useMemo(() => [subplebbitAddress], [subplebbitAddress]) as string[];
const sortType = 'active';
const { feed, hasMore, loadMore } = useFeed({ subplebbitAddresses, sortType });
const subplebbit = subplebbits.find((s) => s?.address === subplebbitAddress);
const subplebbit = useSubplebbit({ subplebbitAddress });
const { shortAddress, state, title } = subplebbit || {};
const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading');