Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Develop to Staging v24.23.1 #7966

Merged
merged 2 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/CAREUI/misc/Fullscreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@ interface Props {
fullscreenClassName?: string;
children: React.ReactNode;
fullscreen: boolean;
onExit: () => void;
onExit: (reason?: "DEVICE_UNSUPPORTED") => void;
}

export default function Fullscreen(props: Props) {
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (!ref.current) {
return;
}

if (props.fullscreen) {
ref.current?.requestFullscreen();
if (ref.current.requestFullscreen) {
ref.current.requestFullscreen();
} else {
props.onExit("DEVICE_UNSUPPORTED");
}
} else {
document.exitFullscreen();
document.exitFullscreen?.();
}
}, [props.fullscreen]);

Expand All @@ -27,6 +35,7 @@ export default function Fullscreen(props: Props) {
};

document.addEventListener("fullscreenchange", listener);

return () => {
document.removeEventListener("fullscreenchange", listener);
};
Expand Down
19 changes: 15 additions & 4 deletions src/Components/CameraFeed/AssetBedSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,35 @@ export default function CameraPresetSelect(props: Props) {
{props.options.length > 5 && (
<CameraPresetDropdown
{...props}
placeholder="More preset"
options={props.options.slice(4)}
value={props.options.slice(4).find((o) => o.id === props.value?.id)}
/>
)}
</div>
<div className="w-full lg:hidden">
{/* Mobile View */}
<CameraPresetDropdown {...props} />
<CameraPresetDropdown {...props} placeholder="Select preset" />
</div>
</>
);
}

