mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
fix: resolve SDK v3 mount errors, back button and fullscreen not working
- Обернуть каждый mount-вызов в safeMountSync() для защиты от ConcurrentCallError при HMR/повторной инициализации - Перенести requestFullscreen() внутрь mountViewport().then() — fullscreen требует смонтированный viewport, ранее вызывался через dynamic import с setTimeout до завершения mount - Стабилизировать обработчик BackButton через useRef + useCallback — navigate меняется каждый рендер, что вызывало постоянную пере-подписку и потерю обработчика
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect, useRef, useCallback } from 'react';
|
||||||
import { BrowserRouter, useLocation, useNavigate } from 'react-router-dom';
|
import { BrowserRouter, useLocation, useNavigate } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
showBackButton,
|
showBackButton,
|
||||||
@@ -21,6 +21,8 @@ import { isInTelegramWebApp } from './hooks/useTelegramSDK';
|
|||||||
function TelegramBackButton() {
|
function TelegramBackButton() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const navigateRef = useRef(navigate);
|
||||||
|
navigateRef.current = navigate;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isRoot = location.pathname === '/' || location.pathname === '';
|
const isRoot = location.pathname === '/' || location.pathname === '';
|
||||||
@@ -31,25 +33,29 @@ function TelegramBackButton() {
|
|||||||
showBackButton();
|
showBackButton();
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Not in Telegram or back button not mounted
|
// Back button not mounted
|
||||||
}
|
}
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
|
// Stable handler — ref prevents re-subscription on every render
|
||||||
|
const handler = useCallback(() => {
|
||||||
|
navigateRef.current(-1);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handler = () => navigate(-1);
|
|
||||||
try {
|
try {
|
||||||
onBackButtonClick(handler);
|
onBackButtonClick(handler);
|
||||||
} catch {
|
} catch {
|
||||||
// Not in Telegram
|
// Back button not mounted
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
try {
|
try {
|
||||||
offBackButtonClick(handler);
|
offBackButtonClick(handler);
|
||||||
} catch {
|
} catch {
|
||||||
// Not in Telegram
|
// Back button not mounted
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [navigate]);
|
}, [handler]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/main.tsx
42
src/main.tsx
@@ -17,6 +17,8 @@ import {
|
|||||||
mountMainButton,
|
mountMainButton,
|
||||||
bindThemeParamsCssVars,
|
bindThemeParamsCssVars,
|
||||||
bindViewportCssVars,
|
bindViewportCssVars,
|
||||||
|
requestFullscreen,
|
||||||
|
isFullscreen,
|
||||||
} from '@telegram-apps/sdk-react';
|
} from '@telegram-apps/sdk-react';
|
||||||
import { AppWithNavigator } from './AppWithNavigator';
|
import { AppWithNavigator } from './AppWithNavigator';
|
||||||
import { initLogoPreload } from './api/branding';
|
import { initLogoPreload } from './api/branding';
|
||||||
@@ -24,40 +26,52 @@ import { getCachedFullscreenEnabled, isTelegramMobile } from './hooks/useTelegra
|
|||||||
import './i18n';
|
import './i18n';
|
||||||
import './styles/globals.css';
|
import './styles/globals.css';
|
||||||
|
|
||||||
|
// Safe mount helper — ignores "already mounted/mounting" errors (HMR, StrictMode)
|
||||||
|
function safeMountSync(fn: () => void) {
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
} catch {
|
||||||
|
// Already mounted or not available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize Telegram SDK v3
|
// Initialize Telegram SDK v3
|
||||||
try {
|
try {
|
||||||
init();
|
init();
|
||||||
restoreInitData();
|
restoreInitData();
|
||||||
|
|
||||||
mountMiniApp();
|
safeMountSync(() => mountMiniApp());
|
||||||
|
safeMountSync(() => {
|
||||||
mountThemeParams();
|
mountThemeParams();
|
||||||
bindThemeParamsCssVars();
|
bindThemeParamsCssVars();
|
||||||
|
});
|
||||||
|
safeMountSync(() => {
|
||||||
mountSwipeBehavior();
|
mountSwipeBehavior();
|
||||||
disableVerticalSwipes();
|
disableVerticalSwipes();
|
||||||
|
});
|
||||||
|
safeMountSync(() => {
|
||||||
mountClosingBehavior();
|
mountClosingBehavior();
|
||||||
disableClosingConfirmation();
|
disableClosingConfirmation();
|
||||||
mountBackButton();
|
});
|
||||||
mountMainButton();
|
safeMountSync(() => mountBackButton());
|
||||||
|
safeMountSync(() => mountMainButton());
|
||||||
|
|
||||||
|
// Viewport — async, fullscreen зависит от смонтированного viewport
|
||||||
mountViewport()
|
mountViewport()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
bindViewportCssVars();
|
bindViewportCssVars();
|
||||||
expandViewport();
|
expandViewport();
|
||||||
|
|
||||||
|
// Auto-enter fullscreen if enabled in settings (mobile only)
|
||||||
|
if (getCachedFullscreenEnabled() && isTelegramMobile()) {
|
||||||
|
if (!isFullscreen()) {
|
||||||
|
requestFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
|
||||||
miniAppReady();
|
miniAppReady();
|
||||||
|
|
||||||
// Auto-enter fullscreen if enabled in settings (mobile only)
|
|
||||||
if (getCachedFullscreenEnabled() && isTelegramMobile()) {
|
|
||||||
import('@telegram-apps/sdk-react').then(({ requestFullscreen, isFullscreen }) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!isFullscreen()) {
|
|
||||||
requestFullscreen();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
// Not in Telegram — ok
|
// Not in Telegram — ok
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user