fix(geocheck): убрать полноэкранный режим в Telegram Mini App

В Mini App окно Telegram и так занимает экран целиком, поэтому режим ничего
не давал: он лишь снимал отступы модалки и лез под шапку и home indicator.
Кнопка полезна на десктопе, где отчёт показывается в центрированном окне.

Модалка определяет платформу через готовый useIsTelegram и передаёт отчёту
canFullscreen; при выключенном флаге кнопка не рендерится, а запрошенный
режим не применяется, даже если состояние осталось от прошлого открытия.

Проверено рендером на обеих платформах в одном дереве: telegram —
canFullscreen=false и 8 кнопок в тулбаре, web — true и 9. Разница ровно в
одной кнопке.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
c0mrade
2026-08-19 17:33:56 +03:00
parent debe26ae35
commit 5db1ffccf6
2 changed files with 34 additions and 15 deletions

View File

@@ -5,6 +5,7 @@ import type { NodeInfo } from '@/api/adminRemnawave';
import { GeoCheckIcon, PlayIcon, WarningIcon, XCloseIcon } from '@/components/icons';
import { Spinner } from '@/components/ui/Spinner';
import { useFocusTrap } from '@/hooks/useFocusTrap';
import { useIsTelegram } from '@/platform/hooks/usePlatform';
import { cn } from '@/lib/utils';
import { GeoCheckReport } from './GeoCheckReport';
import { buildGeoCheckRequest, isRouteReady, type GeoCheckRouteMode } from './geoCheckRoute';
@@ -27,7 +28,12 @@ export function GeoCheckModal({ node, onClose }: GeoCheckModalProps) {
const { t } = useTranslation();
const [mode, setMode] = useState<GeoCheckRouteMode>('default');
const [value, setValue] = useState('');
const [fullscreen, setFullscreen] = useState(false);
const [fullscreenRequested, setFullscreenRequested] = useState(false);
// В Mini App окно Telegram и так занимает экран целиком: отдельный
// полноэкранный режим там только снимал отступы и залезал под хром.
const canFullscreen = !useIsTelegram();
const fullscreen = canFullscreen && fullscreenRequested;
const job = useGeoCheckJob(node.uuid);
const isRunning = job.phase === 'running';
@@ -35,11 +41,11 @@ export function GeoCheckModal({ node, onClose }: GeoCheckModalProps) {
// Пока идёт проверка, закрывать по Escape нельзя: задача уже поставлена
// в панель, и молча потерять её результат — хуже, чем подождать.
const dialogRef = useFocusTrap<HTMLDivElement>(true, {
onEscape: isRunning ? undefined : fullscreen ? () => setFullscreen(false) : onClose,
onEscape: isRunning ? undefined : fullscreen ? () => setFullscreenRequested(false) : onClose,
});
useEffect(() => {
if (job.phase !== 'done') setFullscreen(false);
if (job.phase !== 'done') setFullscreenRequested(false);
}, [job.phase]);
const canStart = isRouteReady(mode, value);
@@ -211,7 +217,8 @@ export function GeoCheckModal({ node, onClose }: GeoCheckModalProps) {
result={job.result}
nodeName={node.name}
fullscreen={fullscreen}
onToggleFullscreen={() => setFullscreen((v) => !v)}
canFullscreen={canFullscreen}
onToggleFullscreen={() => setFullscreenRequested((v) => !v)}
onRerun={job.retry}
/>
)}

View File

@@ -25,6 +25,11 @@ interface GeoCheckReportProps {
result: GeoCheckResult;
nodeName: string;
fullscreen: boolean;
/**
* Показывать ли переключатель полного экрана. В Telegram Mini App окно и так
* во весь экран — режим лишь снимал отступы и лез под хром Telegram.
*/
canFullscreen: boolean;
onToggleFullscreen: () => void;
onRerun: () => void;
}
@@ -42,6 +47,7 @@ export function GeoCheckReport({
result,
nodeName,
fullscreen,
canFullscreen,
onToggleFullscreen,
onRerun,
}: GeoCheckReportProps) {
@@ -133,6 +139,7 @@ export function GeoCheckReport({
</div>
<div className="flex items-center gap-1">
{canFullscreen && (
<button
type="button"
onClick={onToggleFullscreen}
@@ -142,8 +149,13 @@ export function GeoCheckReport({
aria-label={fullscreenLabel}
aria-pressed={fullscreen}
>
{fullscreen ? <CollapseIcon className="h-4 w-4" /> : <ExpandIcon className="h-4 w-4" />}
{fullscreen ? (
<CollapseIcon className="h-4 w-4" />
) : (
<ExpandIcon className="h-4 w-4" />
)}
</button>
)}
<button
type="button"
onClick={handleCopy}