From 13f5f76611336040215dafd8513244cfaad522be Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 18 Apr 2024 15:50:35 +0530 Subject: [PATCH 01/11] Migrate consultation feed to use newer camera feed components --- src/Components/CameraFeed/AssetBedSelect.tsx | 14 ++++- .../ConsultationFeedTab.tsx | 59 +++++++++++++++++-- .../Facility/ConsultationDetails/index.tsx | 51 ---------------- 3 files changed, 64 insertions(+), 60 deletions(-) diff --git a/src/Components/CameraFeed/AssetBedSelect.tsx b/src/Components/CameraFeed/AssetBedSelect.tsx index 17701dccbde..0ebafbb2def 100644 --- a/src/Components/CameraFeed/AssetBedSelect.tsx +++ b/src/Components/CameraFeed/AssetBedSelect.tsx @@ -28,12 +28,20 @@ export default function AssetBedSelect(props: Props) { const selected = props.value; + const label = (obj: AssetBedModel) => { + return props.bed + ? obj.meta.preset_name + : `${obj.bed_object.name}: ${obj.meta.preset_name}`; + }; + + const options = data?.results.filter(({ meta }) => meta.type !== "boundary"); + return (
- {selected?.bed_object.name ?? "No Preset"} + {selected ? label(selected) : "No Preset"} @@ -46,7 +54,7 @@ export default function AssetBedSelect(props: Props) { leaveTo="opacity-0" > - {data?.results.map((obj) => ( + {options?.map((obj) => ( @@ -63,7 +71,7 @@ export default function AssetBedSelect(props: Props) { selected ? "font-bold text-white" : "font-normal" }`} > - {obj.bed_object.name}: {obj.meta.preset_name} + {label(obj)} )} diff --git a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx index f4fbc08331c..22183706808 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx @@ -1,10 +1,47 @@ -import { lazy } from "react"; -import { Feed } from "../Consultations/Feed"; +import { lazy, useState } from "react"; import { ConsultationTabProps } from "./index"; +import { AssetBedModel, AssetData } from "../../Assets/AssetTypes"; +import routes from "../../../Redux/api"; +import useQuery from "../../../Utils/request/useQuery"; +import CameraFeed from "../../CameraFeed/CameraFeed"; +import Loading from "../../Common/Loading"; +import AssetBedSelect from "../../CameraFeed/AssetBedSelect"; const PageTitle = lazy(() => import("../../Common/PageTitle")); export const ConsultationFeedTab = (props: ConsultationTabProps) => { + const bed = props.consultationData.current_bed?.bed_object; + + const [asset, setAsset] = useState(); + const [preset, setPreset] = useState(); + + const { loading } = useQuery(routes.listAssetBeds, { + query: { bed: bed?.id }, + prefetch: !!bed, + onResponse: ({ data }) => { + if (!data) { + return; + } + + const preset = data.results.find( + (obj) => + obj.asset_object.meta?.asset_type === "CAMERA" && + obj.meta.type !== "boundary", + ); + + if (preset) { + setPreset(preset); + setAsset(preset.asset_object); + } + }, + }); + + if (!bed) { + return No bed allocated; + } + + console.log("pos", preset?.meta); + return (
{ hideBack={true} focusOnLoad={true} /> - + {loading || !asset ? ( + + ) : ( + +
+ +
+
+ )}
); }; diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx index 56b8981c4c5..48151b50d11 100644 --- a/src/Components/Facility/ConsultationDetails/index.tsx +++ b/src/Components/Facility/ConsultationDetails/index.tsx @@ -207,57 +207,6 @@ export const ConsultationDetails = (props: any) => { selected === true ? "border-primary-500 text-primary-600 border-b-2" : "" }`; - // const ShowDiagnosis = ({ - // diagnoses = [], - // label = "Diagnosis", - // nshow = 2, - // }: { - // diagnoses: ICD11DiagnosisModel[] | undefined; - // label: string; - // nshow?: number; - // }) => { - // const [showMore, setShowMore] = useState(false); - - // return diagnoses.length ? ( - //
- //

{label}

- // {diagnoses.slice(0, !showMore ? nshow : undefined).map((diagnosis) => - // diagnosis.id === consultationData.icd11_principal_diagnosis ? ( - //
- //

{diagnosis.label}

- //
- // - // - // - //
- //
- // ) : ( - //

{diagnosis.label}

- // ) - // )} - // {diagnoses.length > nshow && ( - // <> - // {!showMore ? ( - // setShowMore(true)} - // className="cursor-pointer text-sm text-blue-600 hover:text-blue-300" - // > - // show more - // - // ) : ( - // setShowMore(false)} - // className="cursor-pointer text-sm text-blue-600 hover:text-blue-300" - // > - // show less - // - // )} - // - // )} - //
- // ) : null; - // }; - return (
From 03b46734ec4ecd7364bf2a148e19b602d8e29eb1 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 18 Apr 2024 15:54:14 +0530 Subject: [PATCH 02/11] remove console logs --- .../Facility/ConsultationDetails/ConsultationFeedTab.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx index 22183706808..a8a111dece2 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx @@ -40,8 +40,6 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { return No bed allocated; } - console.log("pos", preset?.meta); - return (
Date: Thu, 18 Apr 2024 16:00:33 +0530 Subject: [PATCH 03/11] adds plausible tracking --- .../ConsultationFeedTab.tsx | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx index a8a111dece2..e987842ef95 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx @@ -6,10 +6,13 @@ import useQuery from "../../../Utils/request/useQuery"; import CameraFeed from "../../CameraFeed/CameraFeed"; import Loading from "../../Common/Loading"; import AssetBedSelect from "../../CameraFeed/AssetBedSelect"; +import { triggerGoal } from "../../../Integrations/Plausible"; +import useAuthUser from "../../../Common/hooks/useAuthUser"; const PageTitle = lazy(() => import("../../Common/PageTitle")); export const ConsultationFeedTab = (props: ConsultationTabProps) => { + const authUser = useAuthUser(); const bed = props.consultationData.current_bed?.bed_object; const [asset, setAsset] = useState(); @@ -51,13 +54,39 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { {loading || !asset ? ( ) : ( - + { + triggerGoal("Camera Feed Viewed", { + consultationId: props.consultationId, + userId: authUser.id, + result: "error", + }); + }} + onStreamSuccess={() => { + triggerGoal("Camera Feed Viewed", { + consultationId: props.consultationId, + userId: authUser.id, + result: "success", + }); + }} + >
{ + triggerGoal("Camera Preset Clicked", { + presetName: preset?.meta?.preset_name, + consultationId: props.consultationId, + userId: authUser.id, + result: "success", + }); + setPreset(value); + }} />
From ab47c1c1d02ab9fc9912703d5d0898e3540c22e3 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 18 Apr 2024 16:00:46 +0530 Subject: [PATCH 04/11] remove unused code --- .../Facility/Consultations/Feed.tsx | 704 ------------------ 1 file changed, 704 deletions(-) delete mode 100644 src/Components/Facility/Consultations/Feed.tsx diff --git a/src/Components/Facility/Consultations/Feed.tsx b/src/Components/Facility/Consultations/Feed.tsx deleted file mode 100644 index bae950c6e15..00000000000 --- a/src/Components/Facility/Consultations/Feed.tsx +++ /dev/null @@ -1,704 +0,0 @@ -import * as Notification from "../../../Utils/Notifications.js"; -import routes from "../../../Redux/api"; -import request from "../../../Utils/request/request"; -import { - CAMERA_STATES, - CameraPTZ, - getCameraPTZ, -} from "../../../Common/constants"; -import { - ICameraAssetState, - StreamStatus, - useMSEMediaPlayer, -} from "../../../Common/hooks/useMSEplayer"; -import { PTZState, useFeedPTZ } from "../../../Common/hooks/useFeedPTZ"; -import { useEffect, useRef, useState } from "react"; - -import CareIcon, { IconName } from "../../../CAREUI/icons/CareIcon.js"; -import FeedButton from "./FeedButton"; -import Loading from "../../Common/Loading"; -import ReactPlayer from "react-player"; -import { classNames } from "../../../Utils/utils"; -import { useDispatch } from "react-redux"; -import { useHLSPLayer } from "../../../Common/hooks/useHLSPlayer"; -import useKeyboardShortcut from "use-keyboard-shortcut"; -import useFullscreen from "../../../Common/hooks/useFullscreen.js"; -import { triggerGoal } from "../../../Integrations/Plausible.js"; -import useAuthUser from "../../../Common/hooks/useAuthUser.js"; -import Spinner from "../../Common/Spinner.js"; -import useQuery from "../../../Utils/request/useQuery.js"; -import { ResolvedMiddleware } from "../../Assets/AssetTypes.js"; - -interface IFeedProps { - facilityId: string; - consultationId: any; -} - -const PATIENT_DEFAULT_PRESET = "Patient View".trim().toLowerCase(); - -export const Feed: React.FC = ({ consultationId }) => { - const dispatch: any = useDispatch(); - - const videoWrapper = useRef(null); - - const [cameraAsset, setCameraAsset] = useState({ - id: "", - accessKey: "", - middleware_address: "", - location_middleware: "", - }); - - const [cameraConfig, setCameraConfig] = useState({}); - const [bedPresets, setBedPresets] = useState([]); - const [bed, setBed] = useState(); - const [precision, setPrecision] = useState(1); - const [cameraState, setCameraState] = useState(null); - const [isFullscreen, setFullscreen] = useFullscreen(); - const [videoStartTime, setVideoStartTime] = useState(null); - const [statusReported, setStatusReported] = useState(false); - const [resolvedMiddleware, setResolvedMiddleware] = - useState(); - const authUser = useAuthUser(); - - useEffect(() => { - if (cameraState) { - setCameraState({ - ...cameraState, - precision: precision, - }); - } - }, [precision]); - - useEffect(() => { - const timeout = setTimeout(() => { - setCameraState({ - ...cameraConfig.position, - precision: cameraState?.precision, - }); - setCamTimeout(0); - }, 5000); - return () => clearTimeout(timeout); - }, [cameraState]); - - const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); - - const liveFeedPlayerRef = useRef(null); - - const { loading: getConsultationLoading } = useQuery(routes.getConsultation, { - pathParams: { id: consultationId }, - onResponse: ({ res, data }) => { - if (res && res.status === 200 && data) { - const consultationBedId = data.current_bed?.bed_object?.id; - if (consultationBedId) { - (async () => { - const { res: listAssetBedsRes, data: listAssetBedsData } = - await request(routes.listAssetBeds, { - query: { - bed: consultationBedId, - }, - }); - setBed(consultationBedId); - const bedAssets: any = { - ...listAssetBedsRes, - data: { - ...listAssetBedsData, - results: listAssetBedsData?.results.filter((asset) => { - return asset?.asset_object?.meta?.asset_type === "CAMERA"; - }), - }, - }; - - if (bedAssets?.data?.results?.length) { - const { camera_access_key } = - bedAssets.data.results[0].asset_object.meta; - const config = camera_access_key.split(":"); - setCameraAsset({ - id: bedAssets.data.results[0].asset_object.id, - accessKey: config[2] || "", - middleware_address: - bedAssets.data.results[0].asset_object?.meta - ?.middleware_hostname, - location_middleware: - bedAssets.data.results[0].asset_object.location_object - ?.middleware_address, - }); - setResolvedMiddleware( - bedAssets.data.results[0].asset_object.resolved_middleware, - ); - setCameraConfig(bedAssets.data.results[0].meta); - setCameraState({ - ...bedAssets.data.results[0].meta.position, - precision: 1, - }); - } - })(); - } - } - }, - }); - - // const [position, setPosition] = useState(); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [presets, setPresets] = useState([]); - const [currentPreset, setCurrentPreset] = useState(); - // const [showDefaultPresets, setShowDefaultPresets] = useState(false); - - const [loading, setLoading] = useState(CAMERA_STATES.IDLE); - const [camTimeout, setCamTimeout] = useState(0); - useEffect(() => { - const timeout = setTimeout(() => { - if (cameraState) { - cameraPTZ[5].callback(camTimeout - cameraState.zoom); - setCameraState({ - ...cameraState, - zoom: camTimeout, - }); - } - }, 1000); - return () => clearTimeout(timeout); - }, [camTimeout]); - const [streamStatus, setStreamStatus] = useState( - StreamStatus.Offline, - ); - - const url = !isIOS - ? `wss://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/mse?uuid=${cameraAsset?.accessKey}&channel=0` - : `https://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/hls/live/index.m3u8?uuid=${cameraAsset?.accessKey}&channel=0`; - - const { - startStream, - // setVideoEl, - } = isIOS - ? // eslint-disable-next-line react-hooks/rules-of-hooks - useHLSPLayer(liveFeedPlayerRef.current as ReactPlayer) - : // eslint-disable-next-line react-hooks/rules-of-hooks - useMSEMediaPlayer({ - config: { - middlewareHostname: resolvedMiddleware?.hostname ?? "", - ...cameraAsset, - }, - url, - videoEl: liveFeedPlayerRef.current as HTMLVideoElement, - }); - - const { - absoluteMove, - getCameraStatus, - getPTZPayload, - getPresets, - relativeMove, - } = useFeedPTZ({ - config: cameraAsset, - dispatch, - }); - - const calculateVideoLiveDelay = () => { - const video = liveFeedPlayerRef.current as HTMLVideoElement; - if (!video || !videoStartTime) return 0; - - const timeDifference = - (new Date().getTime() - videoStartTime.getTime()) / 1000; - - return timeDifference - video.currentTime; - }; - - const getBedPresets = async (asset: any) => { - if (asset.id && bed) { - const { data: bedAssets } = await request(routes.listAssetBeds, { - query: { asset: asset.id, bed }, - }); - setBedPresets(bedAssets?.results); - } - }; - - const startStreamFeed = () => { - startStream({ - onSuccess: () => setStreamStatus(StreamStatus.Playing), - onError: () => { - setStreamStatus(StreamStatus.Offline); - if (!statusReported) { - triggerGoal("Camera Feed Viewed", { - consultationId, - userId: authUser.id, - result: "error", - }); - setStatusReported(true); - } - }, - }); - }; - - useEffect(() => { - if (cameraAsset.id) { - setTimeout(() => { - startStreamFeed(); - }, 1000); - getPresets({ - onSuccess: (resp) => setPresets(resp), - onError: (_) => { - Notification.Error({ - msg: "Fetching presets failed", - }); - }, - }); - getBedPresets(cameraAsset); - } - }, [cameraAsset, resolvedMiddleware?.hostname]); - - useEffect(() => { - let tId: any; - if (streamStatus !== StreamStatus.Playing) { - if (streamStatus !== StreamStatus.Offline) { - setStreamStatus(StreamStatus.Loading); - } - tId = setTimeout(() => { - startStreamFeed(); - }, 5000); - } else if (!statusReported) { - triggerGoal("Camera Feed Viewed", { - consultationId, - userId: authUser.id, - result: "success", - }); - setStatusReported(true); - } - - return () => { - clearTimeout(tId); - }; - }, [startStream, streamStatus]); - - useEffect(() => { - if (!currentPreset && streamStatus === StreamStatus.Playing) { - setLoading(CAMERA_STATES.MOVING.GENERIC); - const preset = - bedPresets?.find( - (preset: any) => - String(preset?.meta?.preset_name).trim().toLowerCase() === - PATIENT_DEFAULT_PRESET, - ) || bedPresets?.[0]; - - if (preset) { - absoluteMove(preset?.meta?.position, { - onSuccess: () => { - setLoading(CAMERA_STATES.IDLE); - setCurrentPreset(preset); - }, - onError: (err: Record) => { - setLoading(CAMERA_STATES.IDLE); - const responseData = err.data.result; - if (responseData.status) { - switch (responseData.status) { - case "error": - if (responseData.error.code === "EHOSTUNREACH") { - Notification.Error({ msg: "Camera is Offline!" }); - } else if (responseData.message) { - Notification.Error({ msg: responseData.message }); - } - break; - case "fail": - responseData.errors && - responseData.errors.map((error: any) => { - Notification.Error({ msg: error.message }); - }); - break; - } - } else { - Notification.Error({ msg: "Unable to connect server!" }); - } - setCurrentPreset(preset); - }, - }); - } else { - setLoading(CAMERA_STATES.IDLE); - } - } - }, [bedPresets, streamStatus]); - - const cameraPTZActionCBs: { - [key: string]: (option: any, value?: any) => void; - } = { - precision: () => { - setPrecision((precision: number) => - precision === 16 ? 1 : precision * 2, - ); - }, - reset: () => { - setStreamStatus(StreamStatus.Loading); - setVideoStartTime(null); - startStream({ - onSuccess: () => setStreamStatus(StreamStatus.Playing), - onError: () => setStreamStatus(StreamStatus.Offline), - }); - }, - fullScreen: () => { - if (isIOS) { - const element = document.querySelector("video"); - if (!element) return; - setFullscreen(true, element as HTMLElement); - return; - } - if (!liveFeedPlayerRef.current) return; - setFullscreen( - !isFullscreen, - videoWrapper.current - ? videoWrapper.current - : (liveFeedPlayerRef.current as HTMLElement), - ); - }, - updatePreset: (option) => { - getCameraStatus({ - onSuccess: async (data) => { - if (currentPreset?.asset_object?.id && data?.position) { - setLoading(option.loadingLabel); - const { res, data: assetBedData } = await request( - routes.partialUpdateAssetBed, - { - body: { - asset: currentPreset.asset_object.id, - bed: currentPreset.bed_object.id, - meta: { - ...currentPreset.meta, - position: data?.position, - }, - }, - pathParams: { external_id: currentPreset?.id }, - }, - ); - if (res && assetBedData && res.status === 200) { - Notification.Success({ msg: "Preset Updated" }); - await getBedPresets(cameraAsset?.id); - getPresets({}); - } - setLoading(CAMERA_STATES.IDLE); - } - }, - }); - }, - other: (option, value) => { - setLoading(option.loadingLabel); - relativeMove(getPTZPayload(option.action, precision, value), { - onSuccess: () => setLoading(CAMERA_STATES.IDLE), - }); - }, - }; - - const cameraPTZ = getCameraPTZ(precision).map((option) => { - const cb = - cameraPTZActionCBs[ - cameraPTZActionCBs[option.action] ? option.action : "other" - ]; - return { ...option, callback: (value?: any) => cb(option, value) }; - }); - - // Voluntarily disabling eslint, since length of `cameraPTZ` is constant and - // hence shall not cause issues. (https://news.ycombinator.com/item?id=24363703) - for (const option of cameraPTZ) { - if (!option.shortcutKey) continue; - // eslint-disable-next-line react-hooks/rules-of-hooks - useKeyboardShortcut(option.shortcutKey, option.callback); - } - - if (getConsultationLoading) return ; - - return ( -
-
-
-

Camera Presets :

-
- {bedPresets?.map((preset: any, index: number) => ( - - ))} -
-
-
-
- {isIOS ? ( - { - setVideoStartTime(() => new Date()); - }} - width="100%" - height="100%" - onBuffer={() => { - const delay = calculateVideoLiveDelay(); - if (delay > 5) { - setStreamStatus(StreamStatus.Loading); - } - }} - onError={(e: any, _: any, hlsInstance: any) => { - if (e === "hlsError") { - const recovered = hlsInstance.recoverMediaError(); - console.log(recovered); - } - }} - onEnded={() => { - setStreamStatus(StreamStatus.Stop); - }} - /> - ) : ( -
- ); -}; - -export const FeedCameraPTZHelpButton = (props: { cameraPTZ: CameraPTZ[] }) => { - const { cameraPTZ } = props; - return ( - - ); -}; From a9c924b8972a56b47d6a4e5748458686c6288bd2 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 18 Apr 2024 16:11:35 +0530 Subject: [PATCH 05/11] Revert "remove unused code" This reverts commit ab47c1c1d02ab9fc9912703d5d0898e3540c22e3. --- .../Facility/Consultations/Feed.tsx | 704 ++++++++++++++++++ 1 file changed, 704 insertions(+) create mode 100644 src/Components/Facility/Consultations/Feed.tsx diff --git a/src/Components/Facility/Consultations/Feed.tsx b/src/Components/Facility/Consultations/Feed.tsx new file mode 100644 index 00000000000..bae950c6e15 --- /dev/null +++ b/src/Components/Facility/Consultations/Feed.tsx @@ -0,0 +1,704 @@ +import * as Notification from "../../../Utils/Notifications.js"; +import routes from "../../../Redux/api"; +import request from "../../../Utils/request/request"; +import { + CAMERA_STATES, + CameraPTZ, + getCameraPTZ, +} from "../../../Common/constants"; +import { + ICameraAssetState, + StreamStatus, + useMSEMediaPlayer, +} from "../../../Common/hooks/useMSEplayer"; +import { PTZState, useFeedPTZ } from "../../../Common/hooks/useFeedPTZ"; +import { useEffect, useRef, useState } from "react"; + +import CareIcon, { IconName } from "../../../CAREUI/icons/CareIcon.js"; +import FeedButton from "./FeedButton"; +import Loading from "../../Common/Loading"; +import ReactPlayer from "react-player"; +import { classNames } from "../../../Utils/utils"; +import { useDispatch } from "react-redux"; +import { useHLSPLayer } from "../../../Common/hooks/useHLSPlayer"; +import useKeyboardShortcut from "use-keyboard-shortcut"; +import useFullscreen from "../../../Common/hooks/useFullscreen.js"; +import { triggerGoal } from "../../../Integrations/Plausible.js"; +import useAuthUser from "../../../Common/hooks/useAuthUser.js"; +import Spinner from "../../Common/Spinner.js"; +import useQuery from "../../../Utils/request/useQuery.js"; +import { ResolvedMiddleware } from "../../Assets/AssetTypes.js"; + +interface IFeedProps { + facilityId: string; + consultationId: any; +} + +const PATIENT_DEFAULT_PRESET = "Patient View".trim().toLowerCase(); + +export const Feed: React.FC = ({ consultationId }) => { + const dispatch: any = useDispatch(); + + const videoWrapper = useRef(null); + + const [cameraAsset, setCameraAsset] = useState({ + id: "", + accessKey: "", + middleware_address: "", + location_middleware: "", + }); + + const [cameraConfig, setCameraConfig] = useState({}); + const [bedPresets, setBedPresets] = useState([]); + const [bed, setBed] = useState(); + const [precision, setPrecision] = useState(1); + const [cameraState, setCameraState] = useState(null); + const [isFullscreen, setFullscreen] = useFullscreen(); + const [videoStartTime, setVideoStartTime] = useState(null); + const [statusReported, setStatusReported] = useState(false); + const [resolvedMiddleware, setResolvedMiddleware] = + useState(); + const authUser = useAuthUser(); + + useEffect(() => { + if (cameraState) { + setCameraState({ + ...cameraState, + precision: precision, + }); + } + }, [precision]); + + useEffect(() => { + const timeout = setTimeout(() => { + setCameraState({ + ...cameraConfig.position, + precision: cameraState?.precision, + }); + setCamTimeout(0); + }, 5000); + return () => clearTimeout(timeout); + }, [cameraState]); + + const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); + + const liveFeedPlayerRef = useRef(null); + + const { loading: getConsultationLoading } = useQuery(routes.getConsultation, { + pathParams: { id: consultationId }, + onResponse: ({ res, data }) => { + if (res && res.status === 200 && data) { + const consultationBedId = data.current_bed?.bed_object?.id; + if (consultationBedId) { + (async () => { + const { res: listAssetBedsRes, data: listAssetBedsData } = + await request(routes.listAssetBeds, { + query: { + bed: consultationBedId, + }, + }); + setBed(consultationBedId); + const bedAssets: any = { + ...listAssetBedsRes, + data: { + ...listAssetBedsData, + results: listAssetBedsData?.results.filter((asset) => { + return asset?.asset_object?.meta?.asset_type === "CAMERA"; + }), + }, + }; + + if (bedAssets?.data?.results?.length) { + const { camera_access_key } = + bedAssets.data.results[0].asset_object.meta; + const config = camera_access_key.split(":"); + setCameraAsset({ + id: bedAssets.data.results[0].asset_object.id, + accessKey: config[2] || "", + middleware_address: + bedAssets.data.results[0].asset_object?.meta + ?.middleware_hostname, + location_middleware: + bedAssets.data.results[0].asset_object.location_object + ?.middleware_address, + }); + setResolvedMiddleware( + bedAssets.data.results[0].asset_object.resolved_middleware, + ); + setCameraConfig(bedAssets.data.results[0].meta); + setCameraState({ + ...bedAssets.data.results[0].meta.position, + precision: 1, + }); + } + })(); + } + } + }, + }); + + // const [position, setPosition] = useState(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [presets, setPresets] = useState([]); + const [currentPreset, setCurrentPreset] = useState(); + // const [showDefaultPresets, setShowDefaultPresets] = useState(false); + + const [loading, setLoading] = useState(CAMERA_STATES.IDLE); + const [camTimeout, setCamTimeout] = useState(0); + useEffect(() => { + const timeout = setTimeout(() => { + if (cameraState) { + cameraPTZ[5].callback(camTimeout - cameraState.zoom); + setCameraState({ + ...cameraState, + zoom: camTimeout, + }); + } + }, 1000); + return () => clearTimeout(timeout); + }, [camTimeout]); + const [streamStatus, setStreamStatus] = useState( + StreamStatus.Offline, + ); + + const url = !isIOS + ? `wss://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/mse?uuid=${cameraAsset?.accessKey}&channel=0` + : `https://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/hls/live/index.m3u8?uuid=${cameraAsset?.accessKey}&channel=0`; + + const { + startStream, + // setVideoEl, + } = isIOS + ? // eslint-disable-next-line react-hooks/rules-of-hooks + useHLSPLayer(liveFeedPlayerRef.current as ReactPlayer) + : // eslint-disable-next-line react-hooks/rules-of-hooks + useMSEMediaPlayer({ + config: { + middlewareHostname: resolvedMiddleware?.hostname ?? "", + ...cameraAsset, + }, + url, + videoEl: liveFeedPlayerRef.current as HTMLVideoElement, + }); + + const { + absoluteMove, + getCameraStatus, + getPTZPayload, + getPresets, + relativeMove, + } = useFeedPTZ({ + config: cameraAsset, + dispatch, + }); + + const calculateVideoLiveDelay = () => { + const video = liveFeedPlayerRef.current as HTMLVideoElement; + if (!video || !videoStartTime) return 0; + + const timeDifference = + (new Date().getTime() - videoStartTime.getTime()) / 1000; + + return timeDifference - video.currentTime; + }; + + const getBedPresets = async (asset: any) => { + if (asset.id && bed) { + const { data: bedAssets } = await request(routes.listAssetBeds, { + query: { asset: asset.id, bed }, + }); + setBedPresets(bedAssets?.results); + } + }; + + const startStreamFeed = () => { + startStream({ + onSuccess: () => setStreamStatus(StreamStatus.Playing), + onError: () => { + setStreamStatus(StreamStatus.Offline); + if (!statusReported) { + triggerGoal("Camera Feed Viewed", { + consultationId, + userId: authUser.id, + result: "error", + }); + setStatusReported(true); + } + }, + }); + }; + + useEffect(() => { + if (cameraAsset.id) { + setTimeout(() => { + startStreamFeed(); + }, 1000); + getPresets({ + onSuccess: (resp) => setPresets(resp), + onError: (_) => { + Notification.Error({ + msg: "Fetching presets failed", + }); + }, + }); + getBedPresets(cameraAsset); + } + }, [cameraAsset, resolvedMiddleware?.hostname]); + + useEffect(() => { + let tId: any; + if (streamStatus !== StreamStatus.Playing) { + if (streamStatus !== StreamStatus.Offline) { + setStreamStatus(StreamStatus.Loading); + } + tId = setTimeout(() => { + startStreamFeed(); + }, 5000); + } else if (!statusReported) { + triggerGoal("Camera Feed Viewed", { + consultationId, + userId: authUser.id, + result: "success", + }); + setStatusReported(true); + } + + return () => { + clearTimeout(tId); + }; + }, [startStream, streamStatus]); + + useEffect(() => { + if (!currentPreset && streamStatus === StreamStatus.Playing) { + setLoading(CAMERA_STATES.MOVING.GENERIC); + const preset = + bedPresets?.find( + (preset: any) => + String(preset?.meta?.preset_name).trim().toLowerCase() === + PATIENT_DEFAULT_PRESET, + ) || bedPresets?.[0]; + + if (preset) { + absoluteMove(preset?.meta?.position, { + onSuccess: () => { + setLoading(CAMERA_STATES.IDLE); + setCurrentPreset(preset); + }, + onError: (err: Record) => { + setLoading(CAMERA_STATES.IDLE); + const responseData = err.data.result; + if (responseData.status) { + switch (responseData.status) { + case "error": + if (responseData.error.code === "EHOSTUNREACH") { + Notification.Error({ msg: "Camera is Offline!" }); + } else if (responseData.message) { + Notification.Error({ msg: responseData.message }); + } + break; + case "fail": + responseData.errors && + responseData.errors.map((error: any) => { + Notification.Error({ msg: error.message }); + }); + break; + } + } else { + Notification.Error({ msg: "Unable to connect server!" }); + } + setCurrentPreset(preset); + }, + }); + } else { + setLoading(CAMERA_STATES.IDLE); + } + } + }, [bedPresets, streamStatus]); + + const cameraPTZActionCBs: { + [key: string]: (option: any, value?: any) => void; + } = { + precision: () => { + setPrecision((precision: number) => + precision === 16 ? 1 : precision * 2, + ); + }, + reset: () => { + setStreamStatus(StreamStatus.Loading); + setVideoStartTime(null); + startStream({ + onSuccess: () => setStreamStatus(StreamStatus.Playing), + onError: () => setStreamStatus(StreamStatus.Offline), + }); + }, + fullScreen: () => { + if (isIOS) { + const element = document.querySelector("video"); + if (!element) return; + setFullscreen(true, element as HTMLElement); + return; + } + if (!liveFeedPlayerRef.current) return; + setFullscreen( + !isFullscreen, + videoWrapper.current + ? videoWrapper.current + : (liveFeedPlayerRef.current as HTMLElement), + ); + }, + updatePreset: (option) => { + getCameraStatus({ + onSuccess: async (data) => { + if (currentPreset?.asset_object?.id && data?.position) { + setLoading(option.loadingLabel); + const { res, data: assetBedData } = await request( + routes.partialUpdateAssetBed, + { + body: { + asset: currentPreset.asset_object.id, + bed: currentPreset.bed_object.id, + meta: { + ...currentPreset.meta, + position: data?.position, + }, + }, + pathParams: { external_id: currentPreset?.id }, + }, + ); + if (res && assetBedData && res.status === 200) { + Notification.Success({ msg: "Preset Updated" }); + await getBedPresets(cameraAsset?.id); + getPresets({}); + } + setLoading(CAMERA_STATES.IDLE); + } + }, + }); + }, + other: (option, value) => { + setLoading(option.loadingLabel); + relativeMove(getPTZPayload(option.action, precision, value), { + onSuccess: () => setLoading(CAMERA_STATES.IDLE), + }); + }, + }; + + const cameraPTZ = getCameraPTZ(precision).map((option) => { + const cb = + cameraPTZActionCBs[ + cameraPTZActionCBs[option.action] ? option.action : "other" + ]; + return { ...option, callback: (value?: any) => cb(option, value) }; + }); + + // Voluntarily disabling eslint, since length of `cameraPTZ` is constant and + // hence shall not cause issues. (https://news.ycombinator.com/item?id=24363703) + for (const option of cameraPTZ) { + if (!option.shortcutKey) continue; + // eslint-disable-next-line react-hooks/rules-of-hooks + useKeyboardShortcut(option.shortcutKey, option.callback); + } + + if (getConsultationLoading) return ; + + return ( +
+
+
+

Camera Presets :

+
+ {bedPresets?.map((preset: any, index: number) => ( + + ))} +
+
+
+
+ {isIOS ? ( + { + setVideoStartTime(() => new Date()); + }} + width="100%" + height="100%" + onBuffer={() => { + const delay = calculateVideoLiveDelay(); + if (delay > 5) { + setStreamStatus(StreamStatus.Loading); + } + }} + onError={(e: any, _: any, hlsInstance: any) => { + if (e === "hlsError") { + const recovered = hlsInstance.recoverMediaError(); + console.log(recovered); + } + }} + onEnded={() => { + setStreamStatus(StreamStatus.Stop); + }} + /> + ) : ( +
+ ); +}; + +export const FeedCameraPTZHelpButton = (props: { cameraPTZ: CameraPTZ[] }) => { + const { cameraPTZ } = props; + return ( + + ); +}; From 0d9ff7241b03340c50475e0a2a51b2d8afb20261 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 25 Apr 2024 11:29:04 +0530 Subject: [PATCH 06/11] fix responsiveness and full screen issues --- src/Components/CameraFeed/CameraFeed.tsx | 2 +- .../CameraFeed/FeedNetworkSignal.tsx | 2 +- src/Components/Common/PageTitle.tsx | 2 +- .../ConsultationFeedTab.tsx | 29 ++++++++++++------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Components/CameraFeed/CameraFeed.tsx b/src/Components/CameraFeed/CameraFeed.tsx index d5ea120e126..f334f89a07f 100644 --- a/src/Components/CameraFeed/CameraFeed.tsx +++ b/src/Components/CameraFeed/CameraFeed.tsx @@ -90,7 +90,7 @@ export default function CameraFeed(props: Props) { setFullscreen(false)}>
diff --git a/src/Components/CameraFeed/FeedNetworkSignal.tsx b/src/Components/CameraFeed/FeedNetworkSignal.tsx index 55b62ba8620..502c61843e8 100644 --- a/src/Components/CameraFeed/FeedNetworkSignal.tsx +++ b/src/Components/CameraFeed/FeedNetworkSignal.tsx @@ -25,7 +25,7 @@ export default function FeedNetworkSignal(props: Props) { if (-5 > delay || delay > 5) { props.onReset(); } - }, 500); + }, 1000); return () => { clearInterval(interval); diff --git a/src/Components/Common/PageTitle.tsx b/src/Components/Common/PageTitle.tsx index 6fb38a36f08..990dc7b72cc 100644 --- a/src/Components/Common/PageTitle.tsx +++ b/src/Components/Common/PageTitle.tsx @@ -47,7 +47,7 @@ export default function PageTitle({ useEffect(() => { if (divRef.current && focusOnLoad) { - divRef.current.scrollIntoView(); + divRef.current.scrollIntoView({ behavior: "smooth" }); } }, [divRef, focusOnLoad]); diff --git a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx index e987842ef95..258fe3526ae 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx @@ -1,4 +1,4 @@ -import { lazy, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { ConsultationTabProps } from "./index"; import { AssetBedModel, AssetData } from "../../Assets/AssetTypes"; import routes from "../../../Redux/api"; @@ -8,11 +8,11 @@ import Loading from "../../Common/Loading"; import AssetBedSelect from "../../CameraFeed/AssetBedSelect"; import { triggerGoal } from "../../../Integrations/Plausible"; import useAuthUser from "../../../Common/hooks/useAuthUser"; - -const PageTitle = lazy(() => import("../../Common/PageTitle")); +import PageTitle from "../../Common/PageTitle"; export const ConsultationFeedTab = (props: ConsultationTabProps) => { const authUser = useAuthUser(); + const divRef = useRef(); const bed = props.consultationData.current_bed?.bed_object; const [asset, setAsset] = useState(); @@ -39,8 +39,18 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { }, }); - if (!bed) { - return No bed allocated; + useEffect(() => { + if (divRef.current) { + divRef.current.scrollIntoView({ behavior: "smooth" }); + } + }, [!!bed, loading, !!asset, divRef.current]); + + if (!bed || !asset) { + return No bed/asset linked allocated; + } + + if (loading) { + return ; } return ( @@ -49,14 +59,11 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { title="Camera Feed" breadcrumbs={false} hideBack={true} - focusOnLoad={true} + focusOnLoad={false} /> - {loading || !asset ? ( - - ) : ( +
{ triggerGoal("Camera Feed Viewed", { @@ -90,7 +97,7 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { />
- )} +
); }; From bf0984562f06e54ed4b7abe13ea95829856101f7 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 30 Apr 2024 11:43:54 +0530 Subject: [PATCH 07/11] Adds support for updating presets in consultation camera feed --- src/Components/CameraFeed/AssetBedSelect.tsx | 35 ++----- .../CameraFeed/CameraFeedWithBedPresets.tsx | 22 ++++- src/Components/CameraFeed/FeedControls.tsx | 10 -- .../ConsultationFeedTab.tsx | 95 +++++++++++++++---- 4 files changed, 104 insertions(+), 58 deletions(-) diff --git a/src/Components/CameraFeed/AssetBedSelect.tsx b/src/Components/CameraFeed/AssetBedSelect.tsx index 0ebafbb2def..f12745e9773 100644 --- a/src/Components/CameraFeed/AssetBedSelect.tsx +++ b/src/Components/CameraFeed/AssetBedSelect.tsx @@ -1,43 +1,24 @@ import { Fragment } from "react"; -import useSlug from "../../Common/hooks/useSlug"; -import routes from "../../Redux/api"; -import useQuery from "../../Utils/request/useQuery"; -import { AssetBedModel, AssetData } from "../Assets/AssetTypes"; -import { BedModel } from "../Facility/models"; +import { AssetBedModel } from "../Assets/AssetTypes"; import { Listbox, Transition } from "@headlessui/react"; import CareIcon from "../../CAREUI/icons/CareIcon"; interface Props { - asset?: AssetData; - bed?: BedModel; + options: AssetBedModel[]; value?: AssetBedModel; + label?: (value: AssetBedModel) => string; onChange?: (value: AssetBedModel) => void; } export default function AssetBedSelect(props: Props) { - const facility = useSlug("facility"); - - const { data, loading } = useQuery(routes.listAssetBeds, { - query: { - limit: 100, - facility, - asset: props.asset?.id, - bed: props.bed?.id, - }, - }); - const selected = props.value; - const label = (obj: AssetBedModel) => { - return props.bed - ? obj.meta.preset_name - : `${obj.bed_object.name}: ${obj.meta.preset_name}`; - }; + const options = props.options.filter(({ meta }) => meta.type !== "boundary"); - const options = data?.results.filter(({ meta }) => meta.type !== "boundary"); + const label = props.label ?? defaultLabel; return ( - +
@@ -83,3 +64,7 @@ export default function AssetBedSelect(props: Props) { ); } + +const defaultLabel = ({ bed_object, meta }: AssetBedModel) => { + return `${bed_object.name}: ${meta.preset_name}`; +}; diff --git a/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx b/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx index 386b93325b0..4c205c0e9c6 100644 --- a/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx +++ b/src/Components/CameraFeed/CameraFeedWithBedPresets.tsx @@ -2,14 +2,22 @@ import { useState } from "react"; import { AssetBedModel, AssetData } from "../Assets/AssetTypes"; import CameraFeed from "./CameraFeed"; import AssetBedSelect from "./AssetBedSelect"; +import useQuery from "../../Utils/request/useQuery"; +import routes from "../../Redux/api"; +import useSlug from "../../Common/hooks/useSlug"; interface Props { asset: AssetData; } export default function LocationFeedTile(props: Props) { + const facility = useSlug("facility"); const [preset, setPreset] = useState(); + const { data, loading } = useQuery(routes.listAssetBeds, { + query: { limit: 100, facility, asset: props.asset?.id }, + }); + return (
- + {loading ? ( + loading presets... + ) : ( + + )}
); diff --git a/src/Components/CameraFeed/FeedControls.tsx b/src/Components/CameraFeed/FeedControls.tsx index 3a5afb76209..83b73ff4ed7 100644 --- a/src/Components/CameraFeed/FeedControls.tsx +++ b/src/Components/CameraFeed/FeedControls.tsx @@ -185,16 +185,6 @@ export default function FeedControls({ shortcutsDisabled, ...props }: Props) { > - {/* TODO: implement this when this is used in where presets can be saved. */} - {/* console.error("Not implemented")} - shortcutsDisabled={shortcutsDisabled} - > - - */} { const authUser = useAuthUser(); - const divRef = useRef(); + const facility = useSlug("facility"); const bed = props.consultationData.current_bed?.bed_object; const [asset, setAsset] = useState(); const [preset, setPreset] = useState(); + const [isUpdatingPreset, setIsUpdatingPreset] = useState(false); + const divRef = useRef(); + + const operate = useOperateCamera(asset?.id ?? "", true); - const { loading } = useQuery(routes.listAssetBeds, { - query: { bed: bed?.id }, + const { data, loading, refetch } = useQuery(routes.listAssetBeds, { + query: { limit: 100, facility, bed: bed?.id, asset: asset?.id }, prefetch: !!bed, onResponse: ({ data }) => { if (!data) { @@ -39,6 +50,31 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { }, }); + const presets = data?.results; + + const handleUpdatePreset = async () => { + if (!preset) return; + + setIsUpdatingPreset(true); + + const { data } = await operate({ type: "get_status" }); + const { position } = (data as { result: { position: PTZPayload } }).result; + + const { data: updated } = await request(routes.partialUpdateAssetBed, { + pathParams: { external_id: preset.id }, + body: { + asset: preset.asset_object.id, + bed: preset.bed_object.id, + meta: { ...preset.meta, position }, + }, + }); + + await refetch(); + + setPreset(updated); + setIsUpdatingPreset(false); + }; + useEffect(() => { if (divRef.current) { divRef.current.scrollIntoView({ behavior: "smooth" }); @@ -80,21 +116,44 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { }); }} > -
- { - triggerGoal("Camera Preset Clicked", { - presetName: preset?.meta?.preset_name, - consultationId: props.consultationId, - userId: authUser.id, - result: "success", - }); - setPreset(value); - }} - /> +
+ {presets ? ( + <> + obj.meta.preset_name} + value={preset} + onChange={(value) => { + triggerGoal("Camera Preset Clicked", { + presetName: preset?.meta?.preset_name, + consultationId: props.consultationId, + userId: authUser.id, + result: "success", + }); + setPreset(value); + }} + /> + {isUpdatingPreset ? ( + + ) : ( + + + + )} + + ) : ( + loading presets... + )}
From e718b465e2bf7a51766da6874ae7aa88e02f2b95 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 30 Apr 2024 11:50:51 +0530 Subject: [PATCH 08/11] disable update preset if camera not moved --- src/Components/CameraFeed/CameraFeed.tsx | 2 ++ .../ConsultationFeedTab.tsx | 26 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Components/CameraFeed/CameraFeed.tsx b/src/Components/CameraFeed/CameraFeed.tsx index f334f89a07f..7a828548fb6 100644 --- a/src/Components/CameraFeed/CameraFeed.tsx +++ b/src/Components/CameraFeed/CameraFeed.tsx @@ -24,6 +24,7 @@ interface Props { // Controls constrolsDisabled?: boolean; shortcutsDisabled?: boolean; + onMove?: () => void; } export default function CameraFeed(props: Props) { @@ -180,6 +181,7 @@ export default function CameraFeed(props: Props) { setFullscreen={setFullscreen} onReset={resetStream} onMove={async (data) => { + props.onMove?.(); setState("moving"); const { res } = await operate({ type: "relative_move", data }); setTimeout(() => { diff --git a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx index 70329da1d49..64ba39ae5aa 100644 --- a/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx +++ b/src/Components/Facility/ConsultationDetails/ConsultationFeedTab.tsx @@ -16,6 +16,7 @@ import useOperateCamera, { PTZPayload, } from "../../CameraFeed/useOperateCamera"; import request from "../../../Utils/request/request"; +import { classNames } from "../../../Utils/utils"; export const ConsultationFeedTab = (props: ConsultationTabProps) => { const authUser = useAuthUser(); @@ -25,6 +26,7 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { const [asset, setAsset] = useState(); const [preset, setPreset] = useState(); const [isUpdatingPreset, setIsUpdatingPreset] = useState(false); + const [hasMoved, setHasMoved] = useState(false); const divRef = useRef(); const operate = useOperateCamera(asset?.id ?? "", true); @@ -72,6 +74,7 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { await refetch(); setPreset(updated); + setHasMoved(false); setIsUpdatingPreset(false); }; @@ -81,14 +84,14 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { } }, [!!bed, loading, !!asset, divRef.current]); - if (!bed || !asset) { - return No bed/asset linked allocated; - } - if (loading) { return ; } + if (!bed || !asset) { + return No bed/asset linked allocated; + } + return (
{ setHasMoved(true)} onStreamError={() => { triggerGoal("Camera Feed Viewed", { consultationId: props.consultationId, @@ -130,6 +134,7 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { userId: authUser.id, result: "success", }); + setHasMoved(false); setPreset(value); }} /> @@ -142,9 +147,18 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => { From a6ff6da7c81f685840d199199e5ab77ff312bc35 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Fri, 17 May 2024 19:24:19 +0530 Subject: [PATCH 09/11] fix loading state issue --- src/Common/hooks/useMSEplayer.ts | 1 - src/Components/CameraFeed/AssetBedSelect.tsx | 2 +- src/Components/CameraFeed/CameraFeed.tsx | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Common/hooks/useMSEplayer.ts b/src/Common/hooks/useMSEplayer.ts index 482f991bc25..39e4d356910 100644 --- a/src/Common/hooks/useMSEplayer.ts +++ b/src/Common/hooks/useMSEplayer.ts @@ -149,7 +149,6 @@ export const useMSEMediaPlayer = ({ const ws = wsRef.current; ws.binaryType = "arraybuffer"; ws.onopen = function (_event) { - console.log("Connected to ws"); onSuccess && onSuccess(undefined); }; ws.onmessage = function (event) { diff --git a/src/Components/CameraFeed/AssetBedSelect.tsx b/src/Components/CameraFeed/AssetBedSelect.tsx index f12745e9773..c8a2d5451bc 100644 --- a/src/Components/CameraFeed/AssetBedSelect.tsx +++ b/src/Components/CameraFeed/AssetBedSelect.tsx @@ -19,7 +19,7 @@ export default function AssetBedSelect(props: Props) { return ( -
+
{selected ? label(selected) : "No Preset"} diff --git a/src/Components/CameraFeed/CameraFeed.tsx b/src/Components/CameraFeed/CameraFeed.tsx index 7a828548fb6..819f7e018f9 100644 --- a/src/Components/CameraFeed/CameraFeed.tsx +++ b/src/Components/CameraFeed/CameraFeed.tsx @@ -52,7 +52,7 @@ export default function CameraFeed(props: Props) { if (props.preset) { move(props.preset); } - }, [props.preset]); + }, [JSON.stringify(props.preset)]); // Get camera presets (only if onCameraPresetsObtained is provided) useEffect(() => { @@ -77,7 +77,7 @@ export default function CameraFeed(props: Props) { }, onError: props.onStreamError, }); - }, [player.initializeStream, props.onStreamSuccess, props.onStreamError]); + }, [player.initializeStream]); // Start stream on mount useEffect(() => initializeStream(), [initializeStream]); From 76829932a72db5010d95205c233923473db52f4a Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Fri, 17 May 2024 19:25:59 +0530 Subject: [PATCH 10/11] revert unintended changes --- src/Components/CameraFeed/CameraFeed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/CameraFeed/CameraFeed.tsx b/src/Components/CameraFeed/CameraFeed.tsx index 819f7e018f9..8f7659cf730 100644 --- a/src/Components/CameraFeed/CameraFeed.tsx +++ b/src/Components/CameraFeed/CameraFeed.tsx @@ -52,7 +52,7 @@ export default function CameraFeed(props: Props) { if (props.preset) { move(props.preset); } - }, [JSON.stringify(props.preset)]); + }, [props.preset]); // Get camera presets (only if onCameraPresetsObtained is provided) useEffect(() => { From b3ecfa41e0d47650194d0371160d44dacf00afdb Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 22 May 2024 15:18:28 +0530 Subject: [PATCH 11/11] fix responsiveness of tooltip --- src/Components/CameraFeed/FeedControls.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Components/CameraFeed/FeedControls.tsx b/src/Components/CameraFeed/FeedControls.tsx index 83b73ff4ed7..46258114fc0 100644 --- a/src/Components/CameraFeed/FeedControls.tsx +++ b/src/Components/CameraFeed/FeedControls.tsx @@ -87,6 +87,7 @@ export default function FeedControls({ shortcutsDisabled, ...props }: Props) { helpText="Up" shortcut={Shortcuts.MoveUp} shortcutsDisabled={shortcutsDisabled} + tooltipClassName="-translate-y-20 md:translate-y-0" > @@ -102,6 +103,7 @@ export default function FeedControls({ shortcutsDisabled, ...props }: Props) { helpText="Left" shortcut={Shortcuts.MoveLeft} shortcutsDisabled={shortcutsDisabled} + tooltipClassName="-translate-y-20 -translate-x-1 md:translate-x-0 md:translate-y-0" > @@ -114,6 +116,7 @@ export default function FeedControls({ shortcutsDisabled, ...props }: Props) { shortcut={Shortcuts.TogglePrecision} className="font-bold" shortcutsDisabled={shortcutsDisabled} + tooltipClassName="-translate-y-20 -translate-x-20 md:translate-x-0 md:translate-y-0" > {precision}x @@ -125,6 +128,7 @@ export default function FeedControls({ shortcutsDisabled, ...props }: Props) { helpText="Right" shortcut={Shortcuts.MoveRight} shortcutsDisabled={shortcutsDisabled} + tooltipClassName="-translate-y-20 -translate-x-2 md:translate-x-0 md:translate-y-0" > @@ -142,7 +146,7 @@ export default function FeedControls({ shortcutsDisabled, ...props }: Props) { helpText="Down" shortcut={Shortcuts.MoveDown} shortcutsDisabled={shortcutsDisabled} - tooltipClassName="tooltip-top" + tooltipClassName="-translate-y-20 -translate-x-2 md:-translate-x-14" >