(null);
const [search, setSearch] = useState('');
@@ -125,6 +130,7 @@ export function SessionsTab({ initialSessionId, onClearInitialSession }: Session
onToggle={() => setExpandedId(expandedId === s.sessionId ? null : s.sessionId)}
onDelete={() => void handleDeleteSession(s)}
deleteDisabled={deletingSessionId === s.sessionId}
+ onNavigateToMediaDetail={onNavigateToMediaDetail}
/>
{expandedId === s.sessionId && (
diff --git a/stats/src/lib/stats-navigation.ts b/stats/src/lib/stats-navigation.ts
index 360271b..bfba6e4 100644
--- a/stats/src/lib/stats-navigation.ts
+++ b/stats/src/lib/stats-navigation.ts
@@ -1,7 +1,10 @@
import type { SessionSummary } from '../types/stats';
import type { TabId } from '../components/layout/TabBar';
-export type MediaDetailOrigin = { type: 'anime'; animeId: number } | { type: 'overview' };
+export type MediaDetailOrigin =
+ | { type: 'anime'; animeId: number }
+ | { type: 'overview' }
+ | { type: 'sessions' };
export interface MediaDetailState {
videoId: number;
@@ -92,6 +95,24 @@ export function openOverviewMediaDetail(
};
}
+export function openSessionsMediaDetail(
+ state: StatsViewState,
+ videoId: number,
+): StatsViewState {
+ return {
+ activeTab: 'sessions',
+ selectedAnimeId: null,
+ focusedSessionId: null,
+ mediaDetail: {
+ videoId,
+ initialSessionId: null,
+ origin: {
+ type: 'sessions',
+ },
+ },
+ };
+}
+
export function closeMediaDetail(state: StatsViewState): StatsViewState {
if (!state.mediaDetail) {
return state;
@@ -106,6 +127,15 @@ export function closeMediaDetail(state: StatsViewState): StatsViewState {
};
}
+ if (state.mediaDetail.origin.type === 'sessions') {
+ return {
+ activeTab: 'sessions',
+ selectedAnimeId: null,
+ focusedSessionId: null,
+ mediaDetail: null,
+ };
+ }
+
return {
activeTab: 'anime',
selectedAnimeId: state.mediaDetail.origin.animeId,