- Updated CSS to utilize viewport variables for safe area insets and stable height, improving layout consistency across devices. - Introduced haptic feedback triggers in various components to enhance user interaction, mimicking native Telegram behavior. - Added functionality to detect Android performance class, minimizing animations on low-performance devices for better user experience. - Refactored components to incorporate new CSS classes for content safety and improved responsiveness.
74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
/**
|
|
* Main Mini App page: current duty deep link or calendar view.
|
|
* Delegates to CurrentDutyView or CalendarPage; runs theme and app init.
|
|
*/
|
|
|
|
"use client";
|
|
|
|
import { useCallback, useEffect } from "react";
|
|
import { useAppStore, type AppState } 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 { AccessDeniedScreen } from "@/components/states/AccessDeniedScreen";
|
|
import { CurrentDutyView } from "@/components/current-duty/CurrentDutyView";
|
|
import { CalendarPage } from "@/components/CalendarPage";
|
|
|
|
export default function Home() {
|
|
useTelegramTheme();
|
|
|
|
const { initDataRaw, startParam, isLocalhost } = useTelegramAuth();
|
|
const isAllowed = isLocalhost || !!initDataRaw;
|
|
|
|
useAppInit({ isAllowed, startParam });
|
|
|
|
const { accessDenied, currentView, setCurrentView, setSelectedDay, appContentReady } =
|
|
useAppStore(
|
|
useShallow((s: AppState) => ({
|
|
accessDenied: s.accessDenied,
|
|
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]);
|
|
|
|
const content = accessDenied ? (
|
|
<AccessDeniedScreen primaryAction="reload" />
|
|
) : currentView === "currentDuty" ? (
|
|
<div className="content-safe mx-auto flex min-h-screen w-full max-w-[var(--max-width-app)] flex-col bg-background px-3 pb-6">
|
|
<CurrentDutyView
|
|
onBack={handleBackFromCurrentDuty}
|
|
openedFromPin={startParam === "duty"}
|
|
/>
|
|
</div>
|
|
) : (
|
|
<CalendarPage isAllowed={isAllowed} initDataRaw={initDataRaw} />
|
|
);
|
|
|
|
return (
|
|
<div
|
|
className="min-h-[var(--tg-viewport-stable-height,100vh)]"
|
|
style={{
|
|
visibility: appContentReady ? "visible" : "hidden",
|
|
}}
|
|
>
|
|
{content}
|
|
</div>
|
|
);
|
|
}
|