cleaned commented code, moved SipUA as requested and added outbound call fix.

This commit is contained in:
aramide ramadan
2024-09-09 14:50:05 +01:00
parent a713b1b3a1
commit 1f2dbaa1df
10 changed files with 800 additions and 940 deletions

View File

@@ -4,12 +4,6 @@
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap"
rel="stylesheet"
/> -->
<meta name="theme-color" content="#000000" />
<meta
name="description"

View File

@@ -67,7 +67,7 @@ export default class SipSession extends events.EventEmitter {
({ response }: { response: IncomingResponse }) => {
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,
});

View File

@@ -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) => {

View File

@@ -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;
}

View File

@@ -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<IAppSettings | null>(
null
);
const sipUA = useRef<SipUA | null>(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: (
<Phone
ref={phoneSipAschildRef}
sipUsername={sipUsername}
sipPassword={sipPassword}
sipDomain={sipDomain}
@@ -67,7 +82,6 @@ export const WindowApp = () => {
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}
/>
</Grid>
);

View File

@@ -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<SetStateAction<SipClientStatus>>;
@@ -32,135 +30,24 @@ function Footer({
setIsSwitchingUserStatus: React.Dispatch<React.SetStateAction<boolean>>;
isOnline: boolean;
setIsOnline: React.Dispatch<React.SetStateAction<boolean>>;
sipUA: React.MutableRefObject<SipUA | null>;
onHandleGoOffline: (s: SipClientStatus) => void;
}) {
const [isConfigured, setIsConfigured] = useState(false);
// const sipUA = useRef<SipUA | null>(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 (
<HStack
@@ -176,7 +63,7 @@ function Footer({
checked={[isOnline, setIsOnline]}
onChange={(v) => {
setIsSwitchingUserStatus(true);
handleGoOffline(v ? "registered" : "unregistered");
onHandleGoOffline(v ? "registered" : "unregistered");
}}
/>
<Text>You are {isOnline ? "online" : "offline"}</Text>

File diff suppressed because it is too large Load Diff

View File

@@ -38,7 +38,6 @@ export function AccordionList({
if (isNewFormOpen) handleCloseNewForm(); //closes new form if open
handleOpenFormInAccordion();
setOpenAcc(accIndex);
// onToggle();
onOpen();
}
return (

View File

@@ -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);

View File

@@ -55,14 +55,9 @@ export const Settings = () => {
<Button
marginY={"3"}
colorScheme="jambonz"
// bg={btnIsDisabled ? "jambonz.0" : "jambonz.500"}
// textColor={btnIsDisabled ? "jambonz.550" : "white"}
w="full"
onClick={handleOpenForm}
isDisabled={btnIsDisabled}
// _hover={{
// bg={btnIsDisabled ? "jambonz.0" : "jambonz.500"}
// }}
>
Add Account
</Button>