mirror of
https://github.com/jambonz/chrome-extension-dialer.git
synced 2025-12-19 04:47:45 +00:00
fix switching user status
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
export const DEFAULT_COLOR_SCHEME = "pink";
|
||||
export const DEFAULT_TOAST_DURATION = 5000;
|
||||
export const DEFAULT_TOAST_DURATION = 3000;
|
||||
|
||||
@@ -79,6 +79,6 @@ export type SipClientStatus =
|
||||
| "connecting"
|
||||
| "connected"
|
||||
| "disconnected"
|
||||
| "online"
|
||||
| "offline";
|
||||
| "registered"
|
||||
| "unregistered";
|
||||
export type SipCallDirection = "" | "outgoing" | "incoming";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
Box,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuButton,
|
||||
@@ -54,11 +55,13 @@ export const IconButtonMenu = ({
|
||||
<Spinner color="jambonz.500" size="xs" />
|
||||
</MenuItem>
|
||||
) : items.length > 0 ? (
|
||||
items.map((i, idx) => (
|
||||
<Box overflowY="auto" maxH="250px">
|
||||
{items.map((i, idx) => (
|
||||
<MenuItem key={idx} onClick={() => onClick(i.name, i.value)}>
|
||||
{i.name}
|
||||
</MenuItem>
|
||||
))
|
||||
))}
|
||||
</Box>
|
||||
) : (
|
||||
<MenuItem>{noResultLabel}</MenuItem>
|
||||
)}
|
||||
|
||||
@@ -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<React.SetStateAction<boolean>>];
|
||||
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 (
|
||||
<Box
|
||||
position="relative"
|
||||
w="90px"
|
||||
h="30px"
|
||||
bg={isToggled && !isDisabled ? "green.500" : "grey.500"}
|
||||
bg={isToggled ? "green.500" : "grey.500"}
|
||||
borderRadius="full"
|
||||
onClick={() => {
|
||||
if (!isDisabled) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SipClientStatus>("offline");
|
||||
const [status, setStatus] = useState<SipClientStatus>("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<Partial<RegisteredUser>>(
|
||||
{
|
||||
@@ -123,24 +124,26 @@ export const Phone = ({
|
||||
sipDisplayNameRef.current = sipDisplayName;
|
||||
if (sipDomain && sipUsername && sipPassword && sipServerAddress) {
|
||||
if (sipUA.current) {
|
||||
if (sipUA.current.isConnected()) {
|
||||
clientGoOffline();
|
||||
isRestartRef.current = true;
|
||||
} else {
|
||||
createSipClient();
|
||||
}
|
||||
} else {
|
||||
createSipClient();
|
||||
}
|
||||
setIsConfigured(true);
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
unregisteredReasonRef.current = `User is not registered${
|
||||
args.cause ? `, ${args.cause}` : ""
|
||||
}`;
|
||||
});
|
||||
|
||||
sipClient.on(SipConstants.UA_DISCONNECTED, (args) => {
|
||||
if (unregisteredReasonRef.current) {
|
||||
toast({
|
||||
title: `User is not registered${args.cause ? `, ${args.cause}` : ""}`,
|
||||
title: unregisteredReasonRef.current,
|
||||
status: "warning",
|
||||
duration: DEFAULT_TOAST_DURATION,
|
||||
isClosable: true,
|
||||
});
|
||||
});
|
||||
|
||||
sipClient.on(SipConstants.UA_DISCONNECTED, (args) => {
|
||||
unregisteredReasonRef.current = "";
|
||||
}
|
||||
setStatus("disconnected");
|
||||
if (isRestartRef.current) {
|
||||
createSipClient();
|
||||
isRestartRef.current = false;
|
||||
}
|
||||
|
||||
if (args.error) {
|
||||
toast({
|
||||
title: `Cannot connect to ${sipServerAddress}, ${args.reason}`,
|
||||
@@ -392,15 +417,15 @@ export const Phone = ({
|
||||
if (s === status) {
|
||||
return;
|
||||
}
|
||||
if (s === "offline") {
|
||||
clientGoOffline();
|
||||
} else {
|
||||
createSipClient();
|
||||
if (s === "unregistered") {
|
||||
if (sipUA.current) {
|
||||
sipUA.current.stop();
|
||||
}
|
||||
} else {
|
||||
if (sipUA.current) {
|
||||
sipUA.current.start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isOnline = () => {
|
||||
return status === "online";
|
||||
};
|
||||
|
||||
const handleHangup = () => {
|
||||
@@ -441,18 +466,28 @@ export const Phone = ({
|
||||
}
|
||||
};
|
||||
|
||||
const isStatusRegistered = () => {
|
||||
return status === "registered";
|
||||
};
|
||||
|
||||
return (
|
||||
<Center flexDirection="column">
|
||||
{isConfigured ? (
|
||||
<>
|
||||
<HStack spacing={2} boxShadow="md" w="full" borderRadius={5} p={2}>
|
||||
<Image src={isOnline() ? GreenAvatar : Avatar} boxSize="35px" />
|
||||
<Image
|
||||
src={isStatusRegistered() ? GreenAvatar : Avatar}
|
||||
boxSize="35px"
|
||||
/>
|
||||
<VStack alignItems="start" w="full" spacing={0}>
|
||||
<HStack spacing={2} w="full">
|
||||
<Text fontWeight="bold" fontSize="13px">
|
||||
{sipDisplayName || sipUsername}
|
||||
</Text>
|
||||
<Circle size="8px" bg={isOnline() ? "green.500" : "gray.500"} />
|
||||
<Circle
|
||||
size="8px"
|
||||
bg={isStatusRegistered() ? "green.500" : "gray.500"}
|
||||
/>
|
||||
</HStack>
|
||||
<Text fontWeight="bold" w="full">
|
||||
{`${sipUsername}@${sipDomain}`}
|
||||
@@ -462,13 +497,13 @@ export const Phone = ({
|
||||
<Spacer />
|
||||
<VStack h="full" align="center">
|
||||
<JambonzSwitch
|
||||
isDisabled={isForceChangeUaStatus}
|
||||
isDisabled={isSwitchingUserStatus}
|
||||
onlabel="Online"
|
||||
offLabel="Offline"
|
||||
initialCheck={isOnline() || isForceChangeUaStatus}
|
||||
checked={[isOnline, setIsOnline]}
|
||||
onChange={(v) => {
|
||||
setIsForceChangeUaStatus(true);
|
||||
handleGoOffline(v ? "online" : "offline");
|
||||
setIsSwitchingUserStatus(true);
|
||||
handleGoOffline(v ? "registered" : "unregistered");
|
||||
}}
|
||||
/>
|
||||
</VStack>
|
||||
@@ -498,7 +533,7 @@ export const Phone = ({
|
||||
spacing={2}
|
||||
w="full"
|
||||
mt={5}
|
||||
className={isOnline() ? "" : "blurred"}
|
||||
className={isStatusRegistered() ? "" : "blurred"}
|
||||
>
|
||||
{isAdvanceMode && isSipClientIdle(callStatus) && (
|
||||
<HStack spacing={2} align="start" w="full">
|
||||
@@ -627,7 +662,7 @@ export const Phone = ({
|
||||
<Button
|
||||
w="full"
|
||||
onClick={handleCallButtion}
|
||||
isDisabled={status === "offline"}
|
||||
isDisabled={!isStatusRegistered()}
|
||||
colorScheme="jambonz"
|
||||
alignContent="center"
|
||||
isLoading={isCallButtonLoading}
|
||||
|
||||
Reference in New Issue
Block a user