Merge branch 'codex/feature/submit-board-button'

This commit is contained in:
Tommaso Casaburi
2026-06-07 22:47:46 +07:00
38 changed files with 171 additions and 75 deletions
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "الرابط ليس صورة أو فيديو.", "link_not_image_or_video_alert": "الرابط ليس صورة أو فيديو.",
"not_a_file": "ليس ملفًا", "not_a_file": "ليس ملفًا",
"tor_author_flag_label": "هذا المستخدم يستخدم Tor", "tor_author_flag_label": "هذا المستخدم يستخدم Tor",
"copy_share_link": "نسخ رابط المشاركة" "copy_share_link": "نسخ رابط المشاركة",
"directory_submit_board": "أرسل لوحتك"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "লিংকটি ছবি বা ভিডিও নয়।", "link_not_image_or_video_alert": "লিংকটি ছবি বা ভিডিও নয়।",
"not_a_file": "ফাইল নয়", "not_a_file": "ফাইল নয়",
"tor_author_flag_label": "এই ব্যবহারকারী Tor ব্যবহার করছেন", "tor_author_flag_label": "এই ব্যবহারকারী Tor ব্যবহার করছেন",
"copy_share_link": "শেয়ার লিংক কপি করুন" "copy_share_link": "শেয়ার লিংক কপি করুন",
"directory_submit_board": "আপনার বোর্ড জমা দিন"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Odkaz není obrázek ani video.", "link_not_image_or_video_alert": "Odkaz není obrázek ani video.",
"not_a_file": "není soubor", "not_a_file": "není soubor",
"tor_author_flag_label": "Tento uživatel je na síti Tor", "tor_author_flag_label": "Tento uživatel je na síti Tor",
"copy_share_link": "Kopírovat odkaz pro sdílení" "copy_share_link": "Kopírovat odkaz pro sdílení",
"directory_submit_board": "Odeslat svou nástěnku"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Linket er ikke et billede eller en video.", "link_not_image_or_video_alert": "Linket er ikke et billede eller en video.",
"not_a_file": "ikke en fil", "not_a_file": "ikke en fil",
"tor_author_flag_label": "Denne bruger er på Tor", "tor_author_flag_label": "Denne bruger er på Tor",
"copy_share_link": "Kopier delingslinkk" "copy_share_link": "Kopier delingslinkk",
"directory_submit_board": "Indsend dit board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Der Link ist kein Bild oder Video.", "link_not_image_or_video_alert": "Der Link ist kein Bild oder Video.",
"not_a_file": "keine Datei", "not_a_file": "keine Datei",
"tor_author_flag_label": "Dieser Benutzer ist auf Tor", "tor_author_flag_label": "Dieser Benutzer ist auf Tor",
"copy_share_link": "Freigabelink kopieren" "copy_share_link": "Freigabelink kopieren",
"directory_submit_board": "Reiche dein Board ein"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Ο σύνδεσμος δεν είναι εικόνα ή βίντεο.", "link_not_image_or_video_alert": "Ο σύνδεσμος δεν είναι εικόνα ή βίντεο.",
"not_a_file": "δεν είναι αρχείο", "not_a_file": "δεν είναι αρχείο",
"tor_author_flag_label": "Αυτός ο χρήστης είναι στο Tor", "tor_author_flag_label": "Αυτός ο χρήστης είναι στο Tor",
"copy_share_link": "Αντιγραφή ενός συνδέσμου" "copy_share_link": "Αντιγραφή ενός συνδέσμου",
"directory_submit_board": "Υπόβαλε το board σου"
} }
+2 -1
View File
@@ -424,5 +424,6 @@
"link_not_image_or_video_alert": "Link is not an image or video.", "link_not_image_or_video_alert": "Link is not an image or video.",
"not_a_file": "not a file", "not_a_file": "not a file",
"tor_author_flag_label": "This user is on Tor", "tor_author_flag_label": "This user is on Tor",
"copy_share_link": "Copy share link" "copy_share_link": "Copy share link",
"directory_submit_board": "Submit Your Board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "El enlace no es una imagen ni un video.", "link_not_image_or_video_alert": "El enlace no es una imagen ni un video.",
"not_a_file": "no es un archivo", "not_a_file": "no es un archivo",
"tor_author_flag_label": "Este usuario está en Tor", "tor_author_flag_label": "Este usuario está en Tor",
"copy_share_link": "Copiar enlace compartido" "copy_share_link": "Copiar enlace compartido",
"directory_submit_board": "Envía tu board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "پیوند تصویر یا ویدیو نیست.", "link_not_image_or_video_alert": "پیوند تصویر یا ویدیو نیست.",
"not_a_file": "فایل نیست", "not_a_file": "فایل نیست",
"tor_author_flag_label": "این کاربر روی Tor است", "tor_author_flag_label": "این کاربر روی Tor است",
"copy_share_link": "کپی کردن لینک اشتراک" "copy_share_link": "کپی کردن لینک اشتراک",
"directory_submit_board": "برد خود را ارسال کنید"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Linkki ei ole kuva tai video.", "link_not_image_or_video_alert": "Linkki ei ole kuva tai video.",
"not_a_file": "ei ole tiedosto", "not_a_file": "ei ole tiedosto",
"tor_author_flag_label": "Tämä käyttäjä on Torissa", "tor_author_flag_label": "Tämä käyttäjä on Torissa",
"copy_share_link": "Kopioi jakolinkkii" "copy_share_link": "Kopioi jakolinkkii",
"directory_submit_board": "Lähetä boardisi"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Ang link ay hindi larawan o video.", "link_not_image_or_video_alert": "Ang link ay hindi larawan o video.",
"not_a_file": "hindi file", "not_a_file": "hindi file",
"tor_author_flag_label": "Ang user na ito ay nasa Tor", "tor_author_flag_label": "Ang user na ito ay nasa Tor",
"copy_share_link": "Kopyahin ang link sa pagbabahagi" "copy_share_link": "Kopyahin ang link sa pagbabahagi",
"directory_submit_board": "Isumite ang board mo"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Le lien n'est pas une image ni une vidéo.", "link_not_image_or_video_alert": "Le lien n'est pas une image ni une vidéo.",
"not_a_file": "pas un fichier", "not_a_file": "pas un fichier",
"tor_author_flag_label": "Cet utilisateur est sur Tor", "tor_author_flag_label": "Cet utilisateur est sur Tor",
"copy_share_link": "Copier le lien de partage" "copy_share_link": "Copier le lien de partage",
"directory_submit_board": "Soumettez votre board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "הקישור אינו תמונה או וידאו.", "link_not_image_or_video_alert": "הקישור אינו תמונה או וידאו.",
"not_a_file": "לא קובץ", "not_a_file": "לא קובץ",
"tor_author_flag_label": "המשתמש הזה נמצא ב-Tor", "tor_author_flag_label": "המשתמש הזה נמצא ב-Tor",
"copy_share_link": "העתק קישור שיתוף" "copy_share_link": "העתק קישור שיתוף",
"directory_submit_board": "שלח את הבורד שלך"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "लिंक कोई छवि या वीडियो नहीं है.", "link_not_image_or_video_alert": "लिंक कोई छवि या वीडियो नहीं है.",
"not_a_file": "फ़ाइल नहीं है", "not_a_file": "फ़ाइल नहीं है",
"tor_author_flag_label": "यह उपयोगकर्ता Tor पर है", "tor_author_flag_label": "यह उपयोगकर्ता Tor पर है",
"copy_share_link": "शेयर लिंक कॉपी करें" "copy_share_link": "शेयर लिंक कॉपी करें",
"directory_submit_board": "अपना बोर्ड सबमिट करें"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "A hivatkozás nem kép vagy videó.", "link_not_image_or_video_alert": "A hivatkozás nem kép vagy videó.",
"not_a_file": "nem fájl", "not_a_file": "nem fájl",
"tor_author_flag_label": "Ez a felhasználó a Tor hálózatán van", "tor_author_flag_label": "Ez a felhasználó a Tor hálózatán van",
"copy_share_link": "Megosztási hivatkozás másolása" "copy_share_link": "Megosztási hivatkozás másolása",
"directory_submit_board": "Küldd be a boardodat"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Tautan bukan gambar atau video.", "link_not_image_or_video_alert": "Tautan bukan gambar atau video.",
"not_a_file": "bukan file", "not_a_file": "bukan file",
"tor_author_flag_label": "Pengguna ini ada di Tor", "tor_author_flag_label": "Pengguna ini ada di Tor",
"copy_share_link": "Salin tautan bagian" "copy_share_link": "Salin tautan bagian",
"directory_submit_board": "Kirim board Anda"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Il link non è un'immagine né un video.", "link_not_image_or_video_alert": "Il link non è un'immagine né un video.",
"not_a_file": "non è un file", "not_a_file": "non è un file",
"tor_author_flag_label": "Questo utente è su Tor", "tor_author_flag_label": "Questo utente è su Tor",
"copy_share_link": "Copia link condiviso" "copy_share_link": "Copia link condiviso",
"directory_submit_board": "Invia la tua board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "リンクは画像または動画ではありません。", "link_not_image_or_video_alert": "リンクは画像または動画ではありません。",
"not_a_file": "ファイルではありません", "not_a_file": "ファイルではありません",
"tor_author_flag_label": "このユーザーはTorを使用しています", "tor_author_flag_label": "このユーザーはTorを使用しています",
"copy_share_link": "シェアリンクをコピー" "copy_share_link": "シェアリンクをコピー",
"directory_submit_board": "掲示板を提出する"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "링크가 이미지 또는 동영상이 아닙니다.", "link_not_image_or_video_alert": "링크가 이미지 또는 동영상이 아닙니다.",
"not_a_file": "파일이 아님", "not_a_file": "파일이 아님",
"tor_author_flag_label": "이 사용자는 Tor를 사용 중입니다", "tor_author_flag_label": "이 사용자는 Tor를 사용 중입니다",
"copy_share_link": "공유 링크 복사" "copy_share_link": "공유 링크 복사",
"directory_submit_board": "게시판 제출하기"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "लिंक प्रतिमा किंवा व्हिडिओ नाही.", "link_not_image_or_video_alert": "लिंक प्रतिमा किंवा व्हिडिओ नाही.",
"not_a_file": "फाइल नाही", "not_a_file": "फाइल नाही",
"tor_author_flag_label": "हा वापरकर्ता Tor वर आहे", "tor_author_flag_label": "हा वापरकर्ता Tor वर आहे",
"copy_share_link": "शेअर लिंक कॉपी करा" "copy_share_link": "शेअर लिंक कॉपी करा",
"directory_submit_board": "तुमचा बोर्ड सबमिट करा"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "De link is geen afbeelding of video.", "link_not_image_or_video_alert": "De link is geen afbeelding of video.",
"not_a_file": "geen bestand", "not_a_file": "geen bestand",
"tor_author_flag_label": "Deze gebruiker zit op Tor", "tor_author_flag_label": "Deze gebruiker zit op Tor",
"copy_share_link": "Delen link kopiëren" "copy_share_link": "Delen link kopiëren",
"directory_submit_board": "Dien je board in"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Lenken er ikke et bilde eller en video.", "link_not_image_or_video_alert": "Lenken er ikke et bilde eller en video.",
"not_a_file": "ikke en fil", "not_a_file": "ikke en fil",
"tor_author_flag_label": "Denne brukeren er på Tor", "tor_author_flag_label": "Denne brukeren er på Tor",
"copy_share_link": "Kopier delingslenke" "copy_share_link": "Kopier delingslenke",
"directory_submit_board": "Send inn boardet ditt"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Link nie jest obrazem ani filmem.", "link_not_image_or_video_alert": "Link nie jest obrazem ani filmem.",
"not_a_file": "to nie plik", "not_a_file": "to nie plik",
"tor_author_flag_label": "Ten użytkownik jest w sieci Tor", "tor_author_flag_label": "Ten użytkownik jest w sieci Tor",
"copy_share_link": "Kopiuj link udostępniania" "copy_share_link": "Kopiuj link udostępniania",
"directory_submit_board": "Prześlij swój board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "O link não é uma imagem nem um vídeo.", "link_not_image_or_video_alert": "O link não é uma imagem nem um vídeo.",
"not_a_file": "não é um arquivo", "not_a_file": "não é um arquivo",
"tor_author_flag_label": "Este usuário está no Tor", "tor_author_flag_label": "Este usuário está no Tor",
"copy_share_link": "Copiar link compartilhado" "copy_share_link": "Copiar link compartilhado",
"directory_submit_board": "Envie seu board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Linkul nu este o imagine sau un videoclip.", "link_not_image_or_video_alert": "Linkul nu este o imagine sau un videoclip.",
"not_a_file": "nu este fișier", "not_a_file": "nu este fișier",
"tor_author_flag_label": "Acest utilizator este pe Tor", "tor_author_flag_label": "Acest utilizator este pe Tor",
"copy_share_link": "Copiezi link-ul de partajare" "copy_share_link": "Copiezi link-ul de partajare",
"directory_submit_board": "Trimite boardul tău"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Ссылка не является изображением или видео.", "link_not_image_or_video_alert": "Ссылка не является изображением или видео.",
"not_a_file": "не файл", "not_a_file": "не файл",
"tor_author_flag_label": "Этот пользователь находится в Tor", "tor_author_flag_label": "Этот пользователь находится в Tor",
"copy_share_link": "Копировать ссылку для общего доступа" "copy_share_link": "Копировать ссылку для общего доступа",
"directory_submit_board": "Отправить свою доску"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Lidhja nuk është imazh ose video.", "link_not_image_or_video_alert": "Lidhja nuk është imazh ose video.",
"not_a_file": "nuk është skedar", "not_a_file": "nuk është skedar",
"tor_author_flag_label": "Ky përdorues është në Tor", "tor_author_flag_label": "Ky përdorues është në Tor",
"copy_share_link": "Kopjo lidhjen e ndarjes" "copy_share_link": "Kopjo lidhjen e ndarjes",
"directory_submit_board": "Dërgo bordin tënd"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Länken är inte en bild eller video.", "link_not_image_or_video_alert": "Länken är inte en bild eller video.",
"not_a_file": "inte en fil", "not_a_file": "inte en fil",
"tor_author_flag_label": "Den här användaren är på Tor", "tor_author_flag_label": "Den här användaren är på Tor",
"copy_share_link": "Kopiera delningslänk" "copy_share_link": "Kopiera delningslänk",
"directory_submit_board": "Skicka in ditt board"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "లింక్ చిత్రం లేదా వీడియో కాదు.", "link_not_image_or_video_alert": "లింక్ చిత్రం లేదా వీడియో కాదు.",
"not_a_file": "ఫైల్ కాదు", "not_a_file": "ఫైల్ కాదు",
"tor_author_flag_label": "ఈ వినియోగదారు Tor లో ఉన్నారు", "tor_author_flag_label": "ఈ వినియోగదారు Tor లో ఉన్నారు",
"copy_share_link": "భాగస్వామ్య లింక్‌ను కాపీ చేయండి" "copy_share_link": "భాగస్వామ్య లింక్‌ను కాపీ చేయండి",
"directory_submit_board": "మీ బోర్డును సమర్పించండి"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "ลิงก์ไม่ใช่รูปภาพหรือวิดีโอ", "link_not_image_or_video_alert": "ลิงก์ไม่ใช่รูปภาพหรือวิดีโอ",
"not_a_file": "ไม่ใช่ไฟล์", "not_a_file": "ไม่ใช่ไฟล์",
"tor_author_flag_label": "ผู้ใช้นี้อยู่บน Tor", "tor_author_flag_label": "ผู้ใช้นี้อยู่บน Tor",
"copy_share_link": "คัดลอกลิงก์แชร์" "copy_share_link": "คัดลอกลิงก์แชร์",
"directory_submit_board": "ส่งบอร์ดของคุณ"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Bağlantı bir görsel veya video değil.", "link_not_image_or_video_alert": "Bağlantı bir görsel veya video değil.",
"not_a_file": "dosya değil", "not_a_file": "dosya değil",
"tor_author_flag_label": "Bu kullanıcı Tor'da", "tor_author_flag_label": "Bu kullanıcı Tor'da",
"copy_share_link": "Paylaşma bağlantısını kopyala" "copy_share_link": "Paylaşma bağlantısını kopyala",
"directory_submit_board": "Panonu Gönder"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Посилання не є зображенням або відео.", "link_not_image_or_video_alert": "Посилання не є зображенням або відео.",
"not_a_file": "не файл", "not_a_file": "не файл",
"tor_author_flag_label": "Цей користувач у Tor", "tor_author_flag_label": "Цей користувач у Tor",
"copy_share_link": "Копіювати посилання для спільного доступу" "copy_share_link": "Копіювати посилання для спільного доступу",
"directory_submit_board": "Надіслати свою дошку"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "لنک تصویر یا ویڈیو نہیں ہے۔", "link_not_image_or_video_alert": "لنک تصویر یا ویڈیو نہیں ہے۔",
"not_a_file": "فائل نہیں ہے", "not_a_file": "فائل نہیں ہے",
"tor_author_flag_label": "یہ صارف Tor پر ہے", "tor_author_flag_label": "یہ صارف Tor پر ہے",
"copy_share_link": "شیئر لنک کاپی کریں" "copy_share_link": "شیئر لنک کاپی کریں",
"directory_submit_board": "اپنا بورڈ جمع کرائیں"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "Liên kết không phải là hình ảnh hoặc video.", "link_not_image_or_video_alert": "Liên kết không phải là hình ảnh hoặc video.",
"not_a_file": "không phải tệp", "not_a_file": "không phải tệp",
"tor_author_flag_label": "Người dùng này đang ở trên Tor", "tor_author_flag_label": "Người dùng này đang ở trên Tor",
"copy_share_link": "Sao chép liên kết chia sẻ" "copy_share_link": "Sao chép liên kết chia sẻ",
"directory_submit_board": "Gửi bảng của bạn"
} }
+2 -1
View File
@@ -405,5 +405,6 @@
"link_not_image_or_video_alert": "链接不是图片或视频。", "link_not_image_or_video_alert": "链接不是图片或视频。",
"not_a_file": "不是文件", "not_a_file": "不是文件",
"tor_author_flag_label": "该用户正在使用 Tor", "tor_author_flag_label": "该用户正在使用 Tor",
"copy_share_link": "复制分享链接" "copy_share_link": "复制分享链接",
"directory_submit_board": "提交你的版块"
} }
@@ -44,6 +44,7 @@ vi.mock('react-i18next', () => ({
if (key === 'directory_status_online') return 'online'; if (key === 'directory_status_online') return 'online';
if (key === 'directory_status_offline') return 'offline'; if (key === 'directory_status_offline') return 'offline';
if (key === 'directory_heading') return `${values?.boardIdentifier} directory`; if (key === 'directory_heading') return `${values?.boardIdentifier} directory`;
if (key === 'directory_submit_board') return 'Submit Your Board';
if (key === 'view') return 'View'; if (key === 'view') return 'View';
return key; return key;
}, },
@@ -75,18 +76,18 @@ vi.mock('../../../components/board-buttons/board-buttons', () => ({
TopButton: () => createElement('button', { type: 'button' }, 'top'), TopButton: () => createElement('button', { type: 'button' }, 'top'),
})); }));
vi.mock('../../../components/footer', () => ({ vi.mock('../../../components/footer/footer', () => ({
PageFooterDesktop: ({ firstRow, styleRow }: { firstRow: React.ReactNode; styleRow: React.ReactNode }) => PageFooterDesktop: ({ firstRow, styleRow }: { firstRow: React.ReactNode; styleRow: React.ReactNode }) =>
createElement('footer', { 'data-testid': 'desktop-footer' }, firstRow, styleRow), createElement('footer', { 'data-testid': 'desktop-footer' }, firstRow, styleRow),
PageFooterMobile: ({ children }: { children: React.ReactNode }) => createElement('footer', { 'data-testid': 'mobile-footer' }, children), PageFooterMobile: ({ children }: { children: React.ReactNode }) => createElement('footer', { 'data-testid': 'mobile-footer' }, children),
ThreadFooterStyleRow: () => createElement('div', null, 'style'), ThreadFooterStyleRow: () => createElement('div', null, 'style'),
})); }));
vi.mock('../../../components/loading-ellipsis', () => ({ vi.mock('../../../components/loading-ellipsis/loading-ellipsis', () => ({
default: ({ string }: { string: string }) => createElement('span', null, string), default: ({ string }: { string: string }) => createElement('span', null, string),
})); }));
vi.mock('../../../components/tooltip', () => ({ vi.mock('../../../components/tooltip/tooltip', () => ({
default: ({ content, children }: { content: React.ReactNode; children: React.ReactNode }) => default: ({ content, children }: { content: React.ReactNode; children: React.ReactNode }) =>
createElement('span', { title: typeof content === 'string' ? content : undefined }, children), createElement('span', { title: typeof content === 'string' ? content : undefined }, children),
})); }));
@@ -167,6 +168,7 @@ const createCommunity = (address: string, updatedAt = testState.nowSeconds - 60)
}); });
const getDirectoryRow = (address = 'anime-and-manga.bso') => Array.from(container.querySelectorAll('tbody tr')).find((row) => row.textContent?.includes(address)); const getDirectoryRow = (address = 'anime-and-manga.bso') => Array.from(container.querySelectorAll('tbody tr')).find((row) => row.textContent?.includes(address));
const getSubmitBoardLinks = () => Array.from(container.querySelectorAll<HTMLAnchorElement>('a')).filter((link) => link.textContent === 'Submit Your Board');
describe('Directory', () => { describe('Directory', () => {
beforeEach(() => { beforeEach(() => {
@@ -230,6 +232,20 @@ describe('Directory', () => {
}); });
}); });
it('links the submit-board controls to the GitHub directory edit flow', async () => {
await renderDirectory();
const submitLinks = getSubmitBoardLinks();
expect(submitLinks).toHaveLength(4);
for (const link of submitLinks) {
expect(link.getAttribute('href')).toBe('https://github.com/bitsocialnet/lists/edit/master/5chan-directories/5chan-a-directory.json');
expect(link.getAttribute('target')).toBe('_blank');
expect(link.getAttribute('rel')).toContain('noreferrer');
expect(link.getAttribute('rel')).toContain('noopener');
}
});
it('shows loading status while the listed board status is loading', async () => { it('shows loading status while the listed board status is loading', async () => {
testState.communities = {}; testState.communities = {};
testState.offlineHookValue = { testState.offlineHookValue = {
+23 -8
View File
@@ -18,12 +18,24 @@
.desktopNavLinks { .desktopNavLinks {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; justify-content: space-between;
gap: 8px;
width: 100%;
text-align: left; text-align: left;
font-size: 13px; font-size: 13px;
text-transform: capitalize; text-transform: capitalize;
} }
.navButtonGroup {
display: flex;
align-items: center;
gap: 4px;
}
.submitBoardControl {
white-space: nowrap;
}
.desktopNavLinks a:not([class~='button']), .desktopNavLinks a:not([class~='button']),
.desktopFooterButtons a:not([class~='button']) { .desktopFooterButtons a:not([class~='button']) {
all: unset; all: unset;
@@ -36,11 +48,18 @@
margin-top: 5px; margin-top: 5px;
} }
.mobileNavLinks button { .mobileNavLinks button,
.mobileNavLinks a[class~='button'],
.mobileFooterButtons button,
.mobileFooterButtons a[class~='button'] {
text-transform: capitalize; text-transform: capitalize;
margin: 5px 2px; margin: 5px 2px;
} }
.mobileSubmitRow {
margin-top: -5px;
}
.mobileNavLinks a:not([class~='button']), .mobileNavLinks a:not([class~='button']),
.mobileFooterButtons a:not([class~='button']) { .mobileFooterButtons a:not([class~='button']) {
all: unset; all: unset;
@@ -49,7 +68,8 @@
.desktopFooterButtons { .desktopFooterButtons {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; justify-content: space-between;
gap: 8px;
width: 100%; width: 100%;
text-transform: capitalize; text-transform: capitalize;
} }
@@ -59,11 +79,6 @@
text-transform: capitalize; text-transform: capitalize;
} }
.mobileFooterButtons button {
text-transform: capitalize;
margin: 5px 2px;
}
.directorySummary { .directorySummary {
margin: 0 0 12px; margin: 0 0 12px;
text-align: center; text-align: center;
+59 -29
View File
@@ -4,9 +4,9 @@ import { Trans, useTranslation } from 'react-i18next';
import { useCommunity } from '@bitsocial/bitsocial-react-hooks'; import { useCommunity } from '@bitsocial/bitsocial-react-hooks';
import { shouldShowSnow } from '../../lib/snow'; import { shouldShowSnow } from '../../lib/snow';
import { BottomButton, BracketedCatalogButton, CatalogButton, ReturnButton, TopButton } from '../../components/board-buttons/board-buttons'; import { BottomButton, BracketedCatalogButton, CatalogButton, ReturnButton, TopButton } from '../../components/board-buttons/board-buttons';
import { PageFooterDesktop, PageFooterMobile, ThreadFooterStyleRow } from '../../components/footer'; import { PageFooterDesktop, PageFooterMobile, ThreadFooterStyleRow } from '../../components/footer/footer';
import LoadingEllipsis from '../../components/loading-ellipsis'; import LoadingEllipsis from '../../components/loading-ellipsis/loading-ellipsis';
import Tooltip from '../../components/tooltip'; import Tooltip from '../../components/tooltip/tooltip';
import { useDirectories } from '../../hooks/use-directories'; import { useDirectories } from '../../hooks/use-directories';
import { useCommunityIdentifier } from '../../hooks/use-community-identifiers'; import { useCommunityIdentifier } from '../../hooks/use-community-identifiers';
import { useResolvedCommunityAddress } from '../../hooks/use-resolved-community-address'; import { useResolvedCommunityAddress } from '../../hooks/use-resolved-community-address';
@@ -44,43 +44,73 @@ const computeBoardStatus = (
const PASS_LINK = '/pass'; const PASS_LINK = '/pass';
const DirectoryDesktopTopControls = ({ communityAddress }: { communityAddress: string | undefined }) => ( const DirectorySubmitBoardLink = ({ href }: { href: string }) => {
const { t } = useTranslation();
return (
<a className='button' href={href} target='_blank' rel='noreferrer noopener'>
{t('directory_submit_board')}
</a>
);
};
const DirectoryDesktopTopControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
<div className={styles.desktopNavLinks}> <div className={styles.desktopNavLinks}>
<span> <div className={styles.navButtonGroup}>
[<ReturnButton address={communityAddress} />] <span>
</span> [<ReturnButton address={communityAddress} />]
<BracketedCatalogButton address={communityAddress} /> </span>
<span> <BracketedCatalogButton address={communityAddress} />
[<BottomButton />] <span>
[<BottomButton />]
</span>
</div>
<span className={styles.submitBoardControl}>
[<DirectorySubmitBoardLink href={submitHref} />]
</span> </span>
</div> </div>
); );
const DirectoryDesktopFooterControls = ({ communityAddress }: { communityAddress: string | undefined }) => ( const DirectoryDesktopFooterControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
<div className={styles.desktopFooterButtons}> <div className={styles.desktopFooterButtons}>
<span> <div className={styles.navButtonGroup}>
[<ReturnButton address={communityAddress} />] <span>
</span> [<ReturnButton address={communityAddress} />]
<BracketedCatalogButton address={communityAddress} /> </span>
<span> <BracketedCatalogButton address={communityAddress} />
[<TopButton />] <span>
[<TopButton />]
</span>
</div>
<span className={styles.submitBoardControl}>
[<DirectorySubmitBoardLink href={submitHref} />]
</span> </span>
</div> </div>
); );
const DirectoryMobileTopControls = ({ communityAddress }: { communityAddress: string | undefined }) => ( const DirectoryMobileTopControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
<div className={styles.mobileNavLinks}> <div className={styles.mobileNavLinks}>
<ReturnButton address={communityAddress} /> <div>
<CatalogButton address={communityAddress} /> <ReturnButton address={communityAddress} />
<BottomButton /> <CatalogButton address={communityAddress} />
<BottomButton />
</div>
<div className={styles.mobileSubmitRow}>
<DirectorySubmitBoardLink href={submitHref} />
</div>
</div> </div>
); );
const DirectoryMobileFooterControls = ({ communityAddress }: { communityAddress: string | undefined }) => ( const DirectoryMobileFooterControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
<div className={styles.mobileFooterButtons}> <div className={styles.mobileFooterButtons}>
<ReturnButton address={communityAddress} /> <div>
<CatalogButton address={communityAddress} /> <ReturnButton address={communityAddress} />
<TopButton /> <CatalogButton address={communityAddress} />
<TopButton />
</div>
<div className={styles.mobileSubmitRow}>
<DirectorySubmitBoardLink href={submitHref} />
</div>
</div> </div>
); );
@@ -199,9 +229,9 @@ const Directory = () => {
return ( return (
<div id='top' className={`${styles.page} ${shouldShowSnow() ? styles.garland : ''}`}> <div id='top' className={`${styles.page} ${shouldShowSnow() ? styles.garland : ''}`}>
<DirectoryMobileTopControls communityAddress={communityAddress} /> <DirectoryMobileTopControls communityAddress={communityAddress} submitHref={repoEditUrl} />
<hr className={styles.desktopDivider} /> <hr className={styles.desktopDivider} />
<DirectoryDesktopTopControls communityAddress={communityAddress} /> <DirectoryDesktopTopControls communityAddress={communityAddress} submitHref={repoEditUrl} />
<hr className={styles.divider} /> <hr className={styles.divider} />
{isLoadingShell ? ( {isLoadingShell ? (
<h4 className={styles.directorySummary}> <h4 className={styles.directorySummary}>
@@ -257,9 +287,9 @@ const Directory = () => {
</> </>
)} )}
<PageFooterDesktop firstRow={<DirectoryDesktopFooterControls communityAddress={communityAddress} />} styleRow={<ThreadFooterStyleRow />} /> <PageFooterDesktop firstRow={<DirectoryDesktopFooterControls communityAddress={communityAddress} submitHref={repoEditUrl} />} styleRow={<ThreadFooterStyleRow />} />
<PageFooterMobile> <PageFooterMobile>
<DirectoryMobileFooterControls communityAddress={communityAddress} /> <DirectoryMobileFooterControls communityAddress={communityAddress} submitHref={repoEditUrl} />
</PageFooterMobile> </PageFooterMobile>
</div> </div>
); );