Skip to content

Commit

Permalink
chore: Scope UI store to component
Browse files Browse the repository at this point in the history
  • Loading branch information
matvp91 committed Oct 17, 2024
1 parent a76e1da commit 7fe62e0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 28 deletions.
23 changes: 13 additions & 10 deletions packages/player/src/facade/facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,21 @@ export class Facade {
this,
);

this.reset_();
this.disposeAssets_();
}

private onBufferReset_() {
this.reset_();
this.disposeAssets_();

// In case anyone is listening, reset your state.
this.emitter_.emit(Events.RESET);

// Build a generic map, eg; when we started atleast 1 asset,
// it means we started the session as a whole.
this.genericState_ = {
started: false,
playRequested: false,
};

const primaryAsset = new Asset(this.hls, this.observerEmit_);
this.assets_.add(primaryAsset);
Expand Down Expand Up @@ -122,20 +132,13 @@ export class Facade {
this.interstitial = null;
}

private reset_() {
private disposeAssets_() {
this.assets_.forEach((asset) => {
asset.destroy();
});
this.assets_.clear();

this.interstitial = null;

// Build a generic map, eg; when we started atleast 1 asset,
// it means we started the session as a whole.
this.genericState_ = {
started: false,
playRequested: false,
};
}

private observerEmit_: StateObserverEmit = (hls, event, eventObj) => {
Expand Down
2 changes: 2 additions & 0 deletions packages/player/src/facade/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export type State = {
};

export enum Events {
RESET = "reset",
PLAYHEAD_CHANGE = "playheadChange",
TIME_CHANGE = "timeChange",
VOLUME_CHANGE = "volumeChange",
Expand Down Expand Up @@ -99,6 +100,7 @@ export type AutoQualityChangeEventData = {

export type FacadeListeners = {
"*": () => void;
[Events.RESET]: () => void;
[Events.PLAYHEAD_CHANGE]: (data: PlayheadChangeEventData) => void;
[Events.TIME_CHANGE]: (data: TimeChangeEventData) => void;
[Events.VOLUME_CHANGE]: (data: VolumeChangeEventData) => void;
Expand Down
50 changes: 32 additions & 18 deletions packages/player/src/react/controls/AppStoreProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createStore, useStore } from "zustand";
import { createContext, useContext, useEffect } from "react";
import { ControllerContext } from "..";
import { createContext, useContext, useEffect, useState } from "react";
import { ControllerContext, Events } from "..";
import type { ReactNode } from "react";
import type { Settings } from "./hooks/useAppSettings";

Expand All @@ -17,20 +17,7 @@ interface AppState {
setFullscreen(value: boolean): void;
}

const appStore = createStore<AppState>((set) => ({
seeking: false,
setSeeking: (seeking) => set({ seeking }),
targetTime: null,
setTargetTime: (targetTime) => set({ targetTime }),
visible: false,
setVisible: (visible) => set({ visible }),
settings: null,
setSettings: (settings) => set({ settings }),
fullscreen: false,
setFullscreen: (fullscreen) => set({ fullscreen }),
}));

type AppStore = typeof appStore;
type AppStore = ReturnType<typeof createAppStore>;

export const StoreContext = createContext<AppStore>({} as AppStore);

Expand All @@ -39,13 +26,14 @@ type StoreProviderProps = {
};

export function AppStoreProvider({ children }: StoreProviderProps) {
const [store] = useState(createAppStore);
const controller = useContext(ControllerContext);

useEffect(() => {
let prevTime = 0;

const onChange = () => {
const { targetTime, setTargetTime } = appStore.getState();
const { targetTime, setTargetTime } = store.getState();

if (targetTime === null) {
return;
Expand All @@ -63,12 +51,38 @@ export function AppStoreProvider({ children }: StoreProviderProps) {
return controller.subscribe(onChange);
}, [controller]);

useEffect(() => {
const onReset = () => {
const initialState = store.getInitialState();
store.setState(initialState, true);
};
controller.facade.on(Events.RESET, onReset);
return () => {
controller.facade.off(Events.RESET, onReset);
};
}, [controller.facade]);

return (
<StoreContext.Provider value={appStore}>{children}</StoreContext.Provider>
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
}

export function useAppStore<T>(selector: (state: AppState) => T) {
const store = useContext(StoreContext);
return useStore(store, selector);
}

function createAppStore() {
return createStore<AppState>((set) => ({
seeking: false,
setSeeking: (seeking) => set({ seeking }),
targetTime: null,
setTargetTime: (targetTime) => set({ targetTime }),
visible: false,
setVisible: (visible) => set({ visible }),
settings: null,
setSettings: (settings) => set({ settings }),
fullscreen: false,
setFullscreen: (fullscreen) => set({ fullscreen }),
}));
}

0 comments on commit 7fe62e0

Please sign in to comment.