mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
@@ -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": "أعلى"
|
||||
}
|
||||
@@ -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": "শীর্ষ"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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": "Κορυφή"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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": "بالا"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "סגור",
|
||||
"reply": "הגב",
|
||||
"link": "קישור",
|
||||
"close": "סגור"
|
||||
"close": "סגור",
|
||||
"post_a_reply": "פרסם תגובה",
|
||||
"view_thread": "הצג אשכול",
|
||||
"return": "חזור",
|
||||
"bottom": "תחתית",
|
||||
"top": "עליון"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "बंद",
|
||||
"reply": "जवाब दें",
|
||||
"link": "लिंक",
|
||||
"close": "बंद करें"
|
||||
"close": "बंद करें",
|
||||
"post_a_reply": "एक उत्तर पोस्ट करें",
|
||||
"view_thread": "थ्रेड देखें",
|
||||
"return": "वापस",
|
||||
"bottom": "नीचे",
|
||||
"top": "ऊपर"
|
||||
}
|
||||
@@ -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ő"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "閉鎖",
|
||||
"reply": "返信",
|
||||
"link": "リンク",
|
||||
"close": "閉じる"
|
||||
"close": "閉じる",
|
||||
"post_a_reply": "返信を投稿する",
|
||||
"view_thread": "スレッドを見る",
|
||||
"return": "戻る",
|
||||
"bottom": "下へ",
|
||||
"top": "上へ"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "닫힘",
|
||||
"reply": "답장",
|
||||
"link": "링크",
|
||||
"close": "닫기"
|
||||
"close": "닫기",
|
||||
"post_a_reply": "답글 게시",
|
||||
"view_thread": "스레드 보기",
|
||||
"return": "돌아 가기",
|
||||
"bottom": "하단",
|
||||
"top": "맨 위로"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "बंद",
|
||||
"reply": "प्रतिसाद",
|
||||
"link": "लिंक",
|
||||
"close": "बंद करा"
|
||||
"close": "बंद करा",
|
||||
"post_a_reply": "उत्तर पोस्ट करा",
|
||||
"view_thread": "थ्रेड पहा",
|
||||
"return": "परत जा",
|
||||
"bottom": "खाली",
|
||||
"top": "वर"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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": "Верх"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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": "మేలే"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "ปิด",
|
||||
"reply": "ตอบ",
|
||||
"link": "ลิงก์",
|
||||
"close": "ปิด"
|
||||
"close": "ปิด",
|
||||
"post_a_reply": "โพสต์คำตอบ",
|
||||
"view_thread": "ดูกระทู้",
|
||||
"return": "กลับ",
|
||||
"bottom": "ด้านล่าง",
|
||||
"top": "ด้านบน"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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": "Верхній"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "بند",
|
||||
"reply": "جواب دیں",
|
||||
"link": "لنک",
|
||||
"close": "بند کریں"
|
||||
"close": "بند کریں",
|
||||
"post_a_reply": "ایک جواب بھیجیں",
|
||||
"view_thread": "تھریڈ دیکھیں",
|
||||
"return": "واپس",
|
||||
"bottom": "نیچے",
|
||||
"top": "اوپر"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -36,5 +36,10 @@
|
||||
"closed": "关闭",
|
||||
"reply": "回复",
|
||||
"link": "链接",
|
||||
"close": "关闭"
|
||||
"close": "关闭",
|
||||
"post_a_reply": "发表回复",
|
||||
"view_thread": "查看线程",
|
||||
"return": "返回",
|
||||
"bottom": "底部",
|
||||
"top": "顶部"
|
||||
}
|
||||
+8
-6
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
+102
-8
@@ -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");
|
||||
@@ -96,8 +99,12 @@
|
||||
--post-mobile-abbr-font-size: 10pt;
|
||||
--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;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './post-page';
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user