From e27496f2c4a06fdb69db7cb9dc3bc6433fac493a Mon Sep 17 00:00:00 2001 From: Quan HL Date: Wed, 8 Nov 2023 23:16:03 +0700 Subject: [PATCH] fix switching user status --- src/common/constants.ts | 2 +- src/common/types.ts | 4 +- src/components/menu/index.tsx | 13 ++-- src/components/switch/index.tsx | 13 +--- src/lib/SipUA.ts | 4 ++ src/window/phone/index.tsx | 121 ++++++++++++++++++++------------ 6 files changed, 96 insertions(+), 61 deletions(-) diff --git a/src/common/constants.ts b/src/common/constants.ts index 6ac0a63..043fe66 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -1,2 +1,2 @@ export const DEFAULT_COLOR_SCHEME = "pink"; -export const DEFAULT_TOAST_DURATION = 5000; +export const DEFAULT_TOAST_DURATION = 3000; diff --git a/src/common/types.ts b/src/common/types.ts index b24570e..b05554e 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -79,6 +79,6 @@ export type SipClientStatus = | "connecting" | "connected" | "disconnected" - | "online" - | "offline"; + | "registered" + | "unregistered"; export type SipCallDirection = "" | "outgoing" | "incoming"; diff --git a/src/components/menu/index.tsx b/src/components/menu/index.tsx index 7f5c7b8..a935379 100644 --- a/src/components/menu/index.tsx +++ b/src/components/menu/index.tsx @@ -1,4 +1,5 @@ import { + Box, IconButton, Menu, MenuButton, @@ -54,11 +55,13 @@ export const IconButtonMenu = ({ ) : items.length > 0 ? ( - items.map((i, idx) => ( - onClick(i.name, i.value)}> - {i.name} - - )) + + {items.map((i, idx) => ( + onClick(i.name, i.value)}> + {i.name} + + ))} + ) : ( {noResultLabel} )} diff --git a/src/components/switch/index.tsx b/src/components/switch/index.tsx index b90af77..df38d1c 100644 --- a/src/components/switch/index.tsx +++ b/src/components/switch/index.tsx @@ -1,32 +1,25 @@ import { Box, Text } from "@chakra-ui/react"; -import { useEffect, useState } from "react"; type JambonzSwitchProbs = { onlabel: string; offLabel: string; - initialCheck: boolean; + checked: [boolean, React.Dispatch>]; isDisabled?: boolean; onChange: (value: boolean) => void; }; function JambonzSwitch({ onlabel, offLabel, - initialCheck, + checked: [isToggled, setToggled], isDisabled = false, onChange, }: JambonzSwitchProbs) { - const [isToggled, setToggled] = useState(initialCheck); - - useEffect(() => { - setToggled(initialCheck); - }, [initialCheck]); - return ( { if (!isDisabled) { diff --git a/src/lib/SipUA.ts b/src/lib/SipUA.ts index f3d56fc..3b43c59 100644 --- a/src/lib/SipUA.ts +++ b/src/lib/SipUA.ts @@ -211,4 +211,8 @@ export default class SipUA extends events.EventEmitter { const session: SipSession = this.#sessionManager.getSession(id); session.setActive(true); } + + isConnected() { + return this.#ua.isConnected(); + } } diff --git a/src/window/phone/index.tsx b/src/window/phone/index.tsx index 39b0d42..d1a2758 100644 --- a/src/window/phone/index.tsx +++ b/src/window/phone/index.tsx @@ -44,7 +44,6 @@ import GreenAvatar from "src/imgs/icons/Avatar-Green.svg"; import "./styles.scss"; import { deleteCurrentCall, - getAdvancedSettings, getCurrentCall, saveCallHistory, saveCurrentCall, @@ -86,7 +85,7 @@ export const Phone = ({ const [inputNumber, setInputNumber] = useState(""); const [appName, setAppName] = useState(""); const inputNumberRef = useRef(inputNumber); - const [status, setStatus] = useState("offline"); + const [status, setStatus] = useState("stop"); const [isConfigured, setIsConfigured] = useState(false); const [callStatus, setCallStatus] = useState(SipConstants.SESSION_ENDED); const [sessionDirection, setSessionDirection] = @@ -104,7 +103,9 @@ export const Phone = ({ const sipPasswordRef = useRef(""); const sipServerAddressRef = useRef(""); const sipDisplayNameRef = useRef(""); - const [isForceChangeUaStatus, setIsForceChangeUaStatus] = useState(false); + const [isSwitchingUserStatus, setIsSwitchingUserStatus] = useState(true); + const [isOnline, setIsOnline] = useState(false); + const unregisteredReasonRef = useRef(""); const isInputNumberFocusRef = useRef(false); const [registeredUser, setRegisteredUser] = useState>( { @@ -123,8 +124,12 @@ export const Phone = ({ sipDisplayNameRef.current = sipDisplayName; if (sipDomain && sipUsername && sipPassword && sipServerAddress) { if (sipUA.current) { - clientGoOffline(); - isRestartRef.current = true; + if (sipUA.current.isConnected()) { + clientGoOffline(); + isRestartRef.current = true; + } else { + createSipClient(); + } } else { createSipClient(); } @@ -133,14 +138,12 @@ export const Phone = ({ setIsConfigured(false); clientGoOffline(); } - getSelfRegisteredUser(sipUsernameRef.current).then(({ json }) => { - setRegisteredUser(json); - }); + fetchRegisterUser(); }, [sipDomain, sipUsername, sipPassword, sipServerAddress, sipDisplayName]); useEffect(() => { - const advancedSettings = getAdvancedSettings(); setIsAdvancedMode(!!advancedSettings.accountSid); + fetchRegisterUser(); }, [advancedSettings]); useEffect(() => { @@ -173,17 +176,16 @@ export const Phone = ({ }, [calledANumber]); useEffect(() => { - if (status === "online" || status === "offline") { - setIsForceChangeUaStatus(false); + if (status === "registered" || status === "disconnected") { + setIsSwitchingUserStatus(false); + setIsOnline(status === "registered"); } }, [status]); useEffect(() => { setInterval(() => { - getSelfRegisteredUser(sipUsernameRef.current).then(({ json }) => { - setRegisteredUser(json); - }); - }, 20000); + fetchRegisterUser(); + }, 10_000); }, []); // useEffect(() => { @@ -209,6 +211,20 @@ export const Phone = ({ // } // }; + const fetchRegisterUser = () => { + getSelfRegisteredUser(sipUsernameRef.current) + .then(({ json }) => { + setRegisteredUser(json); + }) + .catch(() => { + setRegisteredUser({ + allow_direct_app_calling: false, + allow_direct_queue_calling: false, + allow_direct_user_calling: false, + }); + }); + }; + const startCallDurationCounter = () => { stopCallDurationCounter(); timerRef.current = setInterval(() => { @@ -225,6 +241,7 @@ export const Phone = ({ }; const createSipClient = () => { + setIsSwitchingUserStatus(true); const client = { username: `${sipUsernameRef.current}@${sipDomainRef.current}`, password: sipPasswordRef.current, @@ -243,26 +260,34 @@ export const Phone = ({ // UA Status sipClient.on(SipConstants.UA_REGISTERED, (args) => { - setStatus("online"); + setStatus("registered"); }); sipClient.on(SipConstants.UA_UNREGISTERED, (args) => { - setStatus("offline"); - if (isRestartRef.current) { - createSipClient(); - isRestartRef.current = false; - } else { - clientGoOffline(); + setStatus("unregistered"); + if (sipUA.current) { + sipUA.current.stop(); } - toast({ - title: `User is not registered${args.cause ? `, ${args.cause}` : ""}`, - status: "warning", - duration: DEFAULT_TOAST_DURATION, - isClosable: true, - }); + unregisteredReasonRef.current = `User is not registered${ + args.cause ? `, ${args.cause}` : "" + }`; }); sipClient.on(SipConstants.UA_DISCONNECTED, (args) => { + if (unregisteredReasonRef.current) { + toast({ + title: unregisteredReasonRef.current, + status: "warning", + duration: DEFAULT_TOAST_DURATION, + isClosable: true, + }); + unregisteredReasonRef.current = ""; + } setStatus("disconnected"); + if (isRestartRef.current) { + createSipClient(); + isRestartRef.current = false; + } + if (args.error) { toast({ title: `Cannot connect to ${sipServerAddress}, ${args.reason}`, @@ -392,17 +417,17 @@ export const Phone = ({ if (s === status) { return; } - if (s === "offline") { - clientGoOffline(); + if (s === "unregistered") { + if (sipUA.current) { + sipUA.current.stop(); + } } else { - createSipClient(); + if (sipUA.current) { + sipUA.current.start(); + } } }; - const isOnline = () => { - return status === "online"; - }; - const handleHangup = () => { if (isSipClientAnswered(callStatus) || isSipClientRinging(callStatus)) { sipUA.current?.terminate(480, "Call Finished", undefined); @@ -441,18 +466,28 @@ export const Phone = ({ } }; + const isStatusRegistered = () => { + return status === "registered"; + }; + return (
{isConfigured ? ( <> - + {sipDisplayName || sipUsername} - + {`${sipUsername}@${sipDomain}`} @@ -462,13 +497,13 @@ export const Phone = ({ { - setIsForceChangeUaStatus(true); - handleGoOffline(v ? "online" : "offline"); + setIsSwitchingUserStatus(true); + handleGoOffline(v ? "registered" : "unregistered"); }} /> @@ -498,7 +533,7 @@ export const Phone = ({ spacing={2} w="full" mt={5} - className={isOnline() ? "" : "blurred"} + className={isStatusRegistered() ? "" : "blurred"} > {isAdvanceMode && isSipClientIdle(callStatus) && ( @@ -627,7 +662,7 @@ export const Phone = ({