refactor: move time formatting logic to platform components
Move time formatting responsibility from core component state definition to platform-specific components for better separation of concerns: - Core state definition now only provides raw duration value - HTML component calls formatDuration() in _update() method - React component calls formatDuration() in render function - Maintains same functionality with cleaner architecture This approach gives platforms more control over formatting and reduces the responsibility of the core state abstraction. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
|
After Width: | Height: | Size: 277 KiB |
|
After Width: | Height: | Size: 298 KiB |
|
After Width: | Height: | Size: 277 KiB |
|
After Width: | Height: | Size: 293 KiB |
|
After Width: | Height: | Size: 277 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
@@ -6,23 +6,12 @@
|
||||
* display is a read-only component that shows the total duration of media.
|
||||
*/
|
||||
|
||||
import { formatDuration, formatAsTimePhrase, isValidDuration } from '../utils/time';
|
||||
|
||||
/**
|
||||
* State interface for duration display components
|
||||
*/
|
||||
export interface DurationDisplayState {
|
||||
/** The raw duration value in seconds */
|
||||
duration: number | undefined;
|
||||
|
||||
/** Whether the duration is valid and should be displayed */
|
||||
isValidDuration: boolean;
|
||||
|
||||
/** Formatted duration string for display (e.g., "4:32" or "--:--") */
|
||||
formattedDuration: string;
|
||||
|
||||
/** Human-readable duration phrase for accessibility (e.g., "4 minutes, 32 seconds") */
|
||||
durationPhrase: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,13 +31,9 @@ export const durationDisplayStateDefinition = {
|
||||
*/
|
||||
stateTransform: (rawState: Record<string, any>): DurationDisplayState => {
|
||||
const { duration } = rawState;
|
||||
const isValid = isValidDuration(duration);
|
||||
|
||||
return {
|
||||
duration,
|
||||
isValidDuration: isValid,
|
||||
formattedDuration: formatDuration(duration),
|
||||
durationPhrase: isValid ? formatAsTimePhrase(duration) : 'Duration unknown',
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
StateHook,
|
||||
PropsHook,
|
||||
} from '../utils/component-factory';
|
||||
import { durationDisplayStateDefinition } from '@vjs-10/media-store';
|
||||
import { durationDisplayStateDefinition, formatDuration } from '@vjs-10/media-store';
|
||||
import { namedNodeMapToObject } from '../utils/element-utils.js';
|
||||
|
||||
export function getTemplateHTML(
|
||||
@@ -25,9 +25,6 @@ export class DurationDisplayBase extends HTMLElement {
|
||||
_state:
|
||||
| {
|
||||
duration: number | undefined;
|
||||
isValidDuration: boolean;
|
||||
formattedDuration: string;
|
||||
durationPhrase: string;
|
||||
}
|
||||
| undefined;
|
||||
|
||||
@@ -54,21 +51,13 @@ export class DurationDisplayBase extends HTMLElement {
|
||||
return this._state?.duration;
|
||||
}
|
||||
|
||||
get formattedDuration() {
|
||||
return this._state?.formattedDuration || '--:--';
|
||||
}
|
||||
|
||||
get durationPhrase() {
|
||||
return this._state?.durationPhrase || 'Duration unknown';
|
||||
}
|
||||
|
||||
_update(_props: any, state: any) {
|
||||
this._state = state;
|
||||
|
||||
// Update the span content
|
||||
// Update the span content with formatted duration
|
||||
const spanElement = this.shadowRoot?.querySelector('span') as HTMLElement;
|
||||
if (spanElement) {
|
||||
spanElement.textContent = state.formattedDuration;
|
||||
spanElement.textContent = formatDuration(state.duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,9 +68,6 @@ export class DurationDisplayBase extends HTMLElement {
|
||||
*/
|
||||
export const useDurationDisplayState: StateHook<{
|
||||
duration: number | undefined;
|
||||
isValidDuration: boolean;
|
||||
formattedDuration: string;
|
||||
durationPhrase: string;
|
||||
}> = {
|
||||
keys: [...durationDisplayStateDefinition.keys],
|
||||
transform: (rawState, _mediaStore) => ({
|
||||
@@ -96,9 +82,6 @@ export const useDurationDisplayState: StateHook<{
|
||||
*/
|
||||
export const useDurationDisplayProps: PropsHook<{
|
||||
duration: number | undefined;
|
||||
isValidDuration: boolean;
|
||||
formattedDuration: string;
|
||||
durationPhrase: string;
|
||||
}> = (_state, _element) => {
|
||||
const baseProps: Record<string, any> = {};
|
||||
return baseProps;
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
} from '@vjs-10/react-media-store';
|
||||
import * as React from 'react';
|
||||
import { toConnectedComponent } from '../utils/component-factory';
|
||||
import { durationDisplayStateDefinition } from '@vjs-10/media-store';
|
||||
import { durationDisplayStateDefinition, formatDuration } from '@vjs-10/media-store';
|
||||
|
||||
export const useDurationDisplayState = (_props: any) => {
|
||||
const mediaStore = useMediaStore();
|
||||
@@ -18,9 +18,6 @@ export const useDurationDisplayState = (_props: any) => {
|
||||
// Duration display is read-only, no request methods needed
|
||||
return {
|
||||
duration: mediaState.duration,
|
||||
isValidDuration: mediaState.isValidDuration,
|
||||
formattedDuration: mediaState.formattedDuration,
|
||||
durationPhrase: mediaState.durationPhrase,
|
||||
} as const;
|
||||
};
|
||||
|
||||
@@ -48,7 +45,7 @@ export const renderDurationDisplay = (
|
||||
) => {
|
||||
return (
|
||||
<span {...props}>
|
||||
{state.formattedDuration}
|
||||
{formatDuration(state.duration)}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||