@@ -15,6 +15,7 @@ import { clearLastSession, loadLastSession, saveLastSession } from "@/lib/lastSe
1515import { mediaFromLocalCache } from "@/lib/playFromCache" ;
1616import { playerPathForMedia , softReplaceUrl } from "@/lib/playerNavigation" ;
1717import { appTheme } from "@/lib/theme" ;
18+ import { clearMediaCache } from "@/utils/cache" ;
1819
1920const HISTORY_STORAGE_KEY = "moonlit-history" ;
2021
@@ -42,6 +43,8 @@ export interface OpenPlayerOptions {
4243 autoPlay ?: boolean ;
4344 /** Resume playback head (seconds). Used by session restore. */
4445 resumePosition ?: number ;
46+ /** When false, do not resume history writes (session restore). Default true. */
47+ recordHistory ?: boolean ;
4548}
4649
4750interface AppContextValue {
@@ -64,7 +67,8 @@ interface AppContextValue {
6467 // History state (persisted to localStorage)
6568 history : HistoryItem [ ] ;
6669 setHistory : React . Dispatch < React . SetStateAction < HistoryItem [ ] > > ;
67- clearHistory : ( ) => void ;
70+ clearHistory : ( ) => Promise < void > ;
71+ isHistoryWriteAllowed : ( ) => boolean ;
6872
6973 // Theme state
7074 theme : MantineThemeOverride ;
@@ -88,6 +92,7 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
8892 const mediaRef = useRef ( media ) ;
8993 const playerUrlRef = useRef ( playerUrl ) ;
9094 const restoredRef = useRef ( false ) ;
95+ const skipHistoryWritesRef = useRef ( false ) ;
9196
9297 useEffect ( ( ) => {
9398 mediaRef . current = media ;
@@ -136,15 +141,28 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
136141 [ ] ,
137142 ) ;
138143
139- const clearHistory = useCallback ( ( ) => {
144+ const clearHistory = useCallback ( async ( ) => {
145+ skipHistoryWritesRef . current = true ;
140146 setHistoryState ( [ ] ) ;
147+ try {
148+ localStorage . removeItem ( HISTORY_STORAGE_KEY ) ;
149+ } catch ( e ) {
150+ console . error ( "Failed to clear history:" , e ) ;
151+ }
152+ clearLastSession ( ) ;
153+ await clearMediaCache ( ) ;
141154 } , [ ] ) ;
142155
156+ const isHistoryWriteAllowed = useCallback ( ( ) => ! skipHistoryWritesRef . current , [ ] ) ;
157+
143158 const setMedia = useCallback ( ( next : Media | null ) => {
144159 setMediaState ( next ) ;
145160 } , [ ] ) ;
146161
147162 const openPlayer = useCallback ( ( options : OpenPlayerOptions = { } ) => {
163+ if ( options . recordHistory !== false ) {
164+ skipHistoryWritesRef . current = false ;
165+ }
148166 const expand = options . expand !== false ;
149167 setPlayerAutoPlay ( options . autoPlay !== false ) ;
150168 setPlayerResumeAt (
@@ -244,6 +262,7 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
244262 autoPlay : false ,
245263 syncUrl : true ,
246264 resumePosition : session . positionSeconds ?? 0 ,
265+ recordHistory : false ,
247266 } ) ;
248267 return ;
249268 }
@@ -254,6 +273,7 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
254273 autoPlay : false ,
255274 syncUrl : true ,
256275 resumePosition : session . positionSeconds ?? 0 ,
276+ recordHistory : false ,
257277 } ) ;
258278 } ) ( ) ;
259279 } , 0 ) ;
@@ -263,6 +283,7 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
263283 // Persist last session while a remote track is active
264284 useEffect ( ( ) => {
265285 if ( ! isHydrated ) return ;
286+ if ( skipHistoryWritesRef . current ) return ;
266287 if ( playerMode === "hidden" ) return ;
267288 const sourceUrl = playerUrl || media ?. sourceUrl ;
268289 if ( ! sourceUrl ) return ;
@@ -296,6 +317,7 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
296317 history,
297318 setHistory,
298319 clearHistory,
320+ isHistoryWriteAllowed,
299321 theme,
300322 setTheme,
301323 } }
0 commit comments