From 9a3e84cc853676beb3e72cb9deb55f3231295797 Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Fri, 10 Jul 2026 11:42:26 +0330 Subject: [PATCH] fix: refactor Altcha component to properly handle custom element registration and attribute setting --- components/Altcha.js | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/components/Altcha.js b/components/Altcha.js index 380ecf0..dbf0fff 100644 --- a/components/Altcha.js +++ b/components/Altcha.js @@ -22,11 +22,6 @@ export default function Altcha({ onVerified }) { // null=در حال بررسی، true/false=فعال/غیرفعال بودن کپچا در سرور const [enabled, setEnabled] = useState(null); - // ثبت custom element فقط در مرورگر (وابسته به customElements/DOM). - useEffect(() => { - import("altcha"); - }, []); - useEffect(() => { let alive = true; fetch(`${API}/api/v1/altcha/config`) @@ -44,27 +39,43 @@ export default function Altcha({ onVerified }) { }; }, [onVerified]); + // ثبت custom element + ست‌کردن config به‌صورت attribute واقعی. در React 18 + // پراپ‌های JSX روی custom element ممکن است به‌جای attribute به‌شکل property ست + // شوند و widget آن‌ها را نخواند (strings/theme اعمال نمی‌شد)؛ با setAttribute + // مطمئن می‌شویم درست خوانده می‌شوند. auto را آخر ست می‌کنیم تا بعد از config حل شود. useEffect(() => { - const el = ref.current; - if (!el) return; + if (enabled !== true) return; + const onStateChange = (e) => { if (e.detail?.state === "verified" && e.detail.payload) { onVerified(e.detail.payload); } }; - el.addEventListener("statechange", onStateChange); - return () => el.removeEventListener("statechange", onStateChange); - }, [onVerified, enabled]); + + // attributeها را قبل از import (قبل از upgrade شدن element) ست می‌کنیم تا + // widget از همان ابتدا با تم روشن و متن فارسی init شود. + const el = ref.current; + if (el) { + el.setAttribute("challengeurl", `${API}/api/v1/altcha/challenge`); + el.setAttribute("strings", FA_STRINGS); + el.setAttribute("theme", "light"); + el.setAttribute("auto", "onload"); + el.addEventListener("statechange", onStateChange); + } + + import("altcha"); + + return () => { + el?.removeEventListener("statechange", onStateChange); + }; + }, [enabled, onVerified]); if (enabled !== true) return null; return ( ); }