diff --git a/public/index.html b/public/index.html
index 28ce49e..9eb2137 100644
--- a/public/index.html
+++ b/public/index.html
@@ -4,12 +4,6 @@
-
{
this.emit(SipConstants.SESSION_ANSWERED, {
status: SipConstants.SESSION_ANSWERED,
- callSid: response.hasHeader("X-Call-Sid")
+ callSid: response?.hasHeader("X-Call-Sid")
? response.getHeader("X-Call-Sid")
: null,
});
diff --git a/src/storage/index.ts b/src/storage/index.ts
index 2345993..c287e97 100644
--- a/src/storage/index.ts
+++ b/src/storage/index.ts
@@ -42,34 +42,24 @@ export const saveSettings = (settings: AppSettings) => {
if (str) {
const parsed = JSON.parse(str);
- // const data: IAppSettings[] = parsed.map((el: saveSettingFormat) => {
- // return {
- // active: el.active,
- // decoded: JSON.parse(
- // Buffer.from(el.encoded, "base64").toString("utf-8")
- // ),
- // id: el.id,
- // };
- // });
-
- // const alreadyExists = data.filter(
- // (el) =>
- // el.decoded.sipDomain === settings.sipDomain &&
- // el.decoded.sipServerAddress === settings.sipServerAddress
- // );
- // if (!!alreadyExists.length) return;
-
- localStorage.setItem(
- SETTINGS_KEY,
- JSON.stringify([
- ...parsed,
- {
- encoded,
- active: false,
- id: parsed.length + 1,
- },
- ])
- );
+ if (parsed.length < 1) {
+ localStorage.setItem(
+ SETTINGS_KEY,
+ JSON.stringify([{ id: 1, encoded, active: true }])
+ );
+ } else {
+ localStorage.setItem(
+ SETTINGS_KEY,
+ JSON.stringify([
+ ...parsed,
+ {
+ encoded,
+ active: false,
+ id: parsed.length + 1,
+ },
+ ])
+ );
+ }
} else {
localStorage.setItem(
SETTINGS_KEY,
@@ -153,10 +143,7 @@ export const getSettings = (): IAppSettings[] => {
};
});
return decoded;
- // const planText = Buffer.from(str, "base64").toString("utf-8");
- // return JSON.parse(planText) as AppSettings;
}
- // return {} as AppSettings;
return [] as IAppSettings[];
};
@@ -175,10 +162,7 @@ export const getActiveSettings = (): IAppSettings => {
};
});
return decoded.find((el) => el.active) as IAppSettings;
- // const planText = Buffer.from(str, "base64").toString("utf-8");
- // return JSON.parse(planText) as AppSettings;
}
- // return {} as AppSettings;
return {} as IAppSettings;
};
@@ -227,12 +211,8 @@ export const getAdvancedSettings = (): IAdvancedAppSettings[] => {
};
});
return decoded;
- // const planText = Buffer.from(str, "base64").toString("utf-8");
- // return JSON.parse(planText) as AppSettings;
}
- // return {} as AppSettings;
return [] as IAdvancedAppSettings[];
- // return [] as IAppSettings[];
};
export const getActiveAdvancedSettings = (): IAdvancedAppSettings => {
const str = localStorage.getItem(ADVANCED_SETTINGS_KET);
@@ -250,16 +230,11 @@ export const getActiveAdvancedSettings = (): IAdvancedAppSettings => {
};
});
return decoded.find((el) => el.active) as IAdvancedAppSettings;
- // const planText = Buffer.from(str, "base64").toString("utf-8");
- // return JSON.parse(planText) as AppSettings;
}
- // return {} as AppSettings;
return {} as IAdvancedAppSettings;
- // return [] as IAppSettings[];
};
// Call History
-
const historyKey = "History";
const MAX_HISTORY_COUNT = 20;
export const saveCallHistory = (username: string, call: CallHistory) => {
diff --git a/src/styles.scss b/src/styles.scss
index 8098917..3e092df 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -2,30 +2,10 @@
font-family: "Source Sans";
src: url("../public/fonts/SourceSans3-Regular.ttf") format("truetype");
}
-// @font-face {
-// font-family: 'FontName';
-// font-style: normal;
-// font-weight: 300;
-// src: local('FontName Light'), local('FontName-Light'), url(https://fonts.gstatic.com/some-url.woff2) format('woff2');
-// }
-
-// @font-face {
-// font-family: 'FontName';
-// font-style: normal;
-// font-weight: 700;
-// src: local('FontName Bold'), local('FontName-Bold'), url(https://fonts.gstatic.com/some-url.woff2) format('woff2');
-// }
-// * {
-// font-family: "Source Sans 3", sans-serif;
-// }
-// body {
-// font-family: "Source Sans 3", sans-serif;
-// }
.container {
width: 280px;
height: 480px;
- // font-family: "Source Sans 3", sans-serif;
margin: 0;
padding: 0;
}
diff --git a/src/window/app.tsx b/src/window/app.tsx
index 03a2f21..8f0e3a6 100644
--- a/src/window/app.tsx
+++ b/src/window/app.tsx
@@ -16,7 +16,6 @@ import { getActiveSettings, getCallHistories, getSettings } from "src/storage";
import CallHistories from "./history";
import { CallHistory, IAppSettings, SipClientStatus } from "src/common/types";
import Footer from "./footer/footer";
-import { SipUA } from "src/lib";
export const WindowApp = () => {
const [sipDomain, setSipDomain] = useState("");
@@ -33,9 +32,24 @@ export const WindowApp = () => {
const [advancedSettings, setAdvancedSettings] = useState(
null
);
- const sipUA = useRef(null);
const [isSwitchingUserStatus, setIsSwitchingUserStatus] = useState(false);
const [isOnline, setIsOnline] = useState(false);
+ const phoneSipAschildRef = useRef<{
+ updateGoOffline: (x: string) => void;
+ } | null>(null);
+
+ const handleGoOffline = (s: SipClientStatus) => {
+ if (phoneSipAschildRef.current) {
+ if (s === status) {
+ return;
+ }
+ if (s === "unregistered") {
+ phoneSipAschildRef.current.updateGoOffline("stop");
+ } else {
+ phoneSipAschildRef.current.updateGoOffline("start");
+ }
+ }
+ };
const loadSettings = () => {
const settings = getSettings();
@@ -56,6 +70,7 @@ export const WindowApp = () => {
title: "Dialer",
content: (
{
advancedSettings={advancedSettings}
allSettings={allSettings}
reload={loadSettings}
- sipUA={sipUA}
setIsSwitchingUserStatus={setIsSwitchingUserStatus}
setIsOnline={setIsOnline}
/>
@@ -144,7 +158,7 @@ export const WindowApp = () => {
setIsSwitchingUserStatus={setIsSwitchingUserStatus}
isOnline={isOnline}
setIsOnline={setIsOnline}
- sipUA={sipUA}
+ onHandleGoOffline={handleGoOffline}
/>
);
diff --git a/src/window/footer/footer.tsx b/src/window/footer/footer.tsx
index 520662f..bf3ab34 100644
--- a/src/window/footer/footer.tsx
+++ b/src/window/footer/footer.tsx
@@ -1,9 +1,7 @@
-import { HStack, Image, Text, useToast } from "@chakra-ui/react";
+import { HStack, Image, Text } from "@chakra-ui/react";
import jambonz from "src/imgs/jambonz.svg";
-import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react";
+import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { SipClientStatus } from "src/common/types";
-import { SipConstants, SipUA } from "src/lib";
-import { DEFAULT_TOAST_DURATION } from "src/common/constants";
import JambonzSwitch from "src/components/switch";
import "./styles.scss";
@@ -19,7 +17,7 @@ function Footer({
setIsSwitchingUserStatus,
isOnline,
setIsOnline,
- sipUA,
+ onHandleGoOffline,
}: {
status: string;
setStatus: Dispatch>;
@@ -32,135 +30,24 @@ function Footer({
setIsSwitchingUserStatus: React.Dispatch>;
isOnline: boolean;
setIsOnline: React.Dispatch>;
- sipUA: React.MutableRefObject;
+ onHandleGoOffline: (s: SipClientStatus) => void;
}) {
const [isConfigured, setIsConfigured] = useState(false);
- // const sipUA = useRef(null);
- const sipUsernameRef = useRef("");
- const sipPasswordRef = useRef("");
- const sipServerAddressRef = useRef("");
- const sipDomainRef = useRef("");
- const sipDisplayNameRef = useRef("");
- const unregisteredReasonRef = useRef("");
- const isRestartRef = useRef(false);
-
- const toast = useToast();
-
useEffect(() => {
if (status === "registered" || status === "disconnected") {
setIsSwitchingUserStatus(false);
setIsOnline(status === "registered");
}
- }, [status]);
+ }, [status, setIsSwitchingUserStatus, setIsOnline]);
useEffect(() => {
- sipDomainRef.current = sipDomain;
- sipUsernameRef.current = sipUsername;
- sipPasswordRef.current = sipPassword;
- sipServerAddressRef.current = sipServerAddress;
- 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();
}
- }, [sipDomain, sipUsername, sipPassword, sipServerAddress, sipDisplayName]);
-
- const clientGoOffline = () => {
- if (sipUA.current) {
- sipUA.current.stop();
- sipUA.current = null;
- }
- };
-
- const handleGoOffline = (s: SipClientStatus) => {
- if (s === status) {
- return;
- }
- if (s === "unregistered") {
- if (sipUA.current) {
- sipUA.current.stop();
- }
- } else {
- if (sipUA.current) {
- sipUA.current.start();
- }
- }
- };
-
- const createSipClient = () => {
- setIsSwitchingUserStatus(true);
- const client = {
- username: `${sipUsernameRef.current}@${sipDomainRef.current}`,
- password: sipPasswordRef.current,
- name: sipDisplayNameRef.current ?? sipUsernameRef.current,
- };
-
- const settings = {
- pcConfig: {
- iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }],
- },
- wsUri: sipServerAddressRef.current,
- register: true,
- };
-
- const sipClient = new SipUA(client, settings);
-
- // UA Status
- sipClient.on(SipConstants.UA_REGISTERED, (args) => {
- setStatus("registered");
- });
- sipClient.on(SipConstants.UA_UNREGISTERED, (args) => {
- 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: 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}`,
- status: "warning",
- duration: DEFAULT_TOAST_DURATION,
- isClosable: true,
- });
- }
- });
-
- sipClient.start();
- sipUA.current = sipClient;
- };
+ }, [sipDomain, sipUsername, sipPassword, sipServerAddress]);
return (
{
setIsSwitchingUserStatus(true);
- handleGoOffline(v ? "registered" : "unregistered");
+ onHandleGoOffline(v ? "registered" : "unregistered");
}}
/>
You are {isOnline ? "online" : "offline"}
diff --git a/src/window/phone/index.tsx b/src/window/phone/index.tsx
index ac7304f..66e404b 100644
--- a/src/window/phone/index.tsx
+++ b/src/window/phone/index.tsx
@@ -13,7 +13,15 @@ import {
VStack,
useToast,
} from "@chakra-ui/react";
-import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react";
+import {
+ Dispatch,
+ forwardRef,
+ SetStateAction,
+ useEffect,
+ useImperativeHandle,
+ useRef,
+ useState,
+} from "react";
import {
IAppSettings,
SipCallDirection,
@@ -79,7 +87,6 @@ type PhoneProbs = {
stat: [string, Dispatch>];
allSettings: IAppSettings[];
reload: () => void;
- sipUA: React.MutableRefObject;
setIsSwitchingUserStatus: React.Dispatch>;
setIsOnline: React.Dispatch>;
};
@@ -91,793 +98,805 @@ enum PAGE_VIEW {
JOIN_CONFERENCE,
}
-// add some basic details to advanced to match them, make basic compulsory to fill advanced.
-
-export const Phone = ({
- sipDomain,
- sipServerAddress,
- sipUsername,
- sipPassword,
- sipDisplayName,
- stat: [status, setStatus],
- calledNumber: [calledANumber, setCalledANumber],
- calledName: [calledAName, setCalledAName],
- advancedSettings,
- allSettings,
- reload,
- // sipUA,
- setIsSwitchingUserStatus,
- setIsOnline,
-}: PhoneProbs) => {
- const [inputNumber, setInputNumber] = useState("");
- const [appName, setAppName] = useState("");
- // const [status, setStatus] = useState("stop");
- const [isConfigured, setIsConfigured] = useState(false);
- const [callStatus, setCallStatus] = useState(SipConstants.SESSION_ENDED);
- const [sessionDirection, setSessionDirection] =
- useState("");
- const [seconds, setSeconds] = useState(0);
- const [isCallButtonLoading, setIsCallButtonLoading] = useState(false);
- const [isAdvanceMode, setIsAdvancedMode] = useState(false);
- // const [isSwitchingUserStatus, setIsSwitchingUserStatus] = useState(true);
- // const [isOnline, setIsOnline] = useState(false);
- const [pageView, setPageView] = useState(PAGE_VIEW.DIAL_PAD);
- const [registeredUser, setRegisteredUser] = useState>(
+export const Phone = forwardRef(
+ (
{
+ sipDomain,
+ sipServerAddress,
+ sipUsername,
+ sipPassword,
+ sipDisplayName,
+ stat: [status, setStatus],
+ calledNumber: [calledANumber, setCalledANumber],
+ calledName: [calledAName, setCalledAName],
+ advancedSettings,
+ allSettings,
+ reload,
+ setIsSwitchingUserStatus,
+ setIsOnline,
+ }: PhoneProbs,
+ ref: any
+ ) => {
+ const [inputNumber, setInputNumber] = useState("");
+ const [appName, setAppName] = useState("");
+ const [isConfigured, setIsConfigured] = useState(false);
+ const [callStatus, setCallStatus] = useState(SipConstants.SESSION_ENDED);
+ const [sessionDirection, setSessionDirection] =
+ useState("");
+ const [seconds, setSeconds] = useState(0);
+ const [isCallButtonLoading, setIsCallButtonLoading] = useState(false);
+ const [isAdvanceMode, setIsAdvancedMode] = useState(false);
+ const [pageView, setPageView] = useState(PAGE_VIEW.DIAL_PAD);
+ const [registeredUser, setRegisteredUser] = useState<
+ Partial
+ >({
allow_direct_app_calling: false,
allow_direct_queue_calling: false,
allow_direct_user_calling: false,
- }
- );
- const [selectedConference, setSelectedConference] = useState("");
- const [callSid, setCallSid] = useState("");
- const [showConference, setShowConference] = useState(false);
+ });
+ const [selectedConference, setSelectedConference] = useState("");
+ const [callSid, setCallSid] = useState("");
+ const [showConference, setShowConference] = useState(false);
- const [showAccounts, setShowAccounts] = useState(false);
+ const [showAccounts, setShowAccounts] = useState(false);
- const inputNumberRef = useRef(inputNumber);
- const sessionDirectionRef = useRef(sessionDirection);
- const sipUA = useRef(null);
- const timerRef = useRef(null);
- const isRestartRef = useRef(false);
- const sipDomainRef = useRef("");
- const sipUsernameRef = useRef("");
- const sipPasswordRef = useRef("");
- const sipServerAddressRef = useRef("");
- const sipDisplayNameRef = useRef("");
- const unregisteredReasonRef = useRef("");
- const isInputNumberFocusRef = useRef(false);
- const secondsRef = useRef(seconds);
- const accountsCardRef = useRef(null);
+ const inputNumberRef = useRef(inputNumber);
+ const sessionDirectionRef = useRef(sessionDirection);
+ const sipUA = useRef(null);
+ const timerRef = useRef(null);
+ const isRestartRef = useRef(false);
+ const sipDomainRef = useRef("");
+ const sipUsernameRef = useRef("");
+ const sipPasswordRef = useRef("");
+ const sipServerAddressRef = useRef("");
+ const sipDisplayNameRef = useRef("");
+ const unregisteredReasonRef = useRef("");
+ const isInputNumberFocusRef = useRef(false);
+ const secondsRef = useRef(seconds);
+ const accountsCardRef = useRef(null);
- const toast = useToast();
+ const toast = useToast();
- useEffect(() => {
- sipDomainRef.current = sipDomain;
- sipUsernameRef.current = sipUsername;
- sipPasswordRef.current = sipPassword;
- sipServerAddressRef.current = sipServerAddress;
- sipDisplayNameRef.current = sipDisplayName;
- if (sipDomain && sipUsername && sipPassword && sipServerAddress) {
- if (sipUA.current) {
- if (sipUA.current.isConnected()) {
- clientGoOffline();
- isRestartRef.current = true;
+ useImperativeHandle(ref, () => ({
+ updateGoOffline(newState: string) {
+ if (newState === "start") {
+ sipUA.current?.start();
+ } else {
+ sipUA.current?.stop();
+ }
+ },
+ }));
+
+ useEffect(() => {
+ sipDomainRef.current = sipDomain;
+ sipUsernameRef.current = sipUsername;
+ sipPasswordRef.current = sipPassword;
+ sipServerAddressRef.current = sipServerAddress;
+ 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 {
- createSipClient();
+ setIsConfigured(false);
+ clientGoOffline();
}
- setIsConfigured(true);
- } else {
- setIsConfigured(false);
- clientGoOffline();
- }
- fetchRegisterUser();
- getConferences()
- ?.then(() => {
- setShowConference(true);
- })
- .catch(() => {
- setShowConference(false);
- });
- }, [sipDomain, sipUsername, sipPassword, sipServerAddress, sipDisplayName]);
-
- useEffect(() => {
- setIsAdvancedMode(!!advancedSettings?.decoded?.accountSid);
- fetchRegisterUser();
- }, [advancedSettings]);
-
- useEffect(() => {
- inputNumberRef.current = inputNumber;
- sessionDirectionRef.current = sessionDirection;
- secondsRef.current = seconds;
- }, [inputNumber, seconds, sessionDirection]);
-
- useEffect(() => {
- if (isSipClientIdle(callStatus) && isCallButtonLoading) {
- setIsCallButtonLoading(false);
- }
- switch (callStatus) {
- case SipConstants.SESSION_RINGING:
- if (sessionDirection === "incoming") {
- setPageView(PAGE_VIEW.INCOMING_CALL);
- } else {
- setPageView(PAGE_VIEW.OUTGOING_CALL);
- }
- break;
- case SipConstants.SESSION_ANSWERED:
- if (!!selectedConference) {
- setPageView(PAGE_VIEW.JOIN_CONFERENCE);
- } else {
- setPageView(PAGE_VIEW.DIAL_PAD);
- }
- break;
- case SipConstants.SESSION_ENDED:
- case SipConstants.SESSION_FAILED:
- setSelectedConference("");
- setPageView(PAGE_VIEW.DIAL_PAD);
- break;
- }
- }, [callStatus]);
-
- useEffect(() => {
- if (calledANumber) {
- if (
- !(
- calledANumber.startsWith("app-") ||
- calledANumber.startsWith("queue-") ||
- calledANumber.startsWith("conference-")
- )
- ) {
- setInputNumber(calledANumber);
- }
-
- setAppName(calledAName);
- makeOutboundCall(calledANumber, calledAName);
- setCalledANumber("");
- setCalledAName("");
- }
- }, [calledANumber]);
-
- useEffect(() => {
- if (status === "registered" || status === "disconnected") {
- setIsSwitchingUserStatus(false);
- setIsOnline(status === "registered");
- }
- }, [status]);
-
- useEffect(() => {
- const timer = setInterval(() => {
fetchRegisterUser();
- }, 10000);
- return () => {
- clearInterval(timer);
- };
- }, []);
-
- useEffect(() => {
- if (showAccounts) {
- document.addEventListener("mousedown", handleClickOutside);
- } else {
- document.removeEventListener("mousedown", handleClickOutside);
- }
-
- return () => {
- document.removeEventListener("mousedown", handleClickOutside);
- };
- }, [showAccounts]);
-
- const fetchRegisterUser = () => {
- getSelfRegisteredUser(sipUsernameRef.current)
- .then(({ json }) => {
- setRegisteredUser(json);
- })
- .catch((err) => {
- setRegisteredUser({
- allow_direct_app_calling: false,
- allow_direct_queue_calling: false,
- allow_direct_user_calling: false,
+ getConferences()
+ ?.then(() => {
+ setShowConference(true);
+ })
+ .catch(() => {
+ setShowConference(false);
});
+ }, [sipDomain, sipUsername, sipPassword, sipServerAddress, sipDisplayName]);
+
+ useEffect(() => {
+ setIsAdvancedMode(!!advancedSettings?.decoded?.accountSid);
+ fetchRegisterUser();
+ }, [advancedSettings]);
+
+ useEffect(() => {
+ inputNumberRef.current = inputNumber;
+ sessionDirectionRef.current = sessionDirection;
+ secondsRef.current = seconds;
+ }, [inputNumber, seconds, sessionDirection]);
+
+ useEffect(() => {
+ if (isSipClientIdle(callStatus) && isCallButtonLoading) {
+ setIsCallButtonLoading(false);
+ }
+ switch (callStatus) {
+ case SipConstants.SESSION_RINGING:
+ if (sessionDirection === "incoming") {
+ setPageView(PAGE_VIEW.INCOMING_CALL);
+ } else {
+ setPageView(PAGE_VIEW.OUTGOING_CALL);
+ }
+ break;
+ case SipConstants.SESSION_ANSWERED:
+ if (!!selectedConference) {
+ setPageView(PAGE_VIEW.JOIN_CONFERENCE);
+ } else {
+ setPageView(PAGE_VIEW.DIAL_PAD);
+ }
+ break;
+ case SipConstants.SESSION_ENDED:
+ case SipConstants.SESSION_FAILED:
+ setSelectedConference("");
+ setPageView(PAGE_VIEW.DIAL_PAD);
+ break;
+ }
+ }, [callStatus]);
+
+ useEffect(() => {
+ if (calledANumber) {
+ if (
+ !(
+ calledANumber.startsWith("app-") ||
+ calledANumber.startsWith("queue-") ||
+ calledANumber.startsWith("conference-")
+ )
+ ) {
+ setInputNumber(calledANumber);
+ }
+
+ setAppName(calledAName);
+ makeOutboundCall(calledANumber, calledAName);
+ setCalledANumber("");
+ setCalledAName("");
+ }
+ }, [calledANumber]);
+
+ useEffect(() => {
+ if (status === "registered" || status === "disconnected") {
+ setIsSwitchingUserStatus(false);
+ setIsOnline(status === "registered");
+ }
+ }, [status]);
+
+ useEffect(() => {
+ const timer = setInterval(() => {
+ fetchRegisterUser();
+ }, 10000);
+ return () => {
+ clearInterval(timer);
+ };
+ }, []);
+
+ useEffect(() => {
+ if (showAccounts) {
+ document.addEventListener("mousedown", handleClickOutside);
+ } else {
+ document.removeEventListener("mousedown", handleClickOutside);
+ }
+
+ return () => {
+ document.removeEventListener("mousedown", handleClickOutside);
+ };
+ }, [showAccounts]);
+
+ const fetchRegisterUser = () => {
+ getSelfRegisteredUser(sipUsernameRef.current)
+ .then(({ json }) => {
+ setRegisteredUser(json);
+ })
+ .catch((err) => {
+ setRegisteredUser({
+ allow_direct_app_calling: false,
+ allow_direct_queue_calling: false,
+ allow_direct_user_calling: false,
+ });
+ });
+ };
+
+ const startCallDurationCounter = () => {
+ stopCallDurationCounter();
+ timerRef.current = setInterval(() => {
+ setSeconds((seconds) => seconds + 1);
+ }, 1000);
+ };
+
+ const stopCallDurationCounter = () => {
+ if (timerRef.current) {
+ clearInterval(timerRef.current);
+ timerRef.current = null;
+ setSeconds(0);
+ }
+ };
+
+ const createSipClient = () => {
+ setIsSwitchingUserStatus(true);
+ const client = {
+ username: `${sipUsernameRef.current}@${sipDomainRef.current}`,
+ password: sipPasswordRef.current,
+ name: sipDisplayNameRef.current ?? sipUsernameRef.current,
+ };
+
+ const settings = {
+ pcConfig: {
+ iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }],
+ },
+ wsUri: sipServerAddressRef.current,
+ register: true,
+ };
+
+ const sipClient = new SipUA(client, settings);
+
+ // UA Status
+ sipClient.on(SipConstants.UA_REGISTERED, (args) => {
+ setStatus("registered");
+ });
+ sipClient.on(SipConstants.UA_UNREGISTERED, (args) => {
+ setStatus("unregistered");
+ if (sipUA.current) {
+ sipUA.current.stop();
+ }
+ unregisteredReasonRef.current = `User is not registered${
+ args.cause ? `, ${args.cause}` : ""
+ }`;
});
- };
- const startCallDurationCounter = () => {
- stopCallDurationCounter();
- timerRef.current = setInterval(() => {
- setSeconds((seconds) => seconds + 1);
- }, 1000);
- };
+ 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;
+ }
- const stopCallDurationCounter = () => {
- if (timerRef.current) {
- clearInterval(timerRef.current);
- timerRef.current = null;
- setSeconds(0);
+ if (args.error) {
+ toast({
+ title: `Cannot connect to ${sipServerAddress}, ${args.reason}`,
+ status: "warning",
+ duration: DEFAULT_TOAST_DURATION,
+ isClosable: true,
+ });
+ }
+ });
+ // Call Status
+ sipClient.on(SipConstants.SESSION_RINGING, (args) => {
+ if (args.session.direction === "incoming") {
+ saveCurrentCall({
+ number: args.session.user,
+ direction: args.session.direction,
+ timeStamp: Date.now(),
+ duration: "0",
+ callSid: uuidv4(),
+ });
+ }
+ setCallStatus(SipConstants.SESSION_RINGING);
+ setSessionDirection(args.session.direction);
+ setInputNumber(args.session.user);
+ });
+ sipClient.on(SipConstants.SESSION_ANSWERED, (args) => {
+ setCallSid(args.callSid);
+ const currentCall = getCurrentCall();
+ if (currentCall) {
+ currentCall.timeStamp = Date.now();
+ saveCurrentCall(currentCall);
+ }
+ setCallStatus(SipConstants.SESSION_ANSWERED);
+ startCallDurationCounter();
+ });
+ sipClient.on(SipConstants.SESSION_ENDED, (args) => {
+ addCallHistory();
+ setCallStatus(SipConstants.SESSION_ENDED);
+ setSessionDirection("");
+ stopCallDurationCounter();
+ });
+ sipClient.on(SipConstants.SESSION_FAILED, (args) => {
+ addCallHistory();
+ setCallStatus(SipConstants.SESSION_FAILED);
+ setSessionDirection("");
+ stopCallDurationCounter();
+ });
+
+ sipClient.start();
+ sipUA.current = sipClient;
+ };
+
+ const addCallHistory = () => {
+ const call = getCurrentCall();
+ if (call) {
+ saveCallHistory(sipUsername, {
+ number: call.number,
+ direction: call.direction,
+ duration: transform(Date.now(), call.timeStamp),
+ timeStamp: call.timeStamp,
+ callSid: call.callSid,
+ name: call.name,
+ });
+ }
+ deleteCurrentCall();
+ };
+
+ function transform(t1: number, t2: number) {
+ const diff = Math.abs(t1 - t2) / 1000; // Get the difference in seconds
+
+ const hours = Math.floor(diff / 3600);
+ const minutes = Math.floor((diff % 3600) / 60);
+ const seconds = Math.floor(diff % 60);
+
+ // Pad the values with a leading zero if they are less than 10
+ const hours1 = hours < 10 ? "0" + hours : hours;
+ const minutes1 = minutes < 10 ? "0" + minutes : minutes;
+ const seconds1 = seconds < 10 ? "0" + seconds : seconds;
+
+ return `${hours1}:${minutes1}:${seconds1}`;
}
- };
- const createSipClient = () => {
- setIsSwitchingUserStatus(true);
- const client = {
- username: `${sipUsernameRef.current}@${sipDomainRef.current}`,
- password: sipPasswordRef.current,
- name: sipDisplayNameRef.current ?? sipUsernameRef.current,
+ const handleDialPadClick = (value: string, fromKeyboad: boolean) => {
+ if (!(isInputNumberFocusRef.current && fromKeyboad)) {
+ setInputNumber((prev) => prev + value);
+ }
+
+ if (isSipClientAnswered(callStatus)) {
+ sipUA.current?.dtmf(value, undefined);
+ }
};
- const settings = {
- pcConfig: {
- iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }],
- },
- wsUri: sipServerAddressRef.current,
- register: true,
+ const handleCallButtion = () => {
+ makeOutboundCall(inputNumber);
};
- const sipClient = new SipUA(client, settings);
-
- // UA Status
- sipClient.on(SipConstants.UA_REGISTERED, (args) => {
- setStatus("registered");
- });
- sipClient.on(SipConstants.UA_UNREGISTERED, (args) => {
- 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: 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}`,
- status: "warning",
- duration: DEFAULT_TOAST_DURATION,
- isClosable: true,
- });
- }
- });
- // Call Status
- sipClient.on(SipConstants.SESSION_RINGING, (args) => {
- if (args.session.direction === "incoming") {
+ const makeOutboundCall = (number: string, name: string = "") => {
+ if (sipUA.current && number) {
+ setIsCallButtonLoading(true);
+ setCallStatus(SipConstants.SESSION_RINGING);
+ setSessionDirection("outgoing");
saveCurrentCall({
- number: args.session.user,
- direction: args.session.direction,
+ number: number,
+ name,
+ direction: "outgoing",
timeStamp: Date.now(),
duration: "0",
callSid: uuidv4(),
});
+ // Add custom header if this is special jambonz call
+ let customHeaders: string[] = [];
+ if (number.startsWith("app-")) {
+ customHeaders = [
+ `X-Application-Sid: ${number.substring(4, number.length)}`,
+ ];
+ }
+ sipUA.current.call(number, customHeaders);
}
- setCallStatus(SipConstants.SESSION_RINGING);
- setSessionDirection(args.session.direction);
- setInputNumber(args.session.user);
- });
- sipClient.on(SipConstants.SESSION_ANSWERED, (args) => {
- setCallSid(args.callSid);
- const currentCall = getCurrentCall();
- if (currentCall) {
- currentCall.timeStamp = Date.now();
- saveCurrentCall(currentCall);
+ };
+
+ const clientGoOffline = () => {
+ if (sipUA.current) {
+ sipUA.current.stop();
+ sipUA.current = null;
}
- setCallStatus(SipConstants.SESSION_ANSWERED);
- startCallDurationCounter();
- });
- sipClient.on(SipConstants.SESSION_ENDED, (args) => {
- addCallHistory();
- setCallStatus(SipConstants.SESSION_ENDED);
- setSessionDirection("");
- stopCallDurationCounter();
- });
- sipClient.on(SipConstants.SESSION_FAILED, (args) => {
- addCallHistory();
- setCallStatus(SipConstants.SESSION_FAILED);
- setSessionDirection("");
- stopCallDurationCounter();
- });
+ };
- sipClient.start();
- sipUA.current = sipClient;
- };
-
- const addCallHistory = () => {
- const call = getCurrentCall();
- if (call) {
- saveCallHistory(sipUsername, {
- number: call.number,
- direction: call.direction,
- duration: transform(Date.now(), call.timeStamp),
- timeStamp: call.timeStamp,
- callSid: call.callSid,
- name: call.name,
- });
- }
- deleteCurrentCall();
- };
-
- function transform(t1: number, t2: number) {
- const diff = Math.abs(t1 - t2) / 1000; // Get the difference in seconds
-
- const hours = Math.floor(diff / 3600);
- const minutes = Math.floor((diff % 3600) / 60);
- const seconds = Math.floor(diff % 60);
-
- // Pad the values with a leading zero if they are less than 10
- const hours1 = hours < 10 ? "0" + hours : hours;
- const minutes1 = minutes < 10 ? "0" + minutes : minutes;
- const seconds1 = seconds < 10 ? "0" + seconds : seconds;
-
- return `${hours1}:${minutes1}:${seconds1}`;
- }
-
- const handleDialPadClick = (value: string, fromKeyboad: boolean) => {
- if (!(isInputNumberFocusRef.current && fromKeyboad)) {
- setInputNumber((prev) => prev + value);
- }
-
- if (isSipClientAnswered(callStatus)) {
- sipUA.current?.dtmf(value, undefined);
- }
- };
-
- const handleCallButtion = () => {
- makeOutboundCall(inputNumber);
- };
-
- const makeOutboundCall = (number: string, name: string = "") => {
- if (sipUA.current && number) {
- setIsCallButtonLoading(true);
- setCallStatus(SipConstants.SESSION_RINGING);
- setSessionDirection("outgoing");
- saveCurrentCall({
- number: number,
- name,
- direction: "outgoing",
- timeStamp: Date.now(),
- duration: "0",
- callSid: uuidv4(),
- });
- // Add custom header if this is special jambonz call
- let customHeaders: string[] = [];
- if (number.startsWith("app-")) {
- customHeaders = [
- `X-Application-Sid: ${number.substring(4, number.length)}`,
- ];
+ const handleHangup = () => {
+ if (isSipClientAnswered(callStatus) || isSipClientRinging(callStatus)) {
+ sipUA.current?.terminate(480, "Call Finished", undefined);
}
- sipUA.current.call(number, customHeaders);
- }
- };
+ };
- const clientGoOffline = () => {
- if (sipUA.current) {
- sipUA.current.stop();
- sipUA.current = null;
- }
- };
-
- const handleHangup = () => {
- if (isSipClientAnswered(callStatus) || isSipClientRinging(callStatus)) {
- sipUA.current?.terminate(480, "Call Finished", undefined);
- }
- };
-
- const handleCallOnHold = () => {
- if (isSipClientAnswered(callStatus)) {
- if (sipUA.current?.isHolded(undefined)) {
- sipUA.current?.unhold(undefined);
- } else {
- sipUA.current?.hold(undefined);
+ const handleCallOnHold = () => {
+ if (isSipClientAnswered(callStatus)) {
+ if (sipUA.current?.isHolded(undefined)) {
+ sipUA.current?.unhold(undefined);
+ } else {
+ sipUA.current?.hold(undefined);
+ }
}
- }
- };
+ };
- const handleCallMute = () => {
- if (isSipClientAnswered(callStatus)) {
- if (sipUA.current?.isMuted(undefined)) {
- sipUA.current?.unmute(undefined);
- } else {
- sipUA.current?.mute(undefined);
+ const handleCallMute = () => {
+ if (isSipClientAnswered(callStatus)) {
+ if (sipUA.current?.isMuted(undefined)) {
+ sipUA.current?.unmute(undefined);
+ } else {
+ sipUA.current?.mute(undefined);
+ }
}
- }
- };
+ };
- const handleAnswer = () => {
- if (isSipClientRinging(callStatus)) {
- sipUA.current?.answer(undefined);
- }
- };
+ const handleAnswer = () => {
+ if (isSipClientRinging(callStatus)) {
+ sipUA.current?.answer(undefined);
+ }
+ };
- const handleDecline = () => {
- if (isSipClientRinging(callStatus)) {
- sipUA.current?.terminate(486, "Busy here", undefined);
- }
- };
+ const handleDecline = () => {
+ if (isSipClientRinging(callStatus)) {
+ sipUA.current?.terminate(486, "Busy here", undefined);
+ }
+ };
- const isStatusRegistered = () => {
- return status === "registered";
- };
+ const isStatusRegistered = () => {
+ return status === "registered";
+ };
- const handleSetActive = (id: number) => {
- setActiveSettings(id);
- setShowAccounts(false);
- // fetchRegisterUser();
- reload();
- };
-
- const handleClickOutside = (event: Event) => {
- const target = event.target as Node;
- if (accountsCardRef.current && !accountsCardRef.current.contains(target)) {
+ const handleSetActive = (id: number) => {
+ setActiveSettings(id);
setShowAccounts(false);
- }
- };
- return (
-
- {allSettings.length >= 1 ? (
- <>
-
- Account
-
-
- {
- setShowAccounts(true)}
- _hover={{
- cursor: "pointer",
- }}
- spacing={2}
- boxShadow="md"
- w="full"
- borderRadius={5}
- paddingY={2}
- paddingX={3.5}
- >
- {sipUsername && sipDomain ? (
- <>
-
-
-
-
- {sipDisplayName || sipUsername}
-
-
-
-
- {`${sipUsername}@${sipDomain}`}
-
-
+ reload();
+ };
-
-
-
-
- >
- ) : (
- Select Account
+ const handleClickOutside = (event: Event) => {
+ const target = event.target as Node;
+ if (
+ accountsCardRef.current &&
+ !accountsCardRef.current.contains(target)
+ ) {
+ setShowAccounts(false);
+ }
+ };
+
+ return (
+
+ {allSettings.length >= 1 ? (
+ <>
+
+ Account
+
+
+ {
+ setShowAccounts(true)}
+ _hover={{
+ cursor: "pointer",
+ }}
+ spacing={2}
+ boxShadow="md"
+ w="full"
+ borderRadius={5}
+ paddingY={2}
+ paddingX={3.5}
+ >
+ {sipUsername && sipDomain ? (
+ <>
+
+
+
+
+ {sipDisplayName || sipUsername}
+
+
+
+
+ {`${sipUsername}@${sipDomain}`}
+
+
+
+
+
+
+
+ >
+ ) : (
+ Select Account
+ )}
+
+ }
+ {showAccounts && (
+
+
+
+ )}
+
+ >
+ ) : (
+
+ Go to Settings to configure your account
+
+ )}
+ {pageView === PAGE_VIEW.DIAL_PAD && (
+
+ {isAdvanceMode && isSipClientIdle(callStatus) && (
+
+ {registeredUser.allow_direct_user_calling && (
+ }
+ tooltip="Call an online user"
+ noResultLabel="No one else is online"
+ onClick={(_, value) => {
+ setInputNumber(value);
+ makeOutboundCall(value);
+ }}
+ onOpen={() => {
+ return new Promise(
+ (resolve, reject) => {
+ getRegisteredUser()
+ .then(({ json }) => {
+ const sortedUsers = json.sort((a, b) =>
+ a.localeCompare(b)
+ );
+ resolve(
+ sortedUsers
+ .filter((u) => !u.includes(sipUsername))
+ .map((u) => {
+ const uName = u.match(/(^.*)@.*/);
+ return {
+ name: uName ? uName[1] : u,
+ value: uName ? uName[1] : u,
+ };
+ })
+ );
+ })
+ .catch((err) => reject(err));
+ }
+ );
+ }}
+ />
+ )}
+
+ {registeredUser.allow_direct_queue_calling && (
+ }
+ tooltip="Take a call from queue"
+ noResultLabel="No calls in queue"
+ onClick={(name, value) => {
+ setAppName(`Queue ${name}`);
+ const calledQueue = `queue-${value}`;
+ setInputNumber("");
+ makeOutboundCall(calledQueue, `Queue ${name}`);
+ }}
+ onOpen={() => {
+ return new Promise(
+ (resolve, reject) => {
+ getQueues()
+ .then(({ json }) => {
+ const sortedQueues = json.sort((a, b) =>
+ a.name.localeCompare(b.name)
+ );
+ resolve(
+ sortedQueues.map((q) => ({
+ name: `${q.name} (${q.length})`,
+ value: q.name,
+ }))
+ );
+ })
+ .catch((err) => reject(err));
+ }
+ );
+ }}
+ />
+ )}
+
+ {registeredUser.allow_direct_app_calling && (
+ }
+ tooltip="Call an application"
+ noResultLabel="No applications"
+ onClick={(name, value) => {
+ setAppName(`App ${name}`);
+ const calledAppId = `app-${value}`;
+ setInputNumber("");
+ makeOutboundCall(calledAppId, `App ${name}`);
+ }}
+ onOpen={() => {
+ return new Promise(
+ (resolve, reject) => {
+ getApplications()
+ .then(({ json }) => {
+ const sortedApps = json.sort((a, b) =>
+ a.name.localeCompare(b.name)
+ );
+ resolve(
+ sortedApps.map((a) => ({
+ name: a.name,
+ value: a.application_sid,
+ }))
+ );
+ })
+ .catch((err) => reject(err));
+ }
+ );
+ }}
+ />
+ )}
+ {registeredUser.allow_direct_app_calling && showConference && (
+ }
+ tooltip="Join a conference"
+ noResultLabel="No conference"
+ onClick={(name, value) => {
+ setPageView(PAGE_VIEW.JOIN_CONFERENCE);
+ setSelectedConference(
+ value === PAGE_VIEW.JOIN_CONFERENCE.toString()
+ ? ""
+ : value
+ );
+ }}
+ onOpen={() => {
+ return new Promise(
+ (resolve, reject) => {
+ getConferences()
+ .then(({ json }) => {
+ const sortedApps = json.sort((a, b) =>
+ a.localeCompare(b)
+ );
+ resolve([
+ {
+ name: "Start new conference",
+ value: PAGE_VIEW.JOIN_CONFERENCE.toString(),
+ },
+ ...sortedApps.map((a) => ({
+ name: a,
+ value: a,
+ })),
+ ]);
+ })
+ .catch((err) => reject(err));
+ }
+ );
+ }}
+ />
)}
- }
- {showAccounts && (
-
-
-
)}
-
- >
- ) : (
-
- Go to Settings to configure your account
-
- )}
- {pageView === PAGE_VIEW.DIAL_PAD && (
-
- {isAdvanceMode && isSipClientIdle(callStatus) && (
-
- {registeredUser.allow_direct_user_calling && (
- }
- tooltip="Call an online user"
- noResultLabel="No one else is online"
- onClick={(_, value) => {
- setInputNumber(value);
- makeOutboundCall(value);
- }}
- onOpen={() => {
- return new Promise(
- (resolve, reject) => {
- getRegisteredUser()
- .then(({ json }) => {
- const sortedUsers = json.sort((a, b) =>
- a.localeCompare(b)
- );
- resolve(
- sortedUsers
- .filter((u) => !u.includes(sipUsername))
- .map((u) => {
- const uName = u.match(/(^.*)@.*/);
- return {
- name: uName ? uName[1] : u,
- value: uName ? uName[1] : u,
- };
- })
- );
- })
- .catch((err) => reject(err));
- }
- );
- }}
- />
- )}
- {registeredUser.allow_direct_queue_calling && (
- }
- tooltip="Take a call from queue"
- noResultLabel="No calls in queue"
- onClick={(name, value) => {
- setAppName(`Queue ${name}`);
- const calledQueue = `queue-${value}`;
- setInputNumber("");
- makeOutboundCall(calledQueue, `Queue ${name}`);
- }}
- onOpen={() => {
- return new Promise(
- (resolve, reject) => {
- getQueues()
- .then(({ json }) => {
- const sortedQueues = json.sort((a, b) =>
- a.name.localeCompare(b.name)
- );
- resolve(
- sortedQueues.map((q) => ({
- name: `${q.name} (${q.length})`,
- value: q.name,
- }))
- );
- })
- .catch((err) => reject(err));
- }
- );
- }}
- />
- )}
+ {
+ setInputNumber(e.target.value);
+ }}
+ onFocus={() => {
+ isInputNumberFocusRef.current = true;
+ }}
+ onBlur={() => {
+ isInputNumberFocusRef.current = false;
+ }}
+ textAlign="center"
+ isReadOnly={!isSipClientIdle(callStatus)}
+ />
- {registeredUser.allow_direct_app_calling && (
- }
- tooltip="Call an application"
- noResultLabel="No applications"
- onClick={(name, value) => {
- setAppName(`App ${name}`);
- const calledAppId = `app-${value}`;
- setInputNumber("");
- makeOutboundCall(calledAppId, `App ${name}`);
- }}
- onOpen={() => {
- return new Promise(
- (resolve, reject) => {
- getApplications()
- .then(({ json }) => {
- const sortedApps = json.sort((a, b) =>
- a.name.localeCompare(b.name)
- );
- resolve(
- sortedApps.map((a) => ({
- name: a.name,
- value: a.application_sid,
- }))
- );
- })
- .catch((err) => reject(err));
- }
- );
- }}
- />
- )}
- {registeredUser.allow_direct_app_calling && showConference && (
- }
- tooltip="Join a conference"
- noResultLabel="No conference"
- onClick={(name, value) => {
- setPageView(PAGE_VIEW.JOIN_CONFERENCE);
- setSelectedConference(
- value === PAGE_VIEW.JOIN_CONFERENCE.toString()
- ? ""
- : value
- );
- }}
- onOpen={() => {
- return new Promise(
- (resolve, reject) => {
- getConferences()
- .then(({ json }) => {
- const sortedApps = json.sort((a, b) =>
- a.localeCompare(b)
- );
- resolve([
- {
- name: "Start new conference",
- value: PAGE_VIEW.JOIN_CONFERENCE.toString(),
- },
- ...sortedApps.map((a) => ({
- name: a,
- value: a,
- })),
- ]);
- })
- .catch((err) => reject(err));
- }
- );
- }}
- />
- )}
-
- )}
+ {!isSipClientIdle(callStatus) && seconds >= 0 && (
+
+ {new Date(seconds * 1000).toISOString().substr(11, 8)}
+
+ )}
- {
- setInputNumber(e.target.value);
- }}
- onFocus={() => {
- isInputNumberFocusRef.current = true;
- }}
- onBlur={() => {
- isInputNumberFocusRef.current = false;
- }}
- textAlign="center"
- isReadOnly={!isSipClientIdle(callStatus)}
- />
+
- {!isSipClientIdle(callStatus) && seconds >= 0 && (
-
- {new Date(seconds * 1000).toISOString().substr(11, 8)}
-
- )}
-
-
-
- {isSipClientIdle(callStatus) ? (
-
- ) : (
-
-
-
- }
- w="33%"
- variant="unstyled"
- display="flex"
- alignItems="center"
- justifyContent="center"
- onClick={handleCallOnHold}
- />
-
-
-
- }
- w="70px"
- h="70px"
- borderRadius="100%"
+ {isSipClientIdle(callStatus) ? (
+
-
-
+ Call
+
+ ) : (
+
+
+
+ }
+ w="33%"
+ variant="unstyled"
+ display="flex"
+ alignItems="center"
+ justifyContent="center"
+ onClick={handleCallOnHold}
+ />
+
+
+
- }
- w="33%"
- variant="unstyled"
- display="flex"
- alignItems="center"
- justifyContent="center"
- onClick={handleCallMute}
+ aria-label="Hangup"
+ icon={}
+ w="70px"
+ h="70px"
+ borderRadius="100%"
+ colorScheme="jambonz"
+ onClick={handleHangup}
/>
-
-
- )}
-
- )}
- {pageView === PAGE_VIEW.INCOMING_CALL && (
-
- )}
- {pageView === PAGE_VIEW.OUTGOING_CALL && (
-
- )}
- {pageView === PAGE_VIEW.JOIN_CONFERENCE && (
- {
- if (isSipClientAnswered(callStatus)) {
- sipUA.current?.terminate(480, "Call Finished", undefined);
- }
- setPageView(PAGE_VIEW.DIAL_PAD);
- }}
- call={(name) => {
- const conference = `conference-${name}`;
- setSelectedConference(name);
- setInputNumber(conference);
- makeOutboundCall(conference, `Conference ${name}`);
- }}
- />
- )}
-
- );
-};
+
+
+
+ }
+ w="33%"
+ variant="unstyled"
+ display="flex"
+ alignItems="center"
+ justifyContent="center"
+ onClick={handleCallMute}
+ />
+
+
+ )}
+
+ )}
+ {pageView === PAGE_VIEW.INCOMING_CALL && (
+
+ )}
+ {pageView === PAGE_VIEW.OUTGOING_CALL && (
+
+ )}
+ {pageView === PAGE_VIEW.JOIN_CONFERENCE && (
+ {
+ if (isSipClientAnswered(callStatus)) {
+ sipUA.current?.terminate(480, "Call Finished", undefined);
+ }
+ setPageView(PAGE_VIEW.DIAL_PAD);
+ }}
+ call={(name) => {
+ const conference = `conference-${name}`;
+ setSelectedConference(name);
+ setInputNumber(conference);
+ makeOutboundCall(conference, `Conference ${name}`);
+ }}
+ />
+ )}
+
+ );
+ }
+);
export default Phone;
diff --git a/src/window/settings/accordionList.tsx b/src/window/settings/accordionList.tsx
index ac6b103..034ca2e 100644
--- a/src/window/settings/accordionList.tsx
+++ b/src/window/settings/accordionList.tsx
@@ -38,7 +38,6 @@ export function AccordionList({
if (isNewFormOpen) handleCloseNewForm(); //closes new form if open
handleOpenFormInAccordion();
setOpenAcc(accIndex);
- // onToggle();
onOpen();
}
return (
diff --git a/src/window/settings/accountForm.tsx b/src/window/settings/accountForm.tsx
index e11cee4..65ee232 100644
--- a/src/window/settings/accountForm.tsx
+++ b/src/window/settings/accountForm.tsx
@@ -17,9 +17,7 @@ import { AppSettings, IAppSettings } from "src/common/types";
import PasswordInput from "src/components/password-input";
import { deleteSettings, editSettings, saveSettings } from "src/storage";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import {
- faCheckCircle
-} from "@fortawesome/free-solid-svg-icons";
+import { faCheckCircle } from "@fortawesome/free-solid-svg-icons";
import { normalizeUrl } from "src/utils";
import { getAdvancedValidation } from "src/api";
import Switch from "src/imgs/icons/Switch.svg";
@@ -81,7 +79,6 @@ function AccountForm({
);
const checkCredential = (apiServer: string, accountSid: string) => {
- // getApplications()
getAdvancedValidation(apiServer, accountSid)
.then(() => {
setIsCredentialOk(true);
diff --git a/src/window/settings/index.tsx b/src/window/settings/index.tsx
index 44eea6b..51a826c 100644
--- a/src/window/settings/index.tsx
+++ b/src/window/settings/index.tsx
@@ -55,14 +55,9 @@ export const Settings = () => {