Move automatic media actions out of carousels

This commit is contained in:
Dermot Duffy
2024-09-07 15:04:23 -07:00
parent 81177478db
commit 1a0e219c61
15 changed files with 994 additions and 777 deletions
+58 -21
View File
@@ -47,7 +47,6 @@ import { stopEventFromActivatingCardWideActions } from '../../utils/action.js';
import { aspectRatioToString, contentsChanged } from '../../utils/basic.js';
import { CarouselSelected } from '../../utils/embla/carousel-controller.js';
import { AutoLazyLoad } from '../../utils/embla/plugins/auto-lazy-load/auto-lazy-load.js';
import { AutoMediaActions } from '../../utils/embla/plugins/auto-media-actions/auto-media-actions.js';
import AutoMediaLoadedInfo from '../../utils/embla/plugins/auto-media-loaded-info/auto-media-loaded-info.js';
import AutoSize from '../../utils/embla/plugins/auto-size/auto-size.js';
import { getStateObjOrDispatchError } from '../../utils/get-state-obj.js';
@@ -62,6 +61,7 @@ import '../next-prev-control.js';
import '../ptz.js';
import { FrigateCardPTZ } from '../ptz.js';
import '../surround.js';
import { MediaActionsController } from '../../components-lib/media-actions-controller.js';
const FRIGATE_CARD_LIVE_PROVIDER = 'frigate-card-live-provider';
@@ -290,10 +290,33 @@ export class FrigateCardLiveCarousel extends LitElement {
// Index between camera name and slide number.
protected _cameraToSlide: Record<string, number> = {};
protected _refPTZControl: Ref<FrigateCardPTZ> = createRef();
protected _refCarousel: Ref<HTMLElement> = createRef();
protected _mediaActionsController = new MediaActionsController();
@state()
protected _mediaHasLoaded = false;
public connectedCallback(): void {
super.connectedCallback();
// Request update in order to reinitialize the media action controller.
this.requestUpdate();
}
public disconnectedCallback(): void {
this._mediaActionsController.destroy();
super.disconnectedCallback();
}
updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (!this._mediaActionsController.hasRoot() && this._refCarousel.value) {
this._mediaActionsController.initialize(this._refCarousel.value);
}
}
protected _getTransitionEffect(): TransitionEffect {
return (
this.overriddenLiveConfig?.transition_effect ??
@@ -312,19 +335,12 @@ export class FrigateCardLiveCarousel extends LitElement {
return Math.max(0, Array.from(cameraIDs).indexOf(view.camera));
}
protected _getPlugins(): EmblaCarouselPlugins {
return [
AutoLazyLoad({
...(this.overriddenLiveConfig?.lazy_load && {
lazyLoadCallback: (index, slide) =>
this._lazyloadOrUnloadSlide('load', index, slide),
}),
lazyUnloadConditions: this.overriddenLiveConfig?.lazy_unload,
lazyUnloadCallback: (index, slide) =>
this._lazyloadOrUnloadSlide('unload', index, slide),
}),
AutoMediaLoadedInfo(),
AutoMediaActions({
protected willUpdate(changedProps: PropertyValues): void {
if (
changedProps.has('microphoneManager') ||
changedProps.has('overriddenLiveConfig')
) {
this._mediaActionsController.setOptions({
playerSelector: FRIGATE_CARD_LIVE_PROVIDER,
...(this.overriddenLiveConfig?.auto_play && {
autoPlayConditions: this.overriddenLiveConfig.auto_play,
@@ -344,7 +360,33 @@ export class FrigateCardLiveCarousel extends LitElement {
microphoneMuteSeconds:
this.overriddenLiveConfig.microphone.mute_after_microphone_mute_seconds,
}),
});
}
if (changedProps.has('viewManagerEpoch')) {
if (
this.viewFilterCameraID &&
this.viewManagerEpoch?.manager.getView()?.camera !== this.viewFilterCameraID
) {
this._mediaActionsController.unselectAll();
} else {
this._mediaActionsController.select(this._getSelectedCameraIndex());
}
}
}
protected _getPlugins(): EmblaCarouselPlugins {
return [
AutoLazyLoad({
...(this.overriddenLiveConfig?.lazy_load && {
lazyLoadCallback: (index, slide) =>
this._lazyloadOrUnloadSlide('load', index, slide),
}),
lazyUnloadConditions: this.overriddenLiveConfig?.lazy_unload,
lazyUnloadCallback: (index, slide) =>
this._lazyloadOrUnloadSlide('unload', index, slide),
}),
AutoMediaLoadedInfo(),
AutoSize(),
];
}
@@ -541,15 +583,10 @@ export class FrigateCardLiveCarousel extends LitElement {
// Notes on the below:
// - guard() is used to avoid reseting the carousel unless the
// options/plugins actually change.
// - the 'carousel:settle' event is listened for (instead of
// 'carousel:select') to only trigger the view change (which subsequently
// fetches thumbnails) after the carousel has stopped moving. This gives a
// much smoother carousel experience since network fetches are not at the
// same time as carousel movement (at a cost of fetching thumbnails a
// little later).
return html`
<frigate-card-carousel
${ref(this._refCarousel)}
.loop=${hasMultipleCameras}
.dragEnabled=${hasMultipleCameras && this.overriddenLiveConfig?.draggable}
.plugins=${guard(
@@ -748,7 +785,7 @@ export class FrigateCardLiveProvider
);
}
disconnectedCallback(): void {
public disconnectedCallback(): void {
this._isVideoMediaLoaded = false;
}
+44 -20
View File
@@ -13,6 +13,7 @@ import { createRef, Ref, ref } from 'lit/directives/ref.js';
import { CameraManager } from '../camera-manager/manager.js';
import { RemoveContextPropertyViewModifier } from '../card-controller/view/modifiers/remove-context-property.js';
import { ViewManagerEpoch } from '../card-controller/view/types.js';
import { MediaActionsController } from '../components-lib/media-actions-controller.js';
import { MediaGridSelected } from '../components-lib/media-grid-controller.js';
import { ZoomSettingsObserved } from '../components-lib/zoom/types.js';
import { handleZoomSettingsObservedEvent } from '../components-lib/zoom/zoom-view-context.js';
@@ -47,7 +48,6 @@ import {
} from '../utils/basic.js';
import { CarouselSelected } from '../utils/embla/carousel-controller.js';
import { AutoLazyLoad } from '../utils/embla/plugins/auto-lazy-load/auto-lazy-load.js';
import { AutoMediaActions } from '../utils/embla/plugins/auto-media-actions/auto-media-actions.js';
import AutoMediaLoadedInfo from '../utils/embla/plugins/auto-media-loaded-info/auto-media-loaded-info.js';
import AutoSize from '../utils/embla/plugins/auto-size/auto-size.js';
import { canonicalizeHAURL } from '../utils/ha/index.js';
@@ -189,12 +189,10 @@ export class FrigateCardViewerCarousel extends LitElement {
protected _selected = 0;
protected _media: ViewMedia[] | null = null;
protected _mediaActionsController = new MediaActionsController();
protected _player: FrigateCardMediaPlayer | null = null;
protected _refCarousel: Ref<HTMLElement> = createRef();
/**
* The updated lifecycle callback for this element.
* @param changedProperties The properties that were changed in this render.
*/
updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
@@ -209,6 +207,22 @@ export class FrigateCardViewerCarousel extends LitElement {
this._seekHandler();
}
}
if (!this._mediaActionsController.hasRoot() && this._refCarousel.value) {
this._mediaActionsController.initialize(this._refCarousel.value);
}
}
public connectedCallback(): void {
super.connectedCallback();
// Request update in order to reinitialize the media action controller.
this.requestUpdate();
}
public disconnectedCallback(): void {
this._mediaActionsController.destroy();
super.disconnectedCallback();
}
/**
@@ -234,21 +248,6 @@ export class FrigateCardViewerCarousel extends LitElement {
}),
}),
AutoMediaLoadedInfo(),
AutoMediaActions({
playerSelector: FRIGATE_CARD_VIEWER_PROVIDER,
...(this.viewerConfig?.auto_play && {
autoPlayConditions: this.viewerConfig.auto_play,
}),
...(this.viewerConfig?.auto_pause && {
autoPauseConditions: this.viewerConfig.auto_pause,
}),
...(this.viewerConfig?.auto_mute && {
autoMuteConditions: this.viewerConfig.auto_mute,
}),
...(this.viewerConfig?.auto_unmute && {
autoUnmuteConditions: this.viewerConfig.auto_unmute,
}),
}),
AutoSize(),
];
}
@@ -356,6 +355,24 @@ export class FrigateCardViewerCarousel extends LitElement {
}
protected willUpdate(changedProps: PropertyValues): void {
if (changedProps.has('viewerConfig')) {
this._mediaActionsController.setOptions({
playerSelector: FRIGATE_CARD_VIEWER_PROVIDER,
...(this.viewerConfig?.auto_play && {
autoPlayConditions: this.viewerConfig.auto_play,
}),
...(this.viewerConfig?.auto_pause && {
autoPauseConditions: this.viewerConfig.auto_pause,
}),
...(this.viewerConfig?.auto_mute && {
autoMuteConditions: this.viewerConfig.auto_mute,
}),
...(this.viewerConfig?.auto_unmute && {
autoUnmuteConditions: this.viewerConfig.auto_unmute,
}),
});
}
if (changedProps.has('viewManagerEpoch')) {
const view = this.viewManagerEpoch?.manager.getView();
const newMedia = view?.queryResults?.getResults(this.viewFilterCameraID) ?? null;
@@ -368,6 +385,12 @@ export class FrigateCardViewerCarousel extends LitElement {
this._media = newMedia;
this._selected = newSelected;
}
if (!newMedia) {
this._mediaActionsController.unselectAll();
} else {
this._mediaActionsController.select(newSelected);
}
}
}
@@ -405,6 +428,7 @@ export class FrigateCardViewerCarousel extends LitElement {
return html`
<frigate-card-carousel
${ref(this._refCarousel)}
.dragEnabled=${this.viewerConfig?.draggable ?? true}
.plugins=${guard([this.viewerConfig, this._media], this._getPlugins.bind(this))}
.selected=${this._selected}