diff --git a/src/common/types.ts b/src/common/types.ts index b05554e..2d7be05 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -1,3 +1,5 @@ +import { ConferenceModes } from "src/api/types"; + export interface LoginCredential { name?: string; password?: string; @@ -57,6 +59,12 @@ export interface AppSettings { sipDisplayName: string; } +export interface ConferenceSettings { + mode: ConferenceModes; + tags: string; + speakOnlyTo: string; +} + export interface AdvancedAppSettings { accountSid: string; apiKey: string; diff --git a/src/storage/index.ts b/src/storage/index.ts index 9cc3f00..caa9852 100644 --- a/src/storage/index.ts +++ b/src/storage/index.ts @@ -2,9 +2,26 @@ import { AdvancedAppSettings, AppSettings, CallHistory, + ConferenceSettings, } from "src/common/types"; import { Buffer } from "buffer"; +// Conference settings +const CONFERENCE_SETTINGS = "ConferenceSettingsKey"; + +export const saveConferenceSettings = (settings: ConferenceSettings) => { + sessionStorage.setItem(CONFERENCE_SETTINGS, JSON.stringify(settings)); +}; + +export const getConferenceSettings = (): ConferenceSettings => { + return JSON.parse( + sessionStorage.getItem(CONFERENCE_SETTINGS) || "{}" + ) as ConferenceSettings; +}; + +export const deleteConferenceSettings = () => { + sessionStorage.removeItem(CONFERENCE_SETTINGS); +}; // Settings const SETTINGS_KEY = "SettingsKey"; diff --git a/src/window/phone/conference.tsx b/src/window/phone/conference.tsx index 70c1a2b..d26066c 100644 --- a/src/window/phone/conference.tsx +++ b/src/window/phone/conference.tsx @@ -1,7 +1,6 @@ import { Box, Button, - Checkbox, FormControl, FormLabel, HStack, @@ -9,13 +8,20 @@ import { Radio, RadioGroup, Text, + useToast, VStack, } from "@chakra-ui/react"; import { FormEvent, useEffect, useState } from "react"; import { updateConferenceParticipantAction } from "src/api"; import { ConferenceModes } from "src/api/types"; +import { DEFAULT_TOAST_DURATION } from "src/common/constants"; import OutlineBox from "src/components/outline-box"; import { SipConstants } from "src/lib"; +import { + deleteConferenceSettings, + getConferenceSettings, + saveConferenceSettings, +} from "src/storage"; type JoinConferenceProbs = { conferenceId?: string; @@ -33,6 +39,7 @@ export const JoinConference = ({ handleCancel, call, }: JoinConferenceProbs) => { + const toast = useToast(); const [conferenceName, setConferenceName] = useState(conferenceId || ""); const [appTitle, setAppTitle] = useState( !!conferenceId ? "Joining Conference" : "Start Conference" @@ -40,11 +47,17 @@ export const JoinConference = ({ const [submitTitle, setSubmitTitle] = useState( !!conferenceId ? "Joining Conference" : "Start Conference" ); + const [cancelTitle, setCancelTitle] = useState("Cancel"); const [isLoading, setIsLoading] = useState(false); - const [speakOnlyTo, setSpeakOnlyTo] = useState(""); - const [tags, setTags] = useState(""); - const [mode, setMode] = useState("full_participant"); + const confSettings = getConferenceSettings(); + const [speakOnlyTo, setSpeakOnlyTo] = useState( + confSettings.speakOnlyTo || "" + ); + const [tags, setTags] = useState(confSettings.tags || ""); + const [mode, setMode] = useState( + confSettings.mode || "full_participant" + ); const [participantState, setParticipantState] = useState("Join as"); useEffect(() => { @@ -60,21 +73,11 @@ export const JoinConference = ({ case SipConstants.SESSION_ENDED: case SipConstants.SESSION_FAILED: setIsLoading(false); + deleteConferenceSettings(); break; } }, [callStatus]); - useEffect(() => { - switch (mode) { - case "full_participant": - break; - case "muted": - break; - case "coach": - break; - } - }, [mode]); - const handleSubmit = (e: FormEvent) => { e.preventDefault(); if (callStatus !== SipConstants.SESSION_ANSWERED) { @@ -88,21 +91,49 @@ export const JoinConference = ({ }; const configureConferenceSession = async () => { + const confSettings = getConferenceSettings(); if (callSid) { - await updateConferenceParticipantAction(callSid, { - action: mode === "muted" ? "mute" : "unmute", - tag: "", - }); + if (confSettings.mode) { + updateConferenceParticipantAction(callSid, { + action: confSettings.mode === "muted" ? "mute" : "unmute", + tag: "", + }) + .then(() => { + updateConferenceParticipantAction(callSid, { + action: mode === "coach" ? "coach" : "uncoach", + tag: confSettings.speakOnlyTo, + }).catch((error) => { + toast({ + title: error.msg, + status: "error", + duration: DEFAULT_TOAST_DURATION, + isClosable: true, + }); + }); + }) + .catch((error) => { + toast({ + title: error.msg, + status: "error", + duration: DEFAULT_TOAST_DURATION, + isClosable: true, + }); + }); + } - await updateConferenceParticipantAction(callSid, { - action: tags ? "tag" : "untag", - tag: tags, - }); - - await updateConferenceParticipantAction(callSid, { - action: mode === "coach" ? "coach" : "uncoach", - tag: speakOnlyTo, - }); + if (confSettings.tags) { + updateConferenceParticipantAction(callSid, { + action: tags ? "tag" : "untag", + tag: tags, + }).catch((error) => { + toast({ + title: error.msg, + status: "error", + duration: DEFAULT_TOAST_DURATION, + isClosable: true, + }); + }); + } } }; @@ -131,7 +162,14 @@ export const JoinConference = ({ setMode(e as ConferenceModes)} + onChange={(e) => { + setMode(e as ConferenceModes); + saveConferenceSettings({ + mode: e as ConferenceModes, + speakOnlyTo, + tags, + }); + }} value={mode} colorScheme="jambonz" > @@ -150,7 +188,14 @@ export const JoinConference = ({ type="text" placeholder="tag" value={speakOnlyTo} - onChange={(e) => setSpeakOnlyTo(e.target.value)} + onChange={(e) => { + setSpeakOnlyTo(e.target.value); + saveConferenceSettings({ + mode, + speakOnlyTo: e.target.value, + tags, + }); + }} disabled={mode !== "coach"} required={mode === "coach"} /> @@ -162,7 +207,14 @@ export const JoinConference = ({ type="text" placeholder="tag" value={tags} - onChange={(e) => setTags(e.target.value)} + onChange={(e) => { + setTags(e.target.value); + saveConferenceSettings({ + mode, + speakOnlyTo, + tags: e.target.value, + }); + }} /> @@ -181,7 +233,10 @@ export const JoinConference = ({ type="button" w="full" textColor="black" - onClick={handleCancel} + onClick={() => { + deleteConferenceSettings(); + handleCancel(); + }} > {cancelTitle} diff --git a/src/window/phone/index.tsx b/src/window/phone/index.tsx index 9359fb7..3db865e 100644 --- a/src/window/phone/index.tsx +++ b/src/window/phone/index.tsx @@ -114,6 +114,7 @@ export const Phone = ({ ); const [selectedConference, setSelectedConference] = useState(""); const [callSid, setCallSid] = useState(""); + const [showConference, setShowConference] = useState(false); const inputNumberRef = useRef(inputNumber); const sessionDirectionRef = useRef(sessionDirection); @@ -154,6 +155,13 @@ export const Phone = ({ clientGoOffline(); } fetchRegisterUser(); + getConferences() + .then(() => { + setShowConference(true); + }) + .catch(() => { + setShowConference(false); + }); }, [sipDomain, sipUsername, sipPassword, sipServerAddress, sipDisplayName]); useEffect(() => { @@ -643,7 +651,7 @@ export const Phone = ({ }} /> )} - {registeredUser.allow_direct_app_calling && ( + {registeredUser.allow_direct_app_calling && showConference && ( } tooltip="Join a conference"