All files / src App.tsx

0% Statements 0/52
0% Branches 0/1
0% Functions 0/1
0% Lines 0/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71                                                                                                                                             
import { Routes, Route } from "react-router-dom";
import { AppLayout } from "./components/AppLayout";
import { PlayerView } from "./components/player/VideoPlayer";
import { ChannelList } from "./components/channels/ChannelList";
import { PlaylistManager } from "./components/playlist/PlaylistManager";
import { Settings } from "./components/settings/Settings";
import { UpdateBanner } from "./components/UpdateBanner";
import { SplashScreen } from "./components/SplashScreen";
import { DonationPopup } from "./components/DonationPopup";
import { ChannelsContext, useChannels, useChannelsProvider } from "./hooks/useChannels";
import { useUpdateChecker } from "./hooks/useUpdateChecker";
import { useSplashScreen } from "./hooks/useSplashScreen";
import { useDonationPrompt } from "./hooks/useDonationPrompt";
import { FullscreenProvider } from "./lib/fullscreen-context";
 
export default function App() {
	const channelsValue = useChannelsProvider();
	const updateState = useUpdateChecker();
 
	return (
		<ChannelsContext.Provider value={channelsValue}>
			<FullscreenProvider>
				<AppRoutes updateState={updateState} />
			</FullscreenProvider>
		</ChannelsContext.Provider>
	);
}
 
// Inner component so useSplashScreen can access ChannelsContext via useChannels.
interface AppRoutesProps {
	updateState: ReturnType<typeof useUpdateChecker>;
}
 
const AppRoutes = ({ updateState }: AppRoutesProps) => {
	const { refreshProviders, refreshChannels } = useChannels();
	const splash = useSplashScreen({
		updateState,
		// After splash finishes any playlist/EPG refreshes, sync ChannelsContext so
		// polling in useChannels reads fresh lastUpdated timestamps (avoids re-triggering
		// the same refresh 60s later due to stale state).
		onComplete: (didRefreshProviders) => {
			if (didRefreshProviders) {
				refreshProviders().catch(() => {});
				refreshChannels().catch(() => {});
			}
		},
	});
 
	const donation = useDonationPrompt({ enabled: splash.dismissed });
 
	return (
		<>
			{!splash.dismissed && <SplashScreen splash={splash} updateState={updateState} />}
 
			<Routes>
				<Route element={<AppLayout />}>
					<Route path="/" element={<ChannelList />} />
					<Route path="/player" element={<PlayerView />} />
					<Route path="/playlists" element={<PlaylistManager />} />
					<Route path="/settings" element={<Settings updateState={updateState} />} />
				</Route>
			</Routes>
 
			<UpdateBanner state={updateState} hidden={!splash.dismissed} />
			{donation.shouldShow && !updateState.update && (
				<DonationPopup onDismiss={donation.dismiss} />
			)}
		</>
	);
};