Skip to content

Commit 8e38188

Browse files
Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 8bed725 commit 8e38188

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

src/shared/components/AccountButton/AccountButton.tsx

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ export const AccountButton = ({ logo, children, connected = false, connectedLabe
4141
}
4242
};
4343

44+
useEffect(() => {
45+
return () => {
46+
clearTimer();
47+
if (popupRef.current && !popupRef.current.closed) {
48+
popupRef.current.close();
49+
}
50+
};
51+
}, []);
4452
const fetchAndApply = async (opts: { showToast: boolean }): Promise<boolean> => {
4553
if (!responseId || !questionId) return false;
4654
try {
@@ -108,10 +116,49 @@ export const AccountButton = ({ logo, children, connected = false, connectedLabe
108116
setIsConnecting(true);
109117
clearTimer();
110118

119+
const handleMessage = async (event: MessageEvent) => {
120+
// Only handle messages from this popup and same origin
121+
if (event.source !== popup) return;
122+
if (event.origin !== window.location.origin) return;
123+
124+
const data: any = event.data;
125+
if (!data || data.type !== "FORM_OAUTH_CONNECTED") return;
126+
if (data.questionId !== questionId || data.responseId !== responseId) return;
127+
128+
// Mark this popup as handled so the interval callback does not re-fetch
129+
(popup as any).__oauthHandled = true;
130+
131+
clearTimer();
132+
window.removeEventListener("message", handleMessage);
133+
134+
try {
135+
if (data.error) {
136+
const errorMessage = typeof data.error === "string" ? data.error : "綁定失敗,請再試一次";
137+
pushToast({ title: "綁定失敗", description: errorMessage, variant: "error" });
138+
onConnectErrorRef.current?.(errorMessage);
139+
} else {
140+
await fetchAndApply({ showToast: true });
141+
}
142+
} finally {
143+
setIsConnecting(false);
144+
try {
145+
popup.close();
146+
} catch {
147+
// ignore
148+
}
149+
}
150+
};
151+
152+
window.addEventListener("message", handleMessage);
153+
111154
timerRef.current = window.setInterval(async () => {
112155
if (popup.closed) {
113156
clearTimer();
114-
await fetchAndApply({ showToast: true });
157+
window.removeEventListener("message", handleMessage);
158+
// If no FORM_OAUTH_CONNECTED message was handled, fall back to fetching
159+
if (!(popup as any).__oauthHandled) {
160+
await fetchAndApply({ showToast: true });
161+
}
115162
setIsConnecting(false);
116163
}
117164
}, 500);

0 commit comments

Comments
 (0)