diff --git a/packages/html/html/src/components/media-current-time-display.ts b/packages/html/html/src/components/media-current-time-display.ts
index 99269ae5..afdead26 100644
--- a/packages/html/html/src/components/media-current-time-display.ts
+++ b/packages/html/html/src/components/media-current-time-display.ts
@@ -3,7 +3,10 @@ import {
StateHook,
PropsHook,
} from '../utils/component-factory';
-import { currentTimeDisplayStateDefinition, formatDisplayTime } from '@vjs-10/media-store';
+import {
+ currentTimeDisplayStateDefinition,
+ formatDisplayTime,
+} from '@vjs-10/media-store';
import { namedNodeMapToObject } from '../utils/element-utils.js';
export function getTemplateHTML(
@@ -21,6 +24,7 @@ export class CurrentTimeDisplayBase extends HTMLElement {
mode: 'open' as ShadowRootMode,
};
static getTemplateHTML = getTemplateHTML;
+ static observedAttributes = ['show-remaining'];
_state:
| {
@@ -56,13 +60,39 @@ export class CurrentTimeDisplayBase extends HTMLElement {
return this._state?.duration;
}
+ get showRemaining() {
+ return this.hasAttribute('show-remaining');
+ }
+
+ attributeChangedCallback(
+ name: string,
+ _oldValue: string | null,
+ _newValue: string | null,
+ ) {
+ if (name === 'show-remaining' && this._state) {
+ // Re-render with current state when show-remaining attribute changes
+ this._update({}, this._state);
+ }
+ }
+
_update(_props: any, state: any) {
this._state = state;
-
- // Update the span content with formatted current time
+
+ // Update the span content with formatted time
const spanElement = this.shadowRoot?.querySelector('span') as HTMLElement;
if (spanElement) {
- spanElement.textContent = formatDisplayTime(state.currentTime);
+ if (
+ this.showRemaining &&
+ state.duration != null &&
+ state.currentTime != null
+ ) {
+ // Show remaining time: duration - currentTime
+ const remainingTime = state.duration - state.currentTime;
+ spanElement.textContent = `-${formatDisplayTime(remainingTime)}`;
+ } else {
+ // Show current time (default behavior)
+ spanElement.textContent = formatDisplayTime(state.currentTime);
+ }
}
}
}
@@ -108,7 +138,10 @@ export const CurrentTimeDisplay = toConnectedHTMLComponent(
// Register the custom element
if (!globalThis.customElements.get('media-current-time-display')) {
// @ts-ignore - Custom element constructor compatibility
- globalThis.customElements.define('media-current-time-display', CurrentTimeDisplay);
+ globalThis.customElements.define(
+ 'media-current-time-display',
+ CurrentTimeDisplay,
+ );
}
-export default CurrentTimeDisplay;
\ No newline at end of file
+export default CurrentTimeDisplay;
diff --git a/packages/html/html/src/skins/media-skin-default.ts b/packages/html/html/src/skins/media-skin-default.ts
index 829392f4..02198c7a 100644
--- a/packages/html/html/src/skins/media-skin-default.ts
+++ b/packages/html/html/src/skins/media-skin-default.ts
@@ -114,6 +114,7 @@ export function getTemplateHTML() {
+
diff --git a/packages/react/react/src/components/CurrentTimeDisplay.tsx b/packages/react/react/src/components/CurrentTimeDisplay.tsx
index 43331527..16455a38 100644
--- a/packages/react/react/src/components/CurrentTimeDisplay.tsx
+++ b/packages/react/react/src/components/CurrentTimeDisplay.tsx
@@ -5,7 +5,10 @@ import {
} from '@vjs-10/react-media-store';
import * as React from 'react';
import { toConnectedComponent } from '../utils/component-factory';
-import { currentTimeDisplayStateDefinition, formatDisplayTime } from '@vjs-10/media-store';
+import {
+ currentTimeDisplayStateDefinition,
+ formatDisplayTime,
+} from '@vjs-10/media-store';
export const useCurrentTimeDisplayState = (_props: any) => {
const mediaStore = useMediaStore();
@@ -26,7 +29,7 @@ export type useCurrentTimeDisplayState = typeof useCurrentTimeDisplayState;
export type CurrentTimeDisplayState = ReturnType;
export const useCurrentTimeDisplayProps = (
- props: React.PropsWithChildren<{ [k: string]: any }>,
+ props: React.PropsWithChildren<{ showRemaining?: boolean; [k: string]: any }>,
state: ReturnType,
) => {
const baseProps: Record = {
@@ -44,11 +47,19 @@ export const renderCurrentTimeDisplay = (
props: CurrentTimeDisplayProps,
state: CurrentTimeDisplayState,
) => {
- return (
-
- {formatDisplayTime(state.currentTime)}
-
- );
+ const { showRemaining, ...restProps } = props;
+
+ let timeToDisplay: number | undefined;
+
+ if (showRemaining && state.duration != null && state.currentTime != null) {
+ // Show remaining time: duration - currentTime
+ timeToDisplay = state.duration - state.currentTime;
+ } else {
+ // Show current time (default behavior)
+ timeToDisplay = state.currentTime;
+ }
+
+ return -{formatDisplayTime(timeToDisplay)};
};
export type renderCurrentTimeDisplay = typeof renderCurrentTimeDisplay;
@@ -59,4 +70,4 @@ export const CurrentTimeDisplay = toConnectedComponent(
renderCurrentTimeDisplay,
'CurrentTimeDisplay',
);
-export default CurrentTimeDisplay;
\ No newline at end of file
+export default CurrentTimeDisplay;
diff --git a/packages/react/react/src/skins/MediaSkinDefault.tsx b/packages/react/react/src/skins/MediaSkinDefault.tsx
index 3ccf2e01..fedc45ef 100644
--- a/packages/react/react/src/skins/MediaSkinDefault.tsx
+++ b/packages/react/react/src/skins/MediaSkinDefault.tsx
@@ -31,7 +31,11 @@ export const MediaSkinDefault: React.FC<{ children: React.ReactNode }> = ({
-
+
{/* @ts-ignore */}
@@ -48,7 +52,9 @@ export const MediaSkinDefault: React.FC<{ children: React.ReactNode }> = ({
{/* @ts-ignore */}
-
+