From 30ece694d43bd74fd2c26126926ec6452077681f Mon Sep 17 00:00:00 2001 From: Fringg Date: Mon, 23 Feb 2026 17:15:20 +0300 Subject: [PATCH] perf: fix render cycle in useBranding and conditional polling - Remove isFullscreen from useBranding useEffect deps to prevent re-render loop (requestFullscreen changes isFullscreen which re-triggers the effect); use ref guard instead - Make AdminBroadcasts 5s polling conditional: only poll when there are active broadcasts (queued/in_progress/cancelling) --- src/hooks/useBranding.ts | 13 ++++++++----- src/pages/AdminBroadcasts.tsx | 8 +++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/hooks/useBranding.ts b/src/hooks/useBranding.ts index 125ab15..c561600 100644 --- a/src/hooks/useBranding.ts +++ b/src/hooks/useBranding.ts @@ -1,4 +1,4 @@ -import { useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useAuthStore } from '@/store/auth'; import { useTelegramSDK, setCachedFullscreenEnabled } from '@/hooks/useTelegramSDK'; @@ -14,8 +14,8 @@ const FALLBACK_NAME = import.meta.env.VITE_APP_NAME || 'Cabinet'; const FALLBACK_LOGO = import.meta.env.VITE_APP_LOGO || 'V'; export function useBranding() { - const { isAuthenticated } = useAuthStore(); - const { isFullscreen, isTelegramWebApp, requestFullscreen, isMobile } = useTelegramSDK(); + const isAuthenticated = useAuthStore((state) => state.isAuthenticated); + const { isTelegramWebApp, requestFullscreen, isMobile } = useTelegramSDK(); // Branding data const { data: branding } = useQuery({ @@ -62,13 +62,16 @@ export function useBranding() { staleTime: 60000, }); + const fullscreenRequestedRef = useRef(false); + useEffect(() => { if (!fullscreenSetting || !isTelegramWebApp) return; setCachedFullscreenEnabled(fullscreenSetting.enabled); - if (fullscreenSetting.enabled && !isFullscreen && isMobile) { + if (fullscreenSetting.enabled && isMobile && !fullscreenRequestedRef.current) { + fullscreenRequestedRef.current = true; requestFullscreen(); } - }, [fullscreenSetting, isTelegramWebApp, isFullscreen, requestFullscreen, isMobile]); + }, [fullscreenSetting, isTelegramWebApp, requestFullscreen, isMobile]); return { appName, diff --git a/src/pages/AdminBroadcasts.tsx b/src/pages/AdminBroadcasts.tsx index 131635f..cab9f08 100644 --- a/src/pages/AdminBroadcasts.tsx +++ b/src/pages/AdminBroadcasts.tsx @@ -137,7 +137,13 @@ export default function AdminBroadcasts() { const { data, isLoading, refetch } = useQuery({ queryKey: ['admin', 'broadcasts', 'list', page], queryFn: () => adminBroadcastsApi.list(limit, page * limit), - refetchInterval: 5000, // Auto refresh every 5s + refetchInterval: (query) => { + const items = query.state.data?.items; + const hasActive = items?.some((b: { status: string }) => + ['queued', 'in_progress', 'cancelling'].includes(b.status), + ); + return hasActive ? 5000 : false; + }, }); const broadcasts = data?.items || [];