From f13b1d0e92251d13c63fd91175b68662a88379f1 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Fri, 11 Oct 2024 23:14:09 +0100 Subject: [PATCH 1/2] Make webcam loading spinners appear/disappear more reliably --- components/WebcamView.tsx | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/components/WebcamView.tsx b/components/WebcamView.tsx index 9b4ba7b0..e6f61fe9 100644 --- a/components/WebcamView.tsx +++ b/components/WebcamView.tsx @@ -1,9 +1,8 @@ "use client"; -import { useEffect, useRef } from "react"; +import { useEffect, useRef, useState } from "react"; import MuxVideo from "@mux/mux-video-react"; import { Box, LoadingOverlay } from "@mantine/core"; -import { useDisclosure } from "@mantine/hooks"; export function WebcamView(props: { webcamUrl: string; @@ -12,18 +11,30 @@ export function WebcamView(props: { }) { const ref = useRef(null); - const [videoReady, { open: setReady, close: setUnready }] = - useDisclosure(false); + const [videoReady, setVideoReady] = useState(false); useEffect(() => { - // The four (4) here is the value of readyState when a video element is ready to play - // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState - if (ref.current?.readyState === 4) { - setReady(); - } else { - setUnready(); + const el = ref.current; + if (!el) { + return; } - }, [ref.current?.readyState, setReady, setUnready]); + function isReady() { + setVideoReady(true); + } + function isNotReady() { + setVideoReady(false); + } + el.addEventListener("canplay", isReady); + for (const evt of ["stalled", "waiting", "error"]) { + el.addEventListener(evt, isNotReady); + } + return () => { + el.removeEventListener("canplay", isReady); + for (const evt of ["stalled", "waiting", "error"]) { + el.removeEventListener(evt, isNotReady); + } + }; + }, [props.webcamUrl]); return ( <> @@ -35,6 +46,7 @@ export function WebcamView(props: { /> Date: Fri, 11 Oct 2024 23:16:28 +0100 Subject: [PATCH 2/2] Explanatory comments --- components/WebcamView.tsx | 4 ++++ features/calendar/check_with_tech.ts | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/components/WebcamView.tsx b/components/WebcamView.tsx index e6f61fe9..c37361c9 100644 --- a/components/WebcamView.tsx +++ b/components/WebcamView.tsx @@ -14,6 +14,8 @@ export function WebcamView(props: { const [videoReady, setVideoReady] = useState(false); useEffect(() => { + // Copy the element ref so that we can still reference it in the + // cleanup callback. const el = ref.current; if (!el) { return; @@ -34,6 +36,8 @@ export function WebcamView(props: { el.removeEventListener(evt, isNotReady); } }; + // Since the key of the video element is also webcamUrl, this effect + // will clean up and re-run whenever the webcamUrl changes. }, [props.webcamUrl]); return ( diff --git a/features/calendar/check_with_tech.ts b/features/calendar/check_with_tech.ts index 317b3342..fae4b8d7 100644 --- a/features/calendar/check_with_tech.ts +++ b/features/calendar/check_with_tech.ts @@ -1,4 +1,3 @@ -import { userHasPermission } from "@/lib/auth/core"; import slackApiConnection from "@/lib/slack/slackApiConnection"; import { getEvent } from "./events"; import dayjs from "dayjs"; @@ -8,14 +7,10 @@ import { prisma } from "@/lib/db"; import { env } from "@/lib/env"; import { getCurrentUser, - hasPermission, mustGetCurrentUser, requirePermission, } from "@/lib/auth/server"; import { ExposedUserModel } from "../people/users"; -import * as AdamRMS from "@/lib/adamrms"; -import { getUserName } from "@/components/UserHelpers"; -import { addProjectToAdamRMS } from "./adamRMS"; import { _sendCWTFollowUpAndUpdateMessage } from "./check_with_tech_actions"; import invariant from "@/lib/invariant";