mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
* fix: unattended component reload due to session changes When the session is updated, status goes back to loading then authenticated or unauthenticated. session.accessTokenExpires may also be updated. This triggered various component refresh at unattented times, and brake the user experience. By splitting to only what's needed with memoization, it will prevent unattented refresh. * review * review: change syntax
151 lines
4.7 KiB
TypeScript
151 lines
4.7 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { featureEnabled } from "../../domainContext";
|
|
|
|
import { ShareMode, toShareMode } from "../../lib/shareMode";
|
|
import { GetTranscript, GetTranscriptTopic, UpdateTranscript } from "../../api";
|
|
import {
|
|
Box,
|
|
Flex,
|
|
IconButton,
|
|
Modal,
|
|
ModalBody,
|
|
ModalContent,
|
|
ModalHeader,
|
|
ModalOverlay,
|
|
Text,
|
|
} from "@chakra-ui/react";
|
|
import { FaShare } from "react-icons/fa";
|
|
import useApi from "../../lib/useApi";
|
|
import useSessionUser from "../../lib/useSessionUser";
|
|
import { CustomSession } from "../../lib/types";
|
|
import { Select } from "chakra-react-select";
|
|
import ShareLink from "./shareLink";
|
|
import ShareCopy from "./shareCopy";
|
|
import ShareZulip from "./shareZulip";
|
|
|
|
type ShareAndPrivacyProps = {
|
|
finalSummaryRef: any;
|
|
transcriptResponse: GetTranscript;
|
|
topicsResponse: GetTranscriptTopic[];
|
|
};
|
|
|
|
type ShareOption = { value: ShareMode; label: string };
|
|
|
|
const shareOptions = [
|
|
{ label: "Private", value: toShareMode("private") },
|
|
{ label: "Secure", value: toShareMode("semi-private") },
|
|
{ label: "Public", value: toShareMode("public") },
|
|
];
|
|
|
|
export default function ShareAndPrivacy(props: ShareAndPrivacyProps) {
|
|
const [showModal, setShowModal] = useState(false);
|
|
const [isOwner, setIsOwner] = useState(false);
|
|
const [shareMode, setShareMode] = useState<ShareOption>(
|
|
shareOptions.find(
|
|
(option) => option.value === props.transcriptResponse.share_mode,
|
|
) || shareOptions[0],
|
|
);
|
|
const [shareLoading, setShareLoading] = useState(false);
|
|
const requireLogin = featureEnabled("requireLogin");
|
|
const api = useApi();
|
|
|
|
const updateShareMode = async (selectedShareMode: any) => {
|
|
if (!api)
|
|
throw new Error("ShareLink's API should always be ready at this point");
|
|
|
|
setShareLoading(true);
|
|
const requestBody: UpdateTranscript = {
|
|
share_mode: toShareMode(selectedShareMode.value),
|
|
};
|
|
|
|
const updatedTranscript = await api.v1TranscriptUpdate({
|
|
transcriptId: props.transcriptResponse.id,
|
|
requestBody,
|
|
});
|
|
setShareMode(
|
|
shareOptions.find(
|
|
(option) => option.value === updatedTranscript.share_mode,
|
|
) || shareOptions[0],
|
|
);
|
|
setShareLoading(false);
|
|
};
|
|
|
|
const userId = useSessionUser().id;
|
|
|
|
useEffect(() => {
|
|
setIsOwner(!!(requireLogin && userId === props.transcriptResponse.user_id));
|
|
}, [userId, props.transcriptResponse.user_id]);
|
|
|
|
return (
|
|
<>
|
|
<IconButton
|
|
icon={<FaShare />}
|
|
onClick={() => setShowModal(true)}
|
|
aria-label="Share"
|
|
/>
|
|
<Modal
|
|
isOpen={!!showModal}
|
|
onClose={() => setShowModal(false)}
|
|
size={"xl"}
|
|
>
|
|
<ModalOverlay />
|
|
<ModalContent>
|
|
<ModalHeader>Share</ModalHeader>
|
|
<ModalBody>
|
|
{requireLogin && (
|
|
<Box mb={4}>
|
|
<Text size="sm" mb="2" fontWeight={"bold"}>
|
|
Share mode
|
|
</Text>
|
|
<Text size="sm" mb="2">
|
|
{shareMode.value === "private" &&
|
|
"This transcript is private and can only be accessed by you."}
|
|
{shareMode.value === "semi-private" &&
|
|
"This transcript is secure. Only authenticated users can access it."}
|
|
{shareMode.value === "public" &&
|
|
"This transcript is public. Everyone can access it."}
|
|
</Text>
|
|
|
|
{isOwner && api && (
|
|
<Select
|
|
options={
|
|
[
|
|
{ value: "private", label: "Private" },
|
|
{ label: "Secure", value: "semi-private" },
|
|
{ label: "Public", value: "public" },
|
|
] as any
|
|
}
|
|
value={shareMode}
|
|
onChange={updateShareMode}
|
|
isLoading={shareLoading}
|
|
/>
|
|
)}
|
|
</Box>
|
|
)}
|
|
|
|
<Text size="sm" mb="2" fontWeight={"bold"}>
|
|
Share options
|
|
</Text>
|
|
<Flex gap={2} mb={2}>
|
|
{requireLogin && (
|
|
<ShareZulip
|
|
transcriptResponse={props.transcriptResponse}
|
|
topicsResponse={props.topicsResponse}
|
|
disabled={toShareMode(shareMode.value) === "private"}
|
|
/>
|
|
)}
|
|
<ShareCopy
|
|
finalSummaryRef={props.finalSummaryRef}
|
|
transcriptResponse={props.transcriptResponse}
|
|
topicsResponse={props.topicsResponse}
|
|
/>
|
|
</Flex>
|
|
|
|
<ShareLink transcriptId={props.transcriptResponse.id} />
|
|
</ModalBody>
|
|
</ModalContent>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|