export const CameraPresetDropdown = (props: Props) => {
export const CameraPresetDropdown = (
props: Props & { placeholder: string },
) => {
const selected = props.value;

const options = props.options.filter(({ meta }) => meta.type !== "boundary");

const label = props.label ?? defaultLabel;

return (
<Listbox value={selected} onChange={props.onChange}>
<Listbox
value={selected}
onChange={props.onChange}
disabled={options.length === 0}
>
<div className="relative flex-1">
<Listbox.Button
className={classNames(
Expand All @@ -67,7 +74,11 @@ export const CameraPresetDropdown = (props: Props) => {
)}
>
<span className="block truncate">
{selected ? label(selected) : "Select preset"}
{options.length === 0
? "No presets"
: selected
? label(selected)
: props.placeholder}
</span>
<span className="pointer-events-none absolute inset-y-0 right-0 mr-1 mt-1 flex items-center">
<CareIcon icon="l-angle-down" className="text-xl text-zinc-400" />
Expand Down
41 changes: 30 additions & 11 deletions src/Components/CameraFeed/CameraFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import useOperateCamera, { PTZPayload } from "./useOperateCamera";
import usePlayer from "./usePlayer";
import { getStreamUrl } from "./utils";
import ReactPlayer from "react-player";
import { classNames, isIOS } from "../../Utils/utils";
import { classNames, isAppleDevice, isIOS } from "../../Utils/utils";
import FeedAlert, { FeedAlertState } from "./FeedAlert";
import FeedNetworkSignal from "./FeedNetworkSignal";
import NoFeedAvailable from "./NoFeedAvailable";
import FeedControls from "./FeedControls";
import Fullscreen from "../../CAREUI/misc/Fullscreen";
import FeedWatermark from "./FeedWatermark";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { Error } from "../../Utils/Notifications";

interface Props {
children?: React.ReactNode;
Expand All @@ -27,6 +28,7 @@ interface Props {
constrolsDisabled?: boolean;
shortcutsDisabled?: boolean;
onMove?: () => void;
onReset?: () => void;
}

export default function CameraFeed(props: Props) {
Expand Down Expand Up @@ -86,14 +88,29 @@ export default function CameraFeed(props: Props) {

const resetStream = () => {
setState("loading");
props.onReset?.();
initializeStream();
};
return (
<Fullscreen fullscreen={isFullscreen} onExit={() => setFullscreen(false)}>
<Fullscreen
fullscreen={isFullscreen}
onExit={(reason) => {
setFullscreen(false);

if (reason === "DEVICE_UNSUPPORTED") {
// iOS webkit allows only video/iframe elements to call full-screen
// APIs. But we need to show controls too, not just the video element.
Error({
msg: "This device does not support viewing this content in full-screen.",
});
}
}}
>
<div
className={classNames(
"flex max-h-screen flex-col overflow-clip rounded-xl bg-black",
"flex flex-col overflow-clip rounded-xl bg-black md:max-h-screen",
props.className,
isAppleDevice && isFullscreen && "px-20",
)}
>
<div className="flex items-center justify-between bg-zinc-900 px-4 py-1.5 md:py-2">
Expand All @@ -106,14 +123,16 @@ export default function CameraFeed(props: Props) {
/>
{props.asset.name}
</span>
<div className={state === "loading" ? "animate-pulse" : ""}>
<FeedNetworkSignal
playerRef={playerRef as any}
playedOn={player.playedOn}
status={player.status}
onReset={resetStream}
/>
</div>
{!isIOS && (
<div className={state === "loading" ? "animate-pulse" : ""}>
<FeedNetworkSignal
playerRef={playerRef as any}
playedOn={player.playedOn}
status={player.status}
onReset={resetStream}
/>
</div>
)}
</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions src/Components/CameraFeed/CameraFeedWithBedPresets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default function LocationFeedTile(props: Props) {
options={data?.results ?? []}
value={preset}
onChange={setPreset}
placeholder="Select preset"
/>
)}
</div>
Expand Down
10 changes: 5 additions & 5 deletions src/Components/CameraFeed/FeedAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ interface Props {
state?: FeedAlertState;
}

const ALERT_ICON_MAP: Record<FeedAlertState, IconName> = {
const ALERT_ICON_MAP: Partial<Record<FeedAlertState, IconName>> = {
playing: "l-play-circle",
stop: "l-stop-circle",
offline: "l-exclamation-triangle",
loading: "l-spinner",
moving: "l-expand-from-corner",
// moving: "l-expand-from-corner",
zooming: "l-search",
saving_preset: "l-save",
host_unreachable: "l-exclamation-triangle",
Expand Down Expand Up @@ -53,14 +53,14 @@ export default function FeedAlert({ state }: Props) {
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-5"
>
<div className="absolute right-8 top-6 flex items-center gap-1.5 rounded bg-white/20 px-2 py-1 text-white">
{state && (
<div className="absolute right-8 top-4 z-20 flex items-center gap-1.5 rounded bg-white/20 px-2 py-1 text-white">
{state && ALERT_ICON_MAP[state] && (
<CareIcon
className={classNames(
"text-base",
state === "loading" && "animate-spin",
)}
icon={ALERT_ICON_MAP[state]}
icon={ALERT_ICON_MAP[state]!}
/>
)}
<span className="text-xs font-medium capitalize">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import useOperateCamera, {
PTZPayload,
} from "../../CameraFeed/useOperateCamera";
import request from "../../../Utils/request/request";
import { classNames } from "../../../Utils/utils";
import { classNames, isIOS } from "../../../Utils/utils";

export const ConsultationFeedTab = (props: ConsultationTabProps) => {
const authUser = useAuthUser();
Expand All @@ -27,6 +27,7 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => {
const [preset, setPreset] = useState<AssetBedModel>();
const [isUpdatingPreset, setIsUpdatingPreset] = useState(false);
const [hasMoved, setHasMoved] = useState(false);
const [key, setKey] = useState(0);
const divRef = useRef<any>();

const operate = useOperateCamera(asset?.id ?? "", true);
Expand Down Expand Up @@ -106,9 +107,15 @@ export const ConsultationFeedTab = (props: ConsultationTabProps) => {
</span>
<div ref={divRef}>
<CameraFeed
key={key}
asset={asset}
preset={preset?.meta.position}
onMove={() => setHasMoved(true)}
onReset={() => {
if (isIOS) {
setKey(key + 1);
}
}}
onStreamError={() => {
triggerGoal("Camera Feed Viewed", {
consultationId: props.consultationId,
Expand Down
4 changes: 2 additions & 2 deletions src/Components/Facility/DoctorVideoSlideover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ function UserListItem({ user }: { user: UserAnnotatedWithGroup }) {
function connectOnWhatsApp(e: React.MouseEvent<HTMLAnchorElement>) {
e.stopPropagation();
if (!user.alt_phone_number) return;
const phoneNumber = user.alt_phone_number;
const phoneNumber = user.alt_phone_number?.replace(/\D+/g, "");
const message = `${courtesyTitle(user)} ${user.first_name} ${user.last_name}, I have a query regarding a patient.\n\nPatient Link: ${window.location.href}`;
const encodedMessage = encodeURIComponent(message);
const whatsappAppURL = `whatsapp://send?phone=${phoneNumber}&text=${encodedMessage}`;
const whatsappWebURL = `https://web.whatsapp.com/send?phone=${phoneNumber}&text=${encodedMessage}`;
const whatsappWebURL = `https://wa.me/${phoneNumber}?text=${encodedMessage}`;

const userAgent = navigator.userAgent;
const isEdge = /edge\/\d+/i.test(userAgent);
Expand Down
6 changes: 3 additions & 3 deletions src/Components/Patient/PatientHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ export const PatientHome = (props: any) => {
{patientData?.last_consultation?.assigned_to_object
.alt_phone_number && (
<a
href={`https://wa.me/${patientData?.last_consultation?.assigned_to_object.alt_phone_number}`}
href={`https://wa.me/${patientData?.last_consultation?.assigned_to_object.alt_phone_number?.replace(/\D+/g, "")}`}
target="_blank"
rel="noreferrer"
>
Expand Down Expand Up @@ -433,7 +433,7 @@ export const PatientHome = (props: any) => {
</div>
<div>
<a
href={`https://wa.me/${patientData.phone_number}`}
href={`https://wa.me/${patientData.phone_number?.replace(/\D+/g, "")}`}
target="_blank"
className="text-sm font-normal text-sky-600 hover:text-sky-300"
rel="noreferrer"
Expand All @@ -458,7 +458,7 @@ export const PatientHome = (props: any) => {
</div>
<div>
<a
href={`https://wa.me/${patientData.emergency_phone_number}`}
href={`https://wa.me/${patientData.emergency_phone_number?.replace(/\D+/g, "")}`}
target="_blank"
className="text-sm font-normal text-sky-600 hover:text-sky-300"
rel="noreferrer"
Expand Down
Loading