Skip to content

Commit

Permalink
feat(esl-media): esl-media-control mixin created to control and obs…
Browse files Browse the repository at this point in the history
…erve `esl-media` state

Closes: #2876
  • Loading branch information
fshovchko authored Feb 5, 2025
1 parent 848af39 commit 60695cc
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 14 deletions.
3 changes: 3 additions & 0 deletions site/src/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ESLVSizeCSSProxy,
ESLImageContainerMixin,
ESLMedia,
ESLMediaControlMixin,
ESLToggleable,
ESLPopup,
ESLPopupPlaceholder,
Expand Down Expand Up @@ -88,6 +89,8 @@ ESLRandomText.register('lorem-ipsum');
ESLImageContainerMixin.register();
ESLMedia.register();

ESLMediaControlMixin.register();

ESLToggleableDispatcher.init();
ESLToggleable.register();
ESLPopup.register();
Expand Down
28 changes: 14 additions & 14 deletions site/views/examples/embedded-media.njk
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ aside:
</div>

<div class="btn-group btn-group-centered">
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').play()">Play
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'play'}">Play
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').pause()">Pause
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'pause'}">Pause
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').stop()">Stop
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'stop'}">Stop
</button>
</div>
</script>
Expand All @@ -45,11 +45,11 @@ aside:
</esl-media>

<div class="btn-group btn-group-centered">
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').play()">Play
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'play'}">Play
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').pause()">Pause
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'pause'}">Pause
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').stop()">Stop
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'stop'}">Stop
</button>
</div>
</script>
Expand All @@ -72,11 +72,11 @@ aside:
</div>

<div class="btn-group btn-group-centered">
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').play()">Play
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'play'}">Play
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').pause()">Pause
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'pause'}">Pause
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').stop()">Stop
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'stop'}">Stop
</button>
</div>
</script>
Expand All @@ -102,11 +102,11 @@ aside:
</div>

<div class="btn-group btn-group-centered">
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').play()">Play
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'play'}">Play
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').pause()">Pause
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'pause'}">Pause
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').stop()">Stop
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'stop'}">Stop
</button>
</div>

Expand Down Expand Up @@ -140,9 +140,9 @@ aside:
</div>

<div class="btn-group btn-group-centered">
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').play()">Play
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'play'}">Play
</button>
<button class="btn btn-sec-blue" onclick="this.closest('uip-root').querySelector('.esl-media').stop()">Stop
<button class="btn btn-sec-blue" esl-media-contol="{target: '::closest(uip-root)::find(.esl-media)', action: 'stop'}">Stop
</button>
</div>
</script>
Expand Down
66 changes: 66 additions & 0 deletions src/modules/esl-media/control/esl-media-control-mixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {ESLMixinElement} from '../../esl-mixin-element/core';
import {ESLTraversingQuery} from '../../esl-traversing-query/core/esl-traversing-query';
import {listen, memoize} from '../../esl-utils/decorators';
import {ExportNs} from '../../esl-utils/environment/export-ns';
import {evaluate} from '../../esl-utils/misc/format';

import type {ESLMedia} from '../core/esl-media';

export interface ESLMediaControlConfig {
target?: string;
action?: 'play' | 'pause' | 'stop' | 'toggle';
activeCls?: string;
}

@ExportNs('MediaControlMixin')
export class ESLMediaControlMixin extends ESLMixinElement {
public static override is = 'esl-media-contol';

public static readonly DEFAULT_CONFIG: ESLMediaControlConfig = {
action: 'toggle'
};

@memoize()
public get config(): ESLMediaControlConfig {
const attrVal = this.$$attr(ESLMediaControlMixin.is) || '{}';
const userConfig = attrVal.trim().startsWith('{') ? evaluate(attrVal, {}) : {target: attrVal};
return {...ESLMediaControlMixin.DEFAULT_CONFIG, ...userConfig};
}

public set config(value: string | ESLMediaControlConfig) {
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
this.$$attr(ESLMediaControlMixin.is, serialized);
}

public get $target(): ESLMedia | null {
if (!this.config.target) return null;
return ESLTraversingQuery.first(this.config.target, this.$host) as ESLMedia | null;
}

protected override attributeChangedCallback(): void {
memoize.clear(this, 'config');
this.$$on(this.onStateChange);
}

@listen('click')
protected onClick(): void {
const {$target, config} = this;
if (!$target || !config.action) return;
if (config.action in $target && typeof $target[config.action] === 'function') $target[config.action]();
}

@listen({
event: 'esl:media:play esl:media:paused esl:media:ended',
target: (control: ESLMediaControlMixin) => control.$target,
condition: (control: ESLMediaControlMixin) => !!control.config.activeCls
})
protected onStateChange(e: CustomEvent): void {
this.$$cls(this.config.activeCls!, e.type === 'esl:media:play');
}
}

declare global {
export interface ESLLibrary {
MediaControlMixin: typeof ESLMediaControlMixin;
}
}
1 change: 1 addition & 0 deletions src/modules/esl-media/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export type {ESLMediaTagShape} from './core/esl-media.shape';
export * from './core/esl-media';
export * from './core/esl-media-provider';
export * from './core/esl-media-registry';
export * from './control/esl-media-control-mixin';

0 comments on commit 60695cc

Please sign in to comment.