diff --git a/packages/html/html/src/components/media-mute-button.ts b/packages/html/html/src/components/media-mute-button.ts
index 35bbbb12..eee4f3a1 100644
--- a/packages/html/html/src/components/media-mute-button.ts
+++ b/packages/html/html/src/components/media-mute-button.ts
@@ -4,6 +4,7 @@ import {
PropsHook,
} from '../utils/component-factory';
import { MediaChromeButton } from './media-chrome-button';
+import { muteButtonStateDefinition } from './state-definitions/mute-button';
export class MuteButtonBase extends MediaChromeButton {
_state:
@@ -57,18 +58,10 @@ export const useMuteButtonState: StateHook<{
muted: boolean;
volumeLevel: string;
}> = {
- keys: ['muted', 'volumeLevel'],
+ keys: muteButtonStateDefinition.keys,
transform: (rawState, mediaStore) => ({
- muted: rawState.muted ?? false,
- volumeLevel: rawState.volumeLevel ?? 'off',
- requestMute() {
- const type = 'muterequest';
- mediaStore.dispatch({ type });
- },
- requestUnmute() {
- const type = 'unmuterequest';
- mediaStore.dispatch({ type });
- },
+ ...muteButtonStateDefinition.stateTransform(rawState),
+ ...muteButtonStateDefinition.createRequestMethods(mediaStore.dispatch),
}),
};
diff --git a/packages/html/html/src/components/state-definitions/mute-button.ts b/packages/html/html/src/components/state-definitions/mute-button.ts
new file mode 100644
index 00000000..be77ea62
--- /dev/null
+++ b/packages/html/html/src/components/state-definitions/mute-button.ts
@@ -0,0 +1,35 @@
+export interface MuteButtonState {
+ muted: boolean;
+ volumeLevel: string;
+}
+
+export interface MuteButtonMethods {
+ requestMute: () => void;
+ requestUnmute: () => void;
+}
+
+export interface MuteButtonStateDefinition {
+ keys: string[];
+ stateTransform: (rawState: any) => MuteButtonState;
+ createRequestMethods: (
+ dispatch: (action: { type: string }) => void,
+ ) => MuteButtonMethods;
+}
+
+/**
+ * MuteButton state definition
+ * Defines the core state logic that can be shared between implementations
+ */
+export const muteButtonStateDefinition: MuteButtonStateDefinition = {
+ keys: ['muted', 'volumeLevel'],
+
+ stateTransform: (rawState: any): MuteButtonState => ({
+ muted: rawState.muted ?? (false as boolean),
+ volumeLevel: rawState.volumeLevel ?? ('off' as string),
+ }),
+
+ createRequestMethods: (dispatch): MuteButtonMethods => ({
+ requestMute: () => dispatch({ type: 'muterequest' }),
+ requestUnmute: () => dispatch({ type: 'unmuterequest' }),
+ }),
+};
\ No newline at end of file
diff --git a/packages/html/html/src/components/state-definitions/play-button.ts b/packages/html/html/src/components/state-definitions/play-button.ts
new file mode 100644
index 00000000..4f1f7859
--- /dev/null
+++ b/packages/html/html/src/components/state-definitions/play-button.ts
@@ -0,0 +1,33 @@
+export interface PlayButtonState {
+ paused: boolean;
+}
+
+export interface PlayButtonMethods {
+ requestPlay: () => void;
+ requestPause: () => void;
+}
+
+export interface PlayButtonStateDefinition {
+ keys: string[];
+ stateTransform: (rawState: any) => PlayButtonState;
+ createRequestMethods: (
+ dispatch: (action: { type: string }) => void,
+ ) => PlayButtonMethods;
+}
+
+/**
+ * PlayButton state definition
+ * Defines the core state logic that can be shared between implementations
+ */
+export const playButtonStateDefinition: PlayButtonStateDefinition = {
+ keys: ['paused'],
+
+ stateTransform: (rawState: any): PlayButtonState => ({
+ paused: rawState.paused ?? true,
+ }),
+
+ createRequestMethods: (dispatch): PlayButtonMethods => ({
+ requestPlay: () => dispatch({ type: 'playrequest' }),
+ requestPause: () => dispatch({ type: 'pauserequest' }),
+ }),
+};
diff --git a/packages/react/react/src/components/MuteButton.tsx b/packages/react/react/src/components/MuteButton.tsx
index 0db7a677..22b50af6 100644
--- a/packages/react/react/src/components/MuteButton.tsx
+++ b/packages/react/react/src/components/MuteButton.tsx
@@ -1,53 +1,25 @@
import {
shallowEqual,
- // useMediaDispatch,
useMediaSelector,
useMediaStore,
} from '@vjs-10/react-media-store';
import * as React from 'react';
import { toConnectedComponent } from '../utils/component-factory';
-
-/**
- * MuteButton state hook - equivalent to React's useMuteButtonState
- * Handles media store state subscription and transformation
- */
-export const muteButtonStateDef = {
- keys: ['muted', 'volumeLevel'],
- stateTransform: (rawState: any) => ({
- muted: rawState.muted ?? false,
- volumeLevel: rawState.volumeLevel ?? 'off',
- }),
- /** @TODO Consider "promoting" this up to state-mediator defs + media store (CJP) */
- requestMethods: (mediaStore: ReturnType) => {
- return {
- requestMute() {
- const type = 'muterequest';
- mediaStore.dispatch({ type });
- },
- requestUnmute() {
- const type = 'unmuterequest';
- mediaStore.dispatch({ type });
- },
- };
- },
-} as const;
+import { muteButtonStateDefinition } from './state-definitions/mute-button';
export const useMuteButtonState = (_props: any) => {
const mediaStore = useMediaStore();
/** @TODO Fix type issues with hooks (CJP) */
const mediaState = useMediaSelector(
- muteButtonStateDef.stateTransform,
+ muteButtonStateDefinition.stateTransform,
shallowEqual,
);
- const [methods, setMethods] = React.useState(
- muteButtonStateDef.requestMethods(mediaStore),
+ const methods = React.useMemo(
+ () => muteButtonStateDefinition.createRequestMethods(mediaStore.dispatch),
+ [mediaStore],
);
- React.useEffect(() => {
- setMethods(muteButtonStateDef.requestMethods(mediaStore));
- }, [mediaStore]);
-
return {
volumeLevel: mediaState.volumeLevel,
muted: mediaState.muted,
diff --git a/packages/react/react/src/components/state-definitions/mute-button.ts b/packages/react/react/src/components/state-definitions/mute-button.ts
new file mode 100644
index 00000000..c2de4b95
--- /dev/null
+++ b/packages/react/react/src/components/state-definitions/mute-button.ts
@@ -0,0 +1,33 @@
+export interface MuteButtonState {
+ muted: boolean;
+ volumeLevel: string;
+}
+
+export interface MuteButtonMethods {
+ requestMute: () => void;
+ requestUnmute: () => void;
+}
+
+export interface MuteButtonStateDefinition {
+ keys: string[];
+ stateTransform: (rawState: any) => MuteButtonState;
+ createRequestMethods: (dispatch: (action: { type: string }) => void) => MuteButtonMethods;
+}
+
+/**
+ * MuteButton state definition
+ * Defines the core state logic that can be shared between implementations
+ */
+export const muteButtonStateDefinition: MuteButtonStateDefinition = {
+ keys: ['muted', 'volumeLevel'],
+
+ stateTransform: (rawState: any): MuteButtonState => ({
+ muted: rawState.muted ?? false,
+ volumeLevel: rawState.volumeLevel ?? 'off',
+ }),
+
+ createRequestMethods: (dispatch): MuteButtonMethods => ({
+ requestMute: () => dispatch({ type: 'muterequest' }),
+ requestUnmute: () => dispatch({ type: 'unmuterequest' }),
+ }),
+};
\ No newline at end of file
diff --git a/packages/react/react/src/components/state-definitions/play-button.ts b/packages/react/react/src/components/state-definitions/play-button.ts
new file mode 100644
index 00000000..4f1f7859
--- /dev/null
+++ b/packages/react/react/src/components/state-definitions/play-button.ts
@@ -0,0 +1,33 @@
+export interface PlayButtonState {
+ paused: boolean;
+}
+
+export interface PlayButtonMethods {
+ requestPlay: () => void;
+ requestPause: () => void;
+}
+
+export interface PlayButtonStateDefinition {
+ keys: string[];
+ stateTransform: (rawState: any) => PlayButtonState;
+ createRequestMethods: (
+ dispatch: (action: { type: string }) => void,
+ ) => PlayButtonMethods;
+}
+
+/**
+ * PlayButton state definition
+ * Defines the core state logic that can be shared between implementations
+ */
+export const playButtonStateDefinition: PlayButtonStateDefinition = {
+ keys: ['paused'],
+
+ stateTransform: (rawState: any): PlayButtonState => ({
+ paused: rawState.paused ?? true,
+ }),
+
+ createRequestMethods: (dispatch): PlayButtonMethods => ({
+ requestPlay: () => dispatch({ type: 'playrequest' }),
+ requestPause: () => dispatch({ type: 'pauserequest' }),
+ }),
+};