feat: implement app content readiness handling in page and components

- Added `appContentReady` state to manage visibility of app content once loading is complete.
- Updated `useEffect` hooks in `CurrentDutyView` and `CalendarPage` to signal when content is ready, enhancing user experience by hiding native loading indicators.
- Refactored `Home` component to conditionally render content based on `appContentReady`, ensuring a smoother transition for users.
- Enhanced app store to include `setAppContentReady` method for state management.
This commit is contained in:
2026-03-03 18:11:02 +03:00
parent cac06f22fa
commit 68a153e4a7
4 changed files with 48 additions and 22 deletions

View File

@@ -5,12 +5,13 @@
"use client";
import { useCallback } from "react";
import { useCallback, useEffect } from "react";
import { useAppStore } from "@/store/app-store";
import { useShallow } from "zustand/react/shallow";
import { useTelegramTheme } from "@/hooks/use-telegram-theme";
import { useTelegramAuth } from "@/hooks/use-telegram-auth";
import { useAppInit } from "@/hooks/use-app-init";
import { callMiniAppReadyOnce } from "@/lib/telegram-ready";
import { CurrentDutyView } from "@/components/current-duty/CurrentDutyView";
import { CalendarPage } from "@/components/CalendarPage";
@@ -22,29 +23,48 @@ export default function Home() {
useAppInit({ isAllowed, startParam });
const { currentView, setCurrentView, setSelectedDay } = useAppStore(
useShallow((s) => ({
currentView: s.currentView,
setCurrentView: s.setCurrentView,
setSelectedDay: s.setSelectedDay,
}))
);
const { currentView, setCurrentView, setSelectedDay, appContentReady } =
useAppStore(
useShallow((s) => ({
currentView: s.currentView,
setCurrentView: s.setCurrentView,
setSelectedDay: s.setSelectedDay,
appContentReady: s.appContentReady,
}))
);
// When content is ready, tell Telegram to hide native loading and show our app.
useEffect(() => {
if (appContentReady) {
callMiniAppReadyOnce();
}
}, [appContentReady]);
const handleBackFromCurrentDuty = useCallback(() => {
setCurrentView("calendar");
setSelectedDay(null);
}, [setCurrentView, setSelectedDay]);
if (currentView === "currentDuty") {
return (
const content =
currentView === "currentDuty" ? (
<div className="mx-auto flex min-h-screen w-full max-w-[var(--max-width-app)] flex-col bg-background px-3 pb-6 pt-safe">
<CurrentDutyView
onBack={handleBackFromCurrentDuty}
openedFromPin={startParam === "duty"}
/>
</div>
) : (
<CalendarPage isAllowed={isAllowed} initDataRaw={initDataRaw} />
);
}
return <CalendarPage isAllowed={isAllowed} initDataRaw={initDataRaw} />;
return (
<div
style={{
visibility: appContentReady ? "visible" : "hidden",
minHeight: "100vh",
}}
>
{content}
</div>
);
}