Merge pull request #1506 from dermotduffy/autoplay-intersection-issue

Fix issue that causes media to not correctly unmute
This commit is contained in:
Dermot Duffy
2024-08-26 16:41:50 -07:00
committed by GitHub
3 changed files with 10 additions and 6 deletions
@@ -50,6 +50,9 @@ export class LiveController implements ReactiveController {
constructor(host: LiveControllerHost) { constructor(host: LiveControllerHost) {
this._host = host; this._host = host;
host.addController(this);
this._intersectionObserver = new IntersectionObserver( this._intersectionObserver = new IntersectionObserver(
this._intersectionHandler.bind(this), this._intersectionHandler.bind(this),
); );
@@ -50,7 +50,7 @@ export function AutoMediaActions(
let options: OptionsType; let options: OptionsType;
let emblaApi: EmblaCarouselType; let emblaApi: EmblaCarouselType;
let slides: HTMLElement[]; let slides: HTMLElement[];
let containerIntersecting: boolean | null = null; let viewportIntersecting: boolean | null = null;
const microphoneMuteTimer = new Timer(); const microphoneMuteTimer = new Timer();
const intersectionObserver: IntersectionObserver = new IntersectionObserver( const intersectionObserver: IntersectionObserver = new IntersectionObserver(
@@ -92,7 +92,7 @@ export function AutoMediaActions(
emblaApi.on('destroy', mute); emblaApi.on('destroy', mute);
document.addEventListener('visibilitychange', visibilityHandler); document.addEventListener('visibilitychange', visibilityHandler);
intersectionObserver.observe(emblaApi.containerNode()); intersectionObserver.observe(emblaApi.rootNode());
if ( if (
options.autoUnmuteConditions?.includes('microphone') || options.autoUnmuteConditions?.includes('microphone') ||
@@ -184,14 +184,14 @@ export function AutoMediaActions(
} }
function intersectionHandler(entries: IntersectionObserverEntry[]): void { function intersectionHandler(entries: IntersectionObserverEntry[]): void {
const wasIntersecting = containerIntersecting; const wasIntersecting = viewportIntersecting;
containerIntersecting = entries.some((entry) => entry.isIntersecting); viewportIntersecting = entries.some((entry) => entry.isIntersecting);
if (wasIntersecting !== null && wasIntersecting !== containerIntersecting) { if (wasIntersecting !== null && wasIntersecting !== viewportIntersecting) {
// If the live view is preloaded (i.e. in the background) we may need to // If the live view is preloaded (i.e. in the background) we may need to
// take media actions, e.g. muting a live stream that is now running in // take media actions, e.g. muting a live stream that is now running in
// the background, so we act even if the new state is hidden. // the background, so we act even if the new state is hidden.
actOnVisibilityChange(containerIntersecting); actOnVisibilityChange(viewportIntersecting);
} }
} }
@@ -29,6 +29,7 @@ describe('LiveController', () => {
parent.addEventListener('frigate-card:message', eventListener); parent.addEventListener('frigate-card:message', eventListener);
const controller = new LiveController(host); const controller = new LiveController(host);
expect(host.addController).toBeCalled();
controller.hostConnected(); controller.hostConnected();