mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
fix: prevent popup cascade when Telegram callback doesn't fire
- Add persistent popupClosed listener that resets state even after per-call listener is removed by timeout - Increase safety timeout from 5s to 30s to give user time to interact - On WebAppPopupOpened error, keep popupOpen=true to block retries instead of resetting and allowing infinite error loop - Remove callback param from showPopup to avoid dual-listener conflicts - Remove debug console logs
This commit is contained in:
@@ -184,6 +184,17 @@ function createDialogController(): DialogController {
|
|||||||
const inTelegram = isInTelegramWebApp();
|
const inTelegram = isInTelegramWebApp();
|
||||||
let popupOpen = false;
|
let popupOpen = false;
|
||||||
|
|
||||||
|
// Persistent listener: resets popupOpen whenever Telegram reports popup closed,
|
||||||
|
// even if our per-call listener was already removed.
|
||||||
|
if (inTelegram) {
|
||||||
|
const tg = getTelegram();
|
||||||
|
if (tg?.onEvent) {
|
||||||
|
tg.onEvent('popupClosed', (() => {
|
||||||
|
popupOpen = false;
|
||||||
|
}) as (...args: unknown[]) => void);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showPopupSafe<T>(
|
function showPopupSafe<T>(
|
||||||
params: Parameters<NonNullable<TelegramWebApp['showPopup']>>[0],
|
params: Parameters<NonNullable<TelegramWebApp['showPopup']>>[0],
|
||||||
mapResult: (buttonId: string) => T,
|
mapResult: (buttonId: string) => T,
|
||||||
@@ -203,8 +214,6 @@ function createDialogController(): DialogController {
|
|||||||
popupOpen = true;
|
popupOpen = true;
|
||||||
let settled = false;
|
let settled = false;
|
||||||
|
|
||||||
console.log('[popup] opening', JSON.stringify(params));
|
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
if (settled) return;
|
if (settled) return;
|
||||||
settled = true;
|
settled = true;
|
||||||
@@ -214,7 +223,6 @@ function createDialogController(): DialogController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onPopupClosed = ((...args: unknown[]) => {
|
const onPopupClosed = ((...args: unknown[]) => {
|
||||||
console.log('[popup] popupClosed event', JSON.stringify(args));
|
|
||||||
if (settled) return;
|
if (settled) return;
|
||||||
const event = args[0] as { button_id?: string } | undefined;
|
const event = args[0] as { button_id?: string } | undefined;
|
||||||
const buttonId = event?.button_id ?? '';
|
const buttonId = event?.button_id ?? '';
|
||||||
@@ -223,24 +231,29 @@ function createDialogController(): DialogController {
|
|||||||
}) as (...args: unknown[]) => void;
|
}) as (...args: unknown[]) => void;
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
console.log('[popup] timeout — force reset');
|
|
||||||
if (settled) return;
|
if (settled) return;
|
||||||
cleanup();
|
cleanup();
|
||||||
resolve(mapResult(''));
|
resolve(mapResult(''));
|
||||||
}, 5_000);
|
}, 30_000);
|
||||||
|
|
||||||
tg.onEvent?.('popupClosed', onPopupClosed);
|
tg.onEvent?.('popupClosed', onPopupClosed);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tg.showPopup(params, (buttonId) => {
|
tg.showPopup(params);
|
||||||
console.log('[popup] callback fired, buttonId=', buttonId);
|
|
||||||
if (settled) return;
|
|
||||||
cleanup();
|
|
||||||
resolve(mapResult(buttonId));
|
|
||||||
});
|
|
||||||
console.log('[popup] showPopup called OK');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[popup] showPopup threw', e);
|
// Telegram SDK says a popup is already open — don't reset popupOpen,
|
||||||
|
// so subsequent calls are silently blocked until the popup actually closes.
|
||||||
|
const isAlreadyOpen = e instanceof Error && e.message?.includes('WebAppPopupOpened');
|
||||||
|
|
||||||
|
if (isAlreadyOpen) {
|
||||||
|
settled = true;
|
||||||
|
clearTimeout(timer);
|
||||||
|
tg.offEvent?.('popupClosed', onPopupClosed);
|
||||||
|
// popupOpen stays true — the persistent listener will reset it
|
||||||
|
resolve(mapResult(''));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
resolve(fallback());
|
resolve(fallback());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user