fix(cabinet): blocking screens exit via the native Telegram back button, drop the in-page Close

On a full-screen blocking overlay in the Telegram Mini App there were two exit
affordances: the native back button — which ran SPA navigation on the hidden
route underneath, so it didn't dismiss the block and kept flip-flopping between
Back and Close as the route changed — and a redundant in-page "Close" button on
the service-unavailable screen.

Make the native back button the single, stable exit: while any blocking screen
is active, TelegramBackButton shows one Back button whose click closes the Mini
App (closeTelegramApp) instead of navigating the SPA — no route change, no
Back/Close flip-flop. The normal route-based back button is restored once the
block clears. Remove the in-page Close button.
This commit is contained in:
c0mrade
2026-06-04 13:48:33 +03:00
parent 782568e091
commit f9cc70cba3
2 changed files with 39 additions and 32 deletions

View File

@@ -4,8 +4,7 @@ import { useQueryClient } from '@tanstack/react-query';
import { useBlockingStore } from '../../store/blocking';
import { useFocusTrap } from '../../hooks/useFocusTrap';
import { pingBackend, hasEverReachedBackend } from '../../api/health';
import { isInTelegramWebApp, closeTelegramApp } from '../../hooks/useTelegramSDK';
import { CloudWarningIcon, RestartIcon, CloseIcon } from '@/components/icons';
import { CloudWarningIcon, RestartIcon } from '@/components/icons';
import { Button } from '@/components/primitives';
import { cn } from '@/lib/utils';
import BlockingShell from './BlockingShell';
@@ -25,7 +24,6 @@ export default function ServiceUnavailableScreen() {
const queryClient = useQueryClient();
const [isChecking, setIsChecking] = useState(false);
const isCheckingRef = useRef(false);
const inTelegram = isInTelegramWebApp();
const recover = useCallback(() => {
clearBlocking();
@@ -87,33 +85,18 @@ export default function ServiceUnavailableScreen() {
pulse
footer={t('blocking.serviceUnavailable.hint')}
actions={
<>
<Button
variant="secondary"
size="lg"
fullWidth
onClick={handleRetry}
disabled={isChecking}
leftIcon={<RestartIcon className={cn('h-5 w-5', isChecking && 'animate-spin')} />}
>
{isChecking
? t('blocking.serviceUnavailable.checking')
: t('blocking.serviceUnavailable.retry')}
</Button>
{/* Telegram Mini App only — a browser tab can't be closed by script.
Reliably exits the Mini App instead of routing back. */}
{inTelegram && (
<Button
variant="outline"
size="lg"
fullWidth
onClick={closeTelegramApp}
leftIcon={<CloseIcon className="h-5 w-5" />}
>
{t('blocking.serviceUnavailable.close')}
</Button>
)}
</>
<Button
variant="secondary"
size="lg"
fullWidth
onClick={handleRetry}
disabled={isChecking}
leftIcon={<RestartIcon className={cn('h-5 w-5', isChecking && 'animate-spin')} />}
>
{isChecking
? t('blocking.serviceUnavailable.checking')
: t('blocking.serviceUnavailable.retry')}
</Button>
}
/>
);