mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(post-form): enforce required post link board rules
Validate link and media requirements from community/directory features in post and reply forms, with shared helpers and translated alert messages.
This commit is contained in:
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "ترقية الإعدادات متاحة",
|
||||
"settings_upgrade_review_button": "مراجعة",
|
||||
"settings_upgrade_never_show_again": "لا تظهر مرة أخرى",
|
||||
"site_legal_meta_contributors_link": "المساهمون"
|
||||
"site_legal_meta_contributors_link": "المساهمون",
|
||||
"post_link_required_alert": "يجب أن تنشر رابطًا.",
|
||||
"post_media_link_required_alert": "يجب أن تنشر رابط صورة أو فيديو."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "সেটিংস আপগ্রেড উপলব্ধ",
|
||||
"settings_upgrade_review_button": "পর্যালোচনা",
|
||||
"settings_upgrade_never_show_again": "আর দেখাবেন না",
|
||||
"site_legal_meta_contributors_link": "অবদানকারীরা"
|
||||
"site_legal_meta_contributors_link": "অবদানকারীরা",
|
||||
"post_link_required_alert": "আপনাকে একটি লিঙ্ক পোস্ট করতে হবে।",
|
||||
"post_media_link_required_alert": "আপনাকে একটি ছবি বা ভিডিওর লিঙ্ক পোস্ট করতে হবে।"
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "upgrade nastavení k dispozici",
|
||||
"settings_upgrade_review_button": "zkontrolovat",
|
||||
"settings_upgrade_never_show_again": "už nezobrazovat",
|
||||
"site_legal_meta_contributors_link": "Přispěvatelé"
|
||||
"site_legal_meta_contributors_link": "Přispěvatelé",
|
||||
"post_link_required_alert": "Musíte přidat odkaz.",
|
||||
"post_media_link_required_alert": "Musíte přidat odkaz na obrázek nebo video."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "indstillingsopgradering tilgængelig",
|
||||
"settings_upgrade_review_button": "gennemgå",
|
||||
"settings_upgrade_never_show_again": "vis aldrig igen",
|
||||
"site_legal_meta_contributors_link": "Bidragydere"
|
||||
"site_legal_meta_contributors_link": "Bidragydere",
|
||||
"post_link_required_alert": "Du skal poste et link.",
|
||||
"post_media_link_required_alert": "Du skal poste et billed- eller videolink."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "Einstellungs-Upgrade verfügbar",
|
||||
"settings_upgrade_review_button": "überprüfen",
|
||||
"settings_upgrade_never_show_again": "nie wieder anzeigen",
|
||||
"site_legal_meta_contributors_link": "Mitwirkende"
|
||||
"site_legal_meta_contributors_link": "Mitwirkende",
|
||||
"post_link_required_alert": "Du musst einen Link posten.",
|
||||
"post_media_link_required_alert": "Du musst einen Bild- oder Videolink posten."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "αναβάθμιση ρυθμίσεων διαθέσιμη",
|
||||
"settings_upgrade_review_button": "έλεγχος",
|
||||
"settings_upgrade_never_show_again": "να μην εμφανιστεί ξανά",
|
||||
"site_legal_meta_contributors_link": "Συνεισφέροντες"
|
||||
"site_legal_meta_contributors_link": "Συνεισφέροντες",
|
||||
"post_link_required_alert": "Πρέπει να δημοσιεύσετε έναν σύνδεσμο.",
|
||||
"post_media_link_required_alert": "Πρέπει να δημοσιεύσετε σύνδεσμο εικόνας ή βίντεο."
|
||||
}
|
||||
|
||||
@@ -462,5 +462,7 @@
|
||||
"settings_upgrade_review_notice": "settings upgrade available",
|
||||
"settings_upgrade_review_button": "review",
|
||||
"settings_upgrade_never_show_again": "never show again",
|
||||
"site_legal_meta_contributors_link": "Contributors"
|
||||
"site_legal_meta_contributors_link": "Contributors",
|
||||
"post_link_required_alert": "You must post a link.",
|
||||
"post_media_link_required_alert": "You must post an image or video link."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "actualización de configuración disponible",
|
||||
"settings_upgrade_review_button": "revisar",
|
||||
"settings_upgrade_never_show_again": "no volver a mostrar",
|
||||
"site_legal_meta_contributors_link": "Colaboradores"
|
||||
"site_legal_meta_contributors_link": "Colaboradores",
|
||||
"post_link_required_alert": "Debes publicar un enlace.",
|
||||
"post_media_link_required_alert": "Debes publicar un enlace a una imagen o un video."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "ارتقای تنظیمات موجود است",
|
||||
"settings_upgrade_review_button": "بررسی",
|
||||
"settings_upgrade_never_show_again": "دیگر نشان نده",
|
||||
"site_legal_meta_contributors_link": "مشارکتکنندگان"
|
||||
"site_legal_meta_contributors_link": "مشارکتکنندگان",
|
||||
"post_link_required_alert": "باید یک پیوند ارسال کنید.",
|
||||
"post_media_link_required_alert": "باید پیوند یک تصویر یا ویدیو را ارسال کنید."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "asetuspäivitys saatavilla",
|
||||
"settings_upgrade_review_button": "tarkista",
|
||||
"settings_upgrade_never_show_again": "älä näytä uudelleen",
|
||||
"site_legal_meta_contributors_link": "Avustajat"
|
||||
"site_legal_meta_contributors_link": "Avustajat",
|
||||
"post_link_required_alert": "Sinun on julkaistava linkki.",
|
||||
"post_media_link_required_alert": "Sinun on julkaistava kuva- tai videolinkki."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "may upgrade ng setting",
|
||||
"settings_upgrade_review_button": "suriin",
|
||||
"settings_upgrade_never_show_again": "huwag nang ipakita muli",
|
||||
"site_legal_meta_contributors_link": "Mga Kontribyutor"
|
||||
"site_legal_meta_contributors_link": "Mga Kontribyutor",
|
||||
"post_link_required_alert": "Kailangan mong mag-post ng link.",
|
||||
"post_media_link_required_alert": "Kailangan mong mag-post ng link ng larawan o video."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "mise à jour des paramètres disponible",
|
||||
"settings_upgrade_review_button": "examiner",
|
||||
"settings_upgrade_never_show_again": "ne plus afficher",
|
||||
"site_legal_meta_contributors_link": "Contributeurs"
|
||||
"site_legal_meta_contributors_link": "Contributeurs",
|
||||
"post_link_required_alert": "Vous devez publier un lien.",
|
||||
"post_media_link_required_alert": "Vous devez publier un lien vers une image ou une vidéo."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "שדרוג הגדרות זמין",
|
||||
"settings_upgrade_review_button": "סקור",
|
||||
"settings_upgrade_never_show_again": "לא להציג שוב",
|
||||
"site_legal_meta_contributors_link": "תורמים"
|
||||
"site_legal_meta_contributors_link": "תורמים",
|
||||
"post_link_required_alert": "עליך לפרסם קישור.",
|
||||
"post_media_link_required_alert": "עליך לפרסם קישור לתמונה או לסרטון."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "सेटिंग्स अपग्रेड उपलब्ध",
|
||||
"settings_upgrade_review_button": "समीक्षा करें",
|
||||
"settings_upgrade_never_show_again": "फिर कभी न दिखाएँ",
|
||||
"site_legal_meta_contributors_link": "योगदानकर्ता"
|
||||
"site_legal_meta_contributors_link": "योगदानकर्ता",
|
||||
"post_link_required_alert": "आपको एक लिंक पोस्ट करना होगा।",
|
||||
"post_media_link_required_alert": "आपको एक छवि या वीडियो लिंक पोस्ट करना होगा।"
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "beállításfrissítés elérhető",
|
||||
"settings_upgrade_review_button": "áttekintés",
|
||||
"settings_upgrade_never_show_again": "ne jelenjen meg újra",
|
||||
"site_legal_meta_contributors_link": "Közreműködők"
|
||||
"site_legal_meta_contributors_link": "Közreműködők",
|
||||
"post_link_required_alert": "Közzé kell tenned egy linket.",
|
||||
"post_media_link_required_alert": "Közzé kell tenned egy kép- vagy videólinket."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "pembaruan pengaturan tersedia",
|
||||
"settings_upgrade_review_button": "tinjau",
|
||||
"settings_upgrade_never_show_again": "jangan tampilkan lagi",
|
||||
"site_legal_meta_contributors_link": "Kontributor"
|
||||
"site_legal_meta_contributors_link": "Kontributor",
|
||||
"post_link_required_alert": "Anda harus memposting tautan.",
|
||||
"post_media_link_required_alert": "Anda harus memposting tautan gambar atau video."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "aggiornamento impostazioni disponibile",
|
||||
"settings_upgrade_review_button": "rivedi",
|
||||
"settings_upgrade_never_show_again": "non mostrare più",
|
||||
"site_legal_meta_contributors_link": "Collaboratori"
|
||||
"site_legal_meta_contributors_link": "Collaboratori",
|
||||
"post_link_required_alert": "Devi pubblicare un link.",
|
||||
"post_media_link_required_alert": "Devi pubblicare un link a un'immagine o a un video."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "設定のアップグレードが利用可能",
|
||||
"settings_upgrade_review_button": "確認",
|
||||
"settings_upgrade_never_show_again": "今後表示しない",
|
||||
"site_legal_meta_contributors_link": "貢献者"
|
||||
"site_legal_meta_contributors_link": "貢献者",
|
||||
"post_link_required_alert": "リンクを投稿する必要があります。",
|
||||
"post_media_link_required_alert": "画像または動画のリンクを投稿する必要があります。"
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "설정 업그레이드 사용 가능",
|
||||
"settings_upgrade_review_button": "검토",
|
||||
"settings_upgrade_never_show_again": "다시 표시하지 않기",
|
||||
"site_legal_meta_contributors_link": "기여자"
|
||||
"site_legal_meta_contributors_link": "기여자",
|
||||
"post_link_required_alert": "링크를 게시해야 합니다.",
|
||||
"post_media_link_required_alert": "이미지 또는 동영상 링크를 게시해야 합니다."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "सेटिंग्ज अपग्रेड उपलब्ध",
|
||||
"settings_upgrade_review_button": "पुनरावलोकन",
|
||||
"settings_upgrade_never_show_again": "पुन्हा दाखवू नका",
|
||||
"site_legal_meta_contributors_link": "योगदानकर्ते"
|
||||
"site_legal_meta_contributors_link": "योगदानकर्ते",
|
||||
"post_link_required_alert": "तुम्हाला एक लिंक पोस्ट करावी लागेल.",
|
||||
"post_media_link_required_alert": "तुम्हाला प्रतिमा किंवा व्हिडिओची लिंक पोस्ट करावी लागेल."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "instellingenupgrade beschikbaar",
|
||||
"settings_upgrade_review_button": "bekijken",
|
||||
"settings_upgrade_never_show_again": "niet meer tonen",
|
||||
"site_legal_meta_contributors_link": "Bijdragers"
|
||||
"site_legal_meta_contributors_link": "Bijdragers",
|
||||
"post_link_required_alert": "Je moet een link plaatsen.",
|
||||
"post_media_link_required_alert": "Je moet een afbeelding- of videolink plaatsen."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "innstillingsoppgradering tilgjengelig",
|
||||
"settings_upgrade_review_button": "se gjennom",
|
||||
"settings_upgrade_never_show_again": "vis aldri igjen",
|
||||
"site_legal_meta_contributors_link": "Bidragsytere"
|
||||
"site_legal_meta_contributors_link": "Bidragsytere",
|
||||
"post_link_required_alert": "Du må poste en lenke.",
|
||||
"post_media_link_required_alert": "Du må poste en bilde- eller videolenke."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "aktualizacja ustawień dostępna",
|
||||
"settings_upgrade_review_button": "przejrzyj",
|
||||
"settings_upgrade_never_show_again": "nie pokazuj ponownie",
|
||||
"site_legal_meta_contributors_link": "Współtwórcy"
|
||||
"site_legal_meta_contributors_link": "Współtwórcy",
|
||||
"post_link_required_alert": "Musisz opublikować link.",
|
||||
"post_media_link_required_alert": "Musisz opublikować link do obrazu lub filmu."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "atualização de configurações disponível",
|
||||
"settings_upgrade_review_button": "revisar",
|
||||
"settings_upgrade_never_show_again": "não mostrar novamente",
|
||||
"site_legal_meta_contributors_link": "Colaboradores"
|
||||
"site_legal_meta_contributors_link": "Colaboradores",
|
||||
"post_link_required_alert": "Você deve postar um link.",
|
||||
"post_media_link_required_alert": "Você deve postar um link de imagem ou vídeo."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "actualizare setări disponibilă",
|
||||
"settings_upgrade_review_button": "revizuiește",
|
||||
"settings_upgrade_never_show_again": "nu mai afișa",
|
||||
"site_legal_meta_contributors_link": "Contributori"
|
||||
"site_legal_meta_contributors_link": "Contributori",
|
||||
"post_link_required_alert": "Trebuie să postezi un link.",
|
||||
"post_media_link_required_alert": "Trebuie să postezi un link către o imagine sau un videoclip."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "обновление настроек доступно",
|
||||
"settings_upgrade_review_button": "просмотреть",
|
||||
"settings_upgrade_never_show_again": "больше не показывать",
|
||||
"site_legal_meta_contributors_link": "Участники"
|
||||
"site_legal_meta_contributors_link": "Участники",
|
||||
"post_link_required_alert": "Вы должны опубликовать ссылку.",
|
||||
"post_media_link_required_alert": "Вы должны опубликовать ссылку на изображение или видео."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "përmirësim i cilësimeve i disponueshëm",
|
||||
"settings_upgrade_review_button": "shqyrto",
|
||||
"settings_upgrade_never_show_again": "mos e shfaq më",
|
||||
"site_legal_meta_contributors_link": "Kontribuesit"
|
||||
"site_legal_meta_contributors_link": "Kontribuesit",
|
||||
"post_link_required_alert": "Duhet të postosh një lidhje.",
|
||||
"post_media_link_required_alert": "Duhet të postosh një lidhje imazhi ose videoje."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "inställningsuppgradering tillgänglig",
|
||||
"settings_upgrade_review_button": "granska",
|
||||
"settings_upgrade_never_show_again": "visa inte igen",
|
||||
"site_legal_meta_contributors_link": "Bidragsgivare"
|
||||
"site_legal_meta_contributors_link": "Bidragsgivare",
|
||||
"post_link_required_alert": "Du måste posta en länk.",
|
||||
"post_media_link_required_alert": "Du måste posta en bild- eller videolänk."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "సెట్టింగ్ల అప్గ్రేడ్ అందుబాటులో ఉంది",
|
||||
"settings_upgrade_review_button": "సమీక్షించు",
|
||||
"settings_upgrade_never_show_again": "మళ్లీ చూపించవద్దు",
|
||||
"site_legal_meta_contributors_link": "సహకారులు"
|
||||
"site_legal_meta_contributors_link": "సహకారులు",
|
||||
"post_link_required_alert": "మీరు ఒక లింక్ పోస్ట్ చేయాలి.",
|
||||
"post_media_link_required_alert": "మీరు చిత్రం లేదా వీడియో లింక్ పోస్ట్ చేయాలి."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "มีการอัปเกรดการตั้งค่า",
|
||||
"settings_upgrade_review_button": "ตรวจสอบ",
|
||||
"settings_upgrade_never_show_again": "ไม่ต้องแสดงอีก",
|
||||
"site_legal_meta_contributors_link": "ผู้มีส่วนร่วม"
|
||||
"site_legal_meta_contributors_link": "ผู้มีส่วนร่วม",
|
||||
"post_link_required_alert": "คุณต้องโพสต์ลิงก์",
|
||||
"post_media_link_required_alert": "คุณต้องโพสต์ลิงก์รูปภาพหรือวิดีโอ"
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "ayar yükseltmesi mevcut",
|
||||
"settings_upgrade_review_button": "incele",
|
||||
"settings_upgrade_never_show_again": "bir daha gösterme",
|
||||
"site_legal_meta_contributors_link": "Katkıda Bulunanlar"
|
||||
"site_legal_meta_contributors_link": "Katkıda Bulunanlar",
|
||||
"post_link_required_alert": "Bir bağlantı paylaşmalısınız.",
|
||||
"post_media_link_required_alert": "Bir görsel veya video bağlantısı paylaşmalısınız."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "оновлення налаштувань доступне",
|
||||
"settings_upgrade_review_button": "переглянути",
|
||||
"settings_upgrade_never_show_again": "більше не показувати",
|
||||
"site_legal_meta_contributors_link": "Учасники"
|
||||
"site_legal_meta_contributors_link": "Учасники",
|
||||
"post_link_required_alert": "Потрібно опублікувати посилання.",
|
||||
"post_media_link_required_alert": "Потрібно опублікувати посилання на зображення або відео."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "ترتیبات اپ گریڈ دستیاب",
|
||||
"settings_upgrade_review_button": "جائزہ لیں",
|
||||
"settings_upgrade_never_show_again": "دوبارہ نہ دکھائیں",
|
||||
"site_legal_meta_contributors_link": "شراکت کنندگان"
|
||||
"site_legal_meta_contributors_link": "شراکت کنندگان",
|
||||
"post_link_required_alert": "آپ کو ایک لنک پوسٹ کرنا ہوگا۔",
|
||||
"post_media_link_required_alert": "آپ کو تصویر یا ویڈیو کا لنک پوسٹ کرنا ہوگا۔"
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "nâng cấp cài đặt có sẵn",
|
||||
"settings_upgrade_review_button": "xem lại",
|
||||
"settings_upgrade_never_show_again": "không hiển thị lại",
|
||||
"site_legal_meta_contributors_link": "Người đóng góp"
|
||||
"site_legal_meta_contributors_link": "Người đóng góp",
|
||||
"post_link_required_alert": "Bạn phải đăng một liên kết.",
|
||||
"post_media_link_required_alert": "Bạn phải đăng liên kết hình ảnh hoặc video."
|
||||
}
|
||||
|
||||
@@ -443,5 +443,7 @@
|
||||
"settings_upgrade_review_notice": "设置升级可用",
|
||||
"settings_upgrade_review_button": "查看",
|
||||
"settings_upgrade_never_show_again": "不再显示",
|
||||
"site_legal_meta_contributors_link": "贡献者"
|
||||
"site_legal_meta_contributors_link": "贡献者",
|
||||
"post_link_required_alert": "你必须发布一个链接。",
|
||||
"post_media_link_required_alert": "你必须发布图片或视频链接。"
|
||||
}
|
||||
|
||||
@@ -170,8 +170,17 @@ vi.mock('../../../hooks/use-resolved-community-address', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('../../../hooks/use-stable-community', () => ({
|
||||
useCommunityField: <T,>(communityAddress: string | undefined, selector: (community?: { roles?: Record<string, { role?: string }> }) => T) =>
|
||||
selector(communityAddress ? { roles: testState.rolesByCommunity[communityAddress] } : undefined),
|
||||
useCommunityField: <T,>(communityAddress: string | undefined, selector: (community?: Record<string, unknown> & { roles?: Record<string, { role?: string }> }) => T) => {
|
||||
const community = communityAddress ? (testState.communities[communityAddress] as Record<string, unknown> | undefined) : undefined;
|
||||
return selector(
|
||||
communityAddress
|
||||
? ({
|
||||
...community,
|
||||
roles: testState.rolesByCommunity[communityAddress],
|
||||
} as Record<string, unknown> & { roles?: Record<string, { role?: string }> })
|
||||
: undefined,
|
||||
);
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../../../hooks/use-fetch-gif-first-frame', () => ({
|
||||
@@ -765,6 +774,109 @@ describe('PostForm', () => {
|
||||
expect(testState.publishedPostOptions?.content).toBe(youtubeLink);
|
||||
});
|
||||
|
||||
it('requires a link when live community features require post links', async () => {
|
||||
testState.resolvedCommunityAddress = 'music-posting.eth';
|
||||
testState.communities['music-posting.eth'] = {
|
||||
address: 'music-posting.eth',
|
||||
features: { requirePostLink: true },
|
||||
};
|
||||
|
||||
await renderPostForm('/mu');
|
||||
await clickByText(container, 'start_new_thread');
|
||||
|
||||
const table = container.querySelector('table') as HTMLTableElement;
|
||||
const textarea = table.querySelector('textarea') as HTMLTextAreaElement;
|
||||
const linkInput = table.querySelectorAll<HTMLInputElement>('input[type="text"]')[3];
|
||||
|
||||
await dispatchInput(textarea, 'Link required thread');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(container.textContent).toContain('error: post_link_required_alert');
|
||||
const linkRequiredError = Array.from(container.querySelectorAll('div')).find((element) => element.textContent === 'error: post_link_required_alert');
|
||||
expect(linkRequiredError?.className).toContain('error');
|
||||
expect(linkRequiredError?.className).toContain('formError');
|
||||
expect(linkRequiredError?.closest('tfoot')).toBeTruthy();
|
||||
expect(testState.publishPostMock).not.toHaveBeenCalled();
|
||||
|
||||
await dispatchInput(linkInput, 'https://example.com/thread');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(testState.publishPostMock).toHaveBeenCalledTimes(1);
|
||||
expect(testState.publishedPostOptions?.link).toBe('https://example.com/thread');
|
||||
});
|
||||
|
||||
it('requires a media link when live community features require post links to be media', async () => {
|
||||
testState.resolvedCommunityAddress = 'music-posting.eth';
|
||||
testState.communities['music-posting.eth'] = {
|
||||
address: 'music-posting.eth',
|
||||
features: { requirePostLink: true, requirePostLinkIsMedia: true },
|
||||
};
|
||||
|
||||
await renderPostForm('/mu');
|
||||
await clickByText(container, 'start_new_thread');
|
||||
|
||||
const table = container.querySelector('table') as HTMLTableElement;
|
||||
const textarea = table.querySelector('textarea') as HTMLTextAreaElement;
|
||||
const linkInput = table.querySelectorAll<HTMLInputElement>('input[type="text"]')[3];
|
||||
|
||||
await dispatchInput(textarea, 'Media required thread');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(container.textContent).toContain('error: post_media_link_required_alert');
|
||||
const mediaRequiredError = Array.from(container.querySelectorAll('div')).find((element) => element.textContent === 'error: post_media_link_required_alert');
|
||||
expect(mediaRequiredError?.className).toContain('error');
|
||||
expect(mediaRequiredError?.className).toContain('formError');
|
||||
expect(mediaRequiredError?.closest('tfoot')).toBeTruthy();
|
||||
expect(testState.publishPostMock).not.toHaveBeenCalled();
|
||||
|
||||
await dispatchInput(linkInput, 'https://example.com/page');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(container.textContent).toContain('error: link_not_image_or_video_alert');
|
||||
expect(testState.publishPostMock).not.toHaveBeenCalled();
|
||||
|
||||
await dispatchInput(linkInput, 'https://example.com/image.jpg');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(testState.publishPostMock).toHaveBeenCalledTimes(1);
|
||||
expect(testState.publishedPostOptions?.link).toBe('https://example.com/image.jpg');
|
||||
});
|
||||
|
||||
it('does not require an empty link when only media links are constrained', async () => {
|
||||
testState.resolvedCommunityAddress = 'current-news.bso';
|
||||
testState.directories.push({
|
||||
address: 'current-news.bso',
|
||||
directoryCode: 'news',
|
||||
features: { requirePostLink: false, requirePostLinkIsMedia: true },
|
||||
title: '/news/ - Current News',
|
||||
});
|
||||
testState.communities['current-news.bso'] = {
|
||||
address: 'current-news.bso',
|
||||
features: { requirePostLink: false, requirePostLinkIsMedia: true },
|
||||
};
|
||||
|
||||
await renderPostForm('/news');
|
||||
await clickByText(container, 'start_new_thread');
|
||||
|
||||
const table = container.querySelector('table') as HTMLTableElement;
|
||||
const textarea = table.querySelector('textarea') as HTMLTextAreaElement;
|
||||
const linkInput = table.querySelectorAll<HTMLInputElement>('input[type="text"]')[3];
|
||||
|
||||
await dispatchInput(textarea, 'News body with source in text');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(container.textContent).not.toContain('post_media_link_required_alert');
|
||||
expect(testState.publishPostMock).toHaveBeenCalledTimes(1);
|
||||
expect(testState.publishedPostOptions?.link).toBeUndefined();
|
||||
|
||||
testState.publishPostMock.mockClear();
|
||||
await dispatchInput(linkInput, 'https://example.com/article');
|
||||
await clickByText(table, 'post');
|
||||
|
||||
expect(container.textContent).toContain('error: link_not_image_or_video_alert');
|
||||
expect(testState.publishPostMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('ignores duplicate post clicks while youtube thumbnail resolution is pending', async () => {
|
||||
const youtubeLink = 'https://www.youtube.com/watch?v=slow123';
|
||||
const thumbnailLink = 'https://img.youtube.com/vi/slow123/maxresdefault.jpg';
|
||||
|
||||
@@ -6,13 +6,8 @@ import { Comment, setAccount, useAccount, useAccountComment, useEditedComment }
|
||||
import getShortAddress from '../../lib/get-short-address';
|
||||
import { communitiesPagesStore as useCommunitiesPagesStore } from '../../lib/bitsocial-internals/stores';
|
||||
import { getDisplayMediaInfoType, getLinkMediaInfo, getTwimgMediaFilePublishUrl } from '../../lib/utils/media-utils';
|
||||
import {
|
||||
getExpiringMediaLinkAlert,
|
||||
getPublishFileDisplayName,
|
||||
getPublishLinkOptions,
|
||||
isPublishFileMediaLink,
|
||||
isPublishFileMediaType,
|
||||
} from '../../lib/utils/media-link-validation-utils';
|
||||
import { getExpiringMediaLinkAlert, getPublishFileDisplayName, getPublishLinkOptions, isPublishFileMediaType } from '../../lib/utils/media-link-validation-utils';
|
||||
import { getEffectivePublishLinkFeatures, getPublishLinkValidationError, getRequirePostLink, getRequirePostLinkIsMedia } from '../../lib/utils/publish-link-requirements';
|
||||
import {
|
||||
type DiceRoll,
|
||||
type FortuneEntry,
|
||||
@@ -27,7 +22,7 @@ import {
|
||||
isPostOptionsValidationError,
|
||||
} from '../../lib/utils/post-options-utils';
|
||||
import { truncateWithEllipsisInMiddle } from '../../lib/utils/string-utils';
|
||||
import { isValidPublishURL, isValidURL } from '../../lib/utils/url-utils';
|
||||
import { isValidURL } from '../../lib/utils/url-utils';
|
||||
import { getModerationPostingRoleLabel } from '../../lib/utils/author-display-utils';
|
||||
import { hasModQueueAccessRole } from '../../lib/utils/mod-access';
|
||||
import { getBoardPath, isDirectoryRoute } from '../../lib/utils/route-utils';
|
||||
@@ -577,8 +572,10 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
|
||||
const showSpoilerForReply = directoryEntry?.features?.noSpoilerReplies !== true;
|
||||
const postOptionsDirectoryCode = getPostOptionsDirectoryCode(directoryEntry, location.pathname);
|
||||
const showOekakiControls = postOptionsDirectoryCode === 'i' || directoryEntry?.directoryCode === 'i';
|
||||
const requirePostLinkIsMediaFeature = directoryEntry?.features?.requirePostLinkIsMedia;
|
||||
const requirePostLinkIsMedia = requirePostLinkIsMediaFeature === true || (requirePostLinkIsMediaFeature === undefined && (isInAllView || isInSubscriptionsView));
|
||||
const communityFeatures = useCommunityField(effectiveBoardAddress, (community) => community?.features);
|
||||
const publishLinkFeatures = getEffectivePublishLinkFeatures(communityFeatures, directoryEntry?.features);
|
||||
const requirePostLink = getRequirePostLink(publishLinkFeatures);
|
||||
const requirePostLinkIsMedia = getRequirePostLinkIsMedia(publishLinkFeatures, isInAllView || isInSubscriptionsView);
|
||||
const flagOptions = getCommentFlagOptionsForDirectory(directoryEntry);
|
||||
const showFlashUploadPrompt = isFlashDirectoryCode(postOptionsDirectoryCode);
|
||||
const showFlashTagSelector = showFlashUploadPrompt && !isInPostView;
|
||||
@@ -680,12 +677,14 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
|
||||
setFormError(`${t('error')}: ${t('empty_comment_alert')}`);
|
||||
return;
|
||||
}
|
||||
if (currentUrl && !isValidPublishURL(currentUrl)) {
|
||||
setFormError(`${t('error')}: ${t('invalid_url_alert')}`);
|
||||
return;
|
||||
}
|
||||
if (currentUrl && requirePostLinkIsMedia && !isPublishFileMediaLink(currentUrl)) {
|
||||
setFormError(`${t('error')}: ${t('link_not_image_or_video_alert')}`);
|
||||
const linkValidationError = getPublishLinkValidationError({
|
||||
link: currentUrl,
|
||||
requireLink: requirePostLink,
|
||||
requireMedia: requirePostLinkIsMedia,
|
||||
t,
|
||||
});
|
||||
if (linkValidationError) {
|
||||
setFormError(linkValidationError);
|
||||
return;
|
||||
}
|
||||
const expiringMediaLinkAlert = currentUrl ? getExpiringMediaLinkAlert(currentUrl, t) : null;
|
||||
@@ -809,12 +808,14 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid:
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentUrl && !isValidPublishURL(currentUrl)) {
|
||||
setFormError(`${t('error')}: ${t('invalid_url_alert')}`);
|
||||
return;
|
||||
}
|
||||
if (currentUrl && requirePostLinkIsMedia && !isPublishFileMediaLink(currentUrl)) {
|
||||
setFormError(`${t('error')}: ${t('link_not_image_or_video_alert')}`);
|
||||
const linkValidationError = getPublishLinkValidationError({
|
||||
link: currentUrl,
|
||||
requireLink: requirePostLink,
|
||||
requireMedia: requirePostLinkIsMedia,
|
||||
t,
|
||||
});
|
||||
if (linkValidationError) {
|
||||
setFormError(linkValidationError);
|
||||
return;
|
||||
}
|
||||
const expiringMediaLinkAlert = currentUrl ? getExpiringMediaLinkAlert(currentUrl, t) : null;
|
||||
|
||||
@@ -61,7 +61,7 @@ const testState = vi.hoisted(() => ({
|
||||
'music-posting.eth': {
|
||||
address: 'music-posting.eth',
|
||||
},
|
||||
} as Record<string, { address: string }>,
|
||||
} as Record<string, { address: string; features?: Record<string, unknown> }>,
|
||||
fetchMock: vi.fn(),
|
||||
showUploadControls: true,
|
||||
uploadComplete: undefined as ((url: string) => void) | undefined,
|
||||
@@ -187,8 +187,18 @@ vi.mock('../../../hooks/use-resolved-community-address', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('../../../hooks/use-stable-community', () => ({
|
||||
useCommunityField: <T,>(communityAddress: string | undefined, selector: (community?: { roles?: Record<string, { role?: string }> }) => T) =>
|
||||
selector(communityAddress ? { roles: testState.rolesByCommunity[communityAddress] } : undefined),
|
||||
useCommunityField: <T,>(
|
||||
communityAddress: string | undefined,
|
||||
selector: (community?: { features?: Record<string, unknown>; roles?: Record<string, { role?: string }> }) => T,
|
||||
) =>
|
||||
selector(
|
||||
communityAddress
|
||||
? {
|
||||
...testState.communities[communityAddress],
|
||||
roles: testState.rolesByCommunity[communityAddress],
|
||||
}
|
||||
: undefined,
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('../../../hooks/use-publish-reply', async () => {
|
||||
@@ -755,6 +765,86 @@ describe('ReplyModal', () => {
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('requires a link when live community features require post links', async () => {
|
||||
testState.openEmpty = true;
|
||||
testState.selectedText = 'Reply body';
|
||||
testState.communities['music-posting.eth'] = {
|
||||
address: 'music-posting.eth',
|
||||
features: { requirePostLink: true },
|
||||
};
|
||||
|
||||
await renderReplyModal('/mu/thread/post-1');
|
||||
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(container.textContent).toContain('error: post_link_required_alert');
|
||||
const linkRequiredError = Array.from(container.querySelectorAll('div')).find((element) => element.textContent === 'error: post_link_required_alert');
|
||||
expect(linkRequiredError?.className).toContain('error');
|
||||
expect(testState.publishReplyMock).not.toHaveBeenCalled();
|
||||
|
||||
const linkInput = container.querySelectorAll<HTMLInputElement>('input[type="text"]')[2];
|
||||
await dispatchInput(linkInput, 'https://example.com/reply');
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(testState.setPublishReplyOptionsMock).toHaveBeenCalledWith({ link: 'https://example.com/reply' });
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('requires a media link when live community features require post links to be media', async () => {
|
||||
testState.openEmpty = true;
|
||||
testState.selectedText = 'Reply body';
|
||||
testState.communities['music-posting.eth'] = {
|
||||
address: 'music-posting.eth',
|
||||
features: { requirePostLink: true, requirePostLinkIsMedia: true },
|
||||
};
|
||||
|
||||
await renderReplyModal('/mu/thread/post-1');
|
||||
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(container.textContent).toContain('error: post_media_link_required_alert');
|
||||
const mediaRequiredError = Array.from(container.querySelectorAll('div')).find((element) => element.textContent === 'error: post_media_link_required_alert');
|
||||
expect(mediaRequiredError?.className).toContain('error');
|
||||
expect(testState.publishReplyMock).not.toHaveBeenCalled();
|
||||
|
||||
const linkInput = container.querySelectorAll<HTMLInputElement>('input[type="text"]')[2];
|
||||
await dispatchInput(linkInput, 'https://example.com/page');
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(container.textContent).toContain('error: link_not_image_or_video_alert');
|
||||
expect(testState.publishReplyMock).not.toHaveBeenCalled();
|
||||
|
||||
await dispatchInput(linkInput, 'https://example.com/reply.png');
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(testState.setPublishReplyOptionsMock).toHaveBeenCalledWith({ link: 'https://example.com/reply.png' });
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not require an empty link when only media links are constrained', async () => {
|
||||
testState.openEmpty = true;
|
||||
testState.selectedText = 'Reply body';
|
||||
testState.communities['music-posting.eth'] = {
|
||||
address: 'music-posting.eth',
|
||||
features: { requirePostLink: false, requirePostLinkIsMedia: true },
|
||||
};
|
||||
|
||||
await renderReplyModal('/mu/thread/post-1');
|
||||
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(container.textContent).not.toContain('post_media_link_required_alert');
|
||||
expect(testState.publishReplyMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
testState.publishReplyMock.mockClear();
|
||||
const linkInput = container.querySelectorAll<HTMLInputElement>('input[type="text"]')[2];
|
||||
await dispatchInput(linkInput, 'https://example.com/page');
|
||||
await clickButtonByText('post');
|
||||
|
||||
expect(container.textContent).toContain('error: link_not_image_or_video_alert');
|
||||
expect(testState.publishReplyMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('publishes twimg query-format reply links with a path extension', async () => {
|
||||
testState.openEmpty = true;
|
||||
testState.selectedText = 'reply body';
|
||||
|
||||
@@ -3,8 +3,9 @@ import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { setAccount, useAccount } from '@bitsocial/bitsocial-react-hooks';
|
||||
import { getExpiringMediaLinkAlert, getPublishFileDisplayName, getPublishLinkOptions, isPublishFileMediaLink } from '../../lib/utils/media-link-validation-utils';
|
||||
import { getExpiringMediaLinkAlert, getPublishFileDisplayName, getPublishLinkOptions } from '../../lib/utils/media-link-validation-utils';
|
||||
import { getTwimgMediaFilePublishUrl } from '../../lib/utils/media-utils';
|
||||
import { getEffectivePublishLinkFeatures, getPublishLinkValidationError, getRequirePostLink, getRequirePostLinkIsMedia } from '../../lib/utils/publish-link-requirements';
|
||||
import { getCommentFlagOptionsForDirectory, getCommentFlagPublishOptionsForDirectory } from '../../lib/comment-flag-selection';
|
||||
import {
|
||||
type DiceRoll,
|
||||
@@ -18,7 +19,6 @@ import {
|
||||
hasNonokoOption,
|
||||
isPostOptionsValidationError,
|
||||
} from '../../lib/utils/post-options-utils';
|
||||
import { isValidPublishURL } from '../../lib/utils/url-utils';
|
||||
import { isMathDirectoryCode } from '../../lib/math-tags';
|
||||
import { hasModQueueAccessRole } from '../../lib/utils/mod-access';
|
||||
import { getModerationPostingRoleLabel } from '../../lib/utils/author-display-utils';
|
||||
@@ -78,8 +78,10 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, parentNumber, threa
|
||||
const postOptionsDirectoryCode = getPostOptionsDirectoryCode(directoryEntry, location.pathname);
|
||||
const showOekakiControls = postOptionsDirectoryCode === 'i' || directoryEntry?.directoryCode === 'i';
|
||||
const showTexButton = isMathDirectoryCode(postOptionsDirectoryCode) || isMathDirectoryCode(directoryEntry?.directoryCode);
|
||||
const requirePostLinkIsMediaFeature = directoryEntry?.features?.requirePostLinkIsMedia;
|
||||
const requirePostLinkIsMedia = requirePostLinkIsMediaFeature === true || (requirePostLinkIsMediaFeature === undefined && (isInAllView || isInSubscriptionsView));
|
||||
const communityFeatures = useCommunityField(communityAddress, (community) => community?.features);
|
||||
const publishLinkFeatures = getEffectivePublishLinkFeatures(communityFeatures, directoryEntry?.features);
|
||||
const requirePostLink = getRequirePostLink(publishLinkFeatures);
|
||||
const requirePostLinkIsMedia = getRequirePostLinkIsMedia(publishLinkFeatures, isInAllView || isInSubscriptionsView);
|
||||
const flagOptions = getCommentFlagOptionsForDirectory(directoryEntry);
|
||||
const { isResolvingExternalQuotes, publishReply, publishReplyError, publishReplyStateMessage, resetPublishReplyOptions, replyIndex, setPublishReplyOptions } =
|
||||
usePublishReply({
|
||||
@@ -184,12 +186,14 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, parentNumber, threa
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentUrl && !isValidPublishURL(currentUrl)) {
|
||||
setError(t('error') + ': ' + t('invalid_url_alert'));
|
||||
return;
|
||||
}
|
||||
if (currentUrl && requirePostLinkIsMedia && !isPublishFileMediaLink(currentUrl)) {
|
||||
setError(t('error') + ': ' + t('link_not_image_or_video_alert'));
|
||||
const linkValidationError = getPublishLinkValidationError({
|
||||
link: currentUrl,
|
||||
requireLink: requirePostLink,
|
||||
requireMedia: requirePostLinkIsMedia,
|
||||
t,
|
||||
});
|
||||
if (linkValidationError) {
|
||||
setError(linkValidationError);
|
||||
return;
|
||||
}
|
||||
const expiringMediaLinkAlert = currentUrl ? getExpiringMediaLinkAlert(currentUrl, t) : null;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { getEffectivePublishLinkFeatures, getPublishLinkValidationError, getRequirePostLink, getRequirePostLinkIsMedia } from '../publish-link-requirements';
|
||||
|
||||
const t = ((key: string) => key) as TFunction;
|
||||
|
||||
describe('getEffectivePublishLinkFeatures', () => {
|
||||
it('uses live community feature values before directory defaults', () => {
|
||||
expect(getEffectivePublishLinkFeatures({ requirePostLink: false }, { requirePostLink: true, requirePostLinkIsMedia: true })).toEqual({
|
||||
requirePostLink: false,
|
||||
requirePostLinkIsMedia: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('falls back per feature when live community features are partial', () => {
|
||||
expect(getEffectivePublishLinkFeatures({ requirePostLinkIsMedia: false }, { requirePostLink: true, requirePostLinkIsMedia: true })).toEqual({
|
||||
requirePostLink: true,
|
||||
requirePostLinkIsMedia: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPublishLinkValidationError', () => {
|
||||
it('does not require an empty link when only media links are enabled', () => {
|
||||
expect(getPublishLinkValidationError({ link: '', requireLink: false, requireMedia: true, t })).toBeNull();
|
||||
});
|
||||
|
||||
it('requires a media link when both link and media requirements are enabled', () => {
|
||||
expect(getPublishLinkValidationError({ link: '', requireLink: true, requireMedia: true, t })).toBe('error: post_media_link_required_alert');
|
||||
});
|
||||
});
|
||||
|
||||
describe('publish link feature helpers', () => {
|
||||
it('does not treat media-only validation as a required link', () => {
|
||||
const features = getEffectivePublishLinkFeatures({ requirePostLink: false, requirePostLinkIsMedia: true }, undefined);
|
||||
|
||||
expect(getRequirePostLink(features)).toBe(false);
|
||||
expect(getRequirePostLinkIsMedia(features, false)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { TFunction } from 'i18next';
|
||||
import { isPublishFileMediaLink } from './media-link-validation-utils';
|
||||
import { isValidPublishURL } from './url-utils';
|
||||
|
||||
interface PublishLinkFeatures {
|
||||
requirePostLink?: unknown;
|
||||
requirePostLinkIsMedia?: unknown;
|
||||
}
|
||||
|
||||
export const getEffectivePublishLinkFeatures = (
|
||||
communityFeatures: PublishLinkFeatures | undefined,
|
||||
directoryFeatures: PublishLinkFeatures | undefined,
|
||||
): PublishLinkFeatures | undefined => {
|
||||
const requirePostLink = communityFeatures?.requirePostLink ?? directoryFeatures?.requirePostLink;
|
||||
const requirePostLinkIsMedia = communityFeatures?.requirePostLinkIsMedia ?? directoryFeatures?.requirePostLinkIsMedia;
|
||||
|
||||
if (requirePostLink === undefined && requirePostLinkIsMedia === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
requirePostLink,
|
||||
requirePostLinkIsMedia,
|
||||
};
|
||||
};
|
||||
|
||||
export const getRequirePostLink = (features: PublishLinkFeatures | undefined): boolean => Boolean(features?.requirePostLink);
|
||||
|
||||
export const getRequirePostLinkIsMedia = (features: PublishLinkFeatures | undefined, useMediaDefault: boolean): boolean =>
|
||||
Boolean(features?.requirePostLinkIsMedia) || (features?.requirePostLinkIsMedia === undefined && useMediaDefault);
|
||||
|
||||
export const getPublishLinkValidationError = ({
|
||||
link,
|
||||
requireLink,
|
||||
requireMedia,
|
||||
t,
|
||||
}: {
|
||||
link: string;
|
||||
requireLink: boolean;
|
||||
requireMedia: boolean;
|
||||
t: TFunction;
|
||||
}): string | null => {
|
||||
if (!link && requireLink) {
|
||||
return `${t('error')}: ${t(requireMedia ? 'post_media_link_required_alert' : 'post_link_required_alert')}`;
|
||||
}
|
||||
if (link && !isValidPublishURL(link)) {
|
||||
return `${t('error')}: ${t('invalid_url_alert')}`;
|
||||
}
|
||||
if (link && requireMedia && !isPublishFileMediaLink(link)) {
|
||||
return `${t('error')}: ${t('link_not_image_or_video_alert')}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
Reference in New Issue
Block a user