mirror of
https://github.com/jambonz/chrome-extension-dialer.git
synced 2026-01-25 02:08:05 +00:00
wip
This commit is contained in:
@@ -201,19 +201,19 @@ export default class SipSession extends events.EventEmitter {
|
|||||||
direction: this.#rtcSession.direction,
|
direction: this.#rtcSession.direction,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
pc.addEventListener(
|
// pc.addEventListener(
|
||||||
"track",
|
// "track",
|
||||||
(event: RTCPeerConnectionEventMap["track"]): void => {
|
// (event: RTCPeerConnectionEventMap["track"]): void => {
|
||||||
const stream: MediaStream = new MediaStream([event.track]);
|
// const stream: MediaStream = new MediaStream([event.track]);
|
||||||
if (this.#rtcSession.direction === "outgoing") {
|
// if (this.#rtcSession.direction === "outgoing") {
|
||||||
this.#audio.pauseRinging();
|
// this.#audio.pauseRinging();
|
||||||
}
|
// }
|
||||||
this.#audio.playRemote(stream);
|
// this.#audio.playRemote(stream);
|
||||||
this.emit(SipConstants.SESSION_TRACK, {
|
// this.emit(SipConstants.SESSION_TRACK, {
|
||||||
direction: this.#rtcSession.direction,
|
// direction: this.#rtcSession.direction,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
get rtcSession() {
|
get rtcSession() {
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ import {
|
|||||||
faUserGroup,
|
faUserGroup,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import NewConference from "./new-conference";
|
|
||||||
import JoinConference from "./join-conference";
|
import JoinConference from "./join-conference";
|
||||||
|
|
||||||
type PhoneProbs = {
|
type PhoneProbs = {
|
||||||
@@ -80,7 +79,6 @@ enum PAGE_VIEW {
|
|||||||
DIAL_PAD,
|
DIAL_PAD,
|
||||||
INCOMING_CALL,
|
INCOMING_CALL,
|
||||||
OUTGOING_CALL,
|
OUTGOING_CALL,
|
||||||
START_NEW_CONFERENCE,
|
|
||||||
JOIN_CONFERENCE,
|
JOIN_CONFERENCE,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,29 +94,16 @@ export const Phone = ({
|
|||||||
}: PhoneProbs) => {
|
}: PhoneProbs) => {
|
||||||
const [inputNumber, setInputNumber] = useState("");
|
const [inputNumber, setInputNumber] = useState("");
|
||||||
const [appName, setAppName] = useState("");
|
const [appName, setAppName] = useState("");
|
||||||
const inputNumberRef = useRef(inputNumber);
|
|
||||||
const [status, setStatus] = useState<SipClientStatus>("stop");
|
const [status, setStatus] = useState<SipClientStatus>("stop");
|
||||||
const [isConfigured, setIsConfigured] = useState(false);
|
const [isConfigured, setIsConfigured] = useState(false);
|
||||||
const [callStatus, setCallStatus] = useState(SipConstants.SESSION_ENDED);
|
const [callStatus, setCallStatus] = useState(SipConstants.SESSION_ENDED);
|
||||||
const [sessionDirection, setSessionDirection] =
|
const [sessionDirection, setSessionDirection] =
|
||||||
useState<SipCallDirection>("");
|
useState<SipCallDirection>("");
|
||||||
const sessionDirectionRef = useRef(sessionDirection);
|
|
||||||
const sipUA = useRef<SipUA | null>(null);
|
|
||||||
const timerRef = useRef<NodeJS.Timer | null>(null);
|
|
||||||
const [seconds, setSeconds] = useState(0);
|
const [seconds, setSeconds] = useState(0);
|
||||||
const secondsRef = useRef(seconds);
|
|
||||||
const [isCallButtonLoading, setIsCallButtonLoading] = useState(false);
|
const [isCallButtonLoading, setIsCallButtonLoading] = useState(false);
|
||||||
const [isAdvanceMode, setIsAdvancedMode] = useState(false);
|
const [isAdvanceMode, setIsAdvancedMode] = useState(false);
|
||||||
const isRestartRef = useRef(false);
|
|
||||||
const sipDomainRef = useRef("");
|
|
||||||
const sipUsernameRef = useRef("");
|
|
||||||
const sipPasswordRef = useRef("");
|
|
||||||
const sipServerAddressRef = useRef("");
|
|
||||||
const sipDisplayNameRef = useRef("");
|
|
||||||
const [isSwitchingUserStatus, setIsSwitchingUserStatus] = useState(true);
|
const [isSwitchingUserStatus, setIsSwitchingUserStatus] = useState(true);
|
||||||
const [isOnline, setIsOnline] = useState(false);
|
const [isOnline, setIsOnline] = useState(false);
|
||||||
const unregisteredReasonRef = useRef("");
|
|
||||||
const isInputNumberFocusRef = useRef(false);
|
|
||||||
const [pageView, setPageView] = useState<PAGE_VIEW>(PAGE_VIEW.DIAL_PAD);
|
const [pageView, setPageView] = useState<PAGE_VIEW>(PAGE_VIEW.DIAL_PAD);
|
||||||
const [registeredUser, setRegisteredUser] = useState<Partial<RegisteredUser>>(
|
const [registeredUser, setRegisteredUser] = useState<Partial<RegisteredUser>>(
|
||||||
{
|
{
|
||||||
@@ -127,7 +112,23 @@ export const Phone = ({
|
|||||||
allow_direct_user_calling: false,
|
allow_direct_user_calling: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const callSidRef = useRef("");
|
const [selectedConference, setSelectedConference] = useState("");
|
||||||
|
const [callSid, setCallSid] = useState("");
|
||||||
|
|
||||||
|
const inputNumberRef = useRef(inputNumber);
|
||||||
|
const sessionDirectionRef = useRef(sessionDirection);
|
||||||
|
const sipUA = useRef<SipUA | null>(null);
|
||||||
|
const timerRef = useRef<NodeJS.Timer | null>(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 toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -170,15 +171,27 @@ export const Phone = ({
|
|||||||
if (isSipClientIdle(callStatus) && isCallButtonLoading) {
|
if (isSipClientIdle(callStatus) && isCallButtonLoading) {
|
||||||
setIsCallButtonLoading(false);
|
setIsCallButtonLoading(false);
|
||||||
}
|
}
|
||||||
if (isSipClientRinging(callStatus)) {
|
switch (callStatus) {
|
||||||
|
case SipConstants.SESSION_RINGING:
|
||||||
if (sessionDirection === "incoming") {
|
if (sessionDirection === "incoming") {
|
||||||
setPageView(PAGE_VIEW.INCOMING_CALL);
|
setPageView(PAGE_VIEW.INCOMING_CALL);
|
||||||
} else {
|
} else {
|
||||||
setPageView(PAGE_VIEW.OUTGOING_CALL);
|
setPageView(PAGE_VIEW.OUTGOING_CALL);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case SipConstants.SESSION_ANSWERED:
|
||||||
|
if (!!selectedConference) {
|
||||||
|
setPageView(PAGE_VIEW.JOIN_CONFERENCE);
|
||||||
} else {
|
} else {
|
||||||
setPageView(PAGE_VIEW.DIAL_PAD);
|
setPageView(PAGE_VIEW.DIAL_PAD);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case SipConstants.SESSION_ENDED:
|
||||||
|
case SipConstants.SESSION_FAILED:
|
||||||
|
setSelectedConference("");
|
||||||
|
setPageView(PAGE_VIEW.DIAL_PAD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}, [callStatus]);
|
}, [callStatus]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -316,7 +329,7 @@ export const Phone = ({
|
|||||||
setInputNumber(args.session.user);
|
setInputNumber(args.session.user);
|
||||||
});
|
});
|
||||||
sipClient.on(SipConstants.SESSION_ANSWERED, (args) => {
|
sipClient.on(SipConstants.SESSION_ANSWERED, (args) => {
|
||||||
callSidRef.current = args.callSid;
|
setCallSid(args.callSid);
|
||||||
const currentCall = getCurrentCall();
|
const currentCall = getCurrentCall();
|
||||||
if (currentCall) {
|
if (currentCall) {
|
||||||
currentCall.timeStamp = Date.now();
|
currentCall.timeStamp = Date.now();
|
||||||
@@ -634,11 +647,10 @@ export const Phone = ({
|
|||||||
tooltip="Join a conference"
|
tooltip="Join a conference"
|
||||||
noResultLabel="No conference"
|
noResultLabel="No conference"
|
||||||
onClick={(name, value) => {
|
onClick={(name, value) => {
|
||||||
if (value === PAGE_VIEW.START_NEW_CONFERENCE.toString()) {
|
|
||||||
setPageView(PAGE_VIEW.START_NEW_CONFERENCE);
|
|
||||||
} else {
|
|
||||||
setPageView(PAGE_VIEW.JOIN_CONFERENCE);
|
setPageView(PAGE_VIEW.JOIN_CONFERENCE);
|
||||||
}
|
setSelectedConference(
|
||||||
|
value === PAGE_VIEW.JOIN_CONFERENCE.toString() ? "" : value
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
onOpen={() => {
|
onOpen={() => {
|
||||||
return new Promise<IconButtonMenuItems[]>(
|
return new Promise<IconButtonMenuItems[]>(
|
||||||
@@ -651,7 +663,7 @@ export const Phone = ({
|
|||||||
resolve([
|
resolve([
|
||||||
{
|
{
|
||||||
name: "Start new conference",
|
name: "Start new conference",
|
||||||
value: PAGE_VIEW.START_NEW_CONFERENCE.toString(),
|
value: PAGE_VIEW.JOIN_CONFERENCE.toString(),
|
||||||
},
|
},
|
||||||
...sortedApps.map((a) => ({
|
...sortedApps.map((a) => ({
|
||||||
name: a,
|
name: a,
|
||||||
@@ -779,15 +791,14 @@ export const Phone = ({
|
|||||||
)}
|
)}
|
||||||
{pageView === PAGE_VIEW.JOIN_CONFERENCE && (
|
{pageView === PAGE_VIEW.JOIN_CONFERENCE && (
|
||||||
<JoinConference
|
<JoinConference
|
||||||
|
conferenceId={selectedConference}
|
||||||
|
callSid={callSid}
|
||||||
handleCancel={() => {
|
handleCancel={() => {
|
||||||
setPageView(PAGE_VIEW.DIAL_PAD);
|
setPageView(PAGE_VIEW.DIAL_PAD);
|
||||||
}}
|
}}
|
||||||
/>
|
call={(name) => {
|
||||||
)}
|
setSelectedConference(name);
|
||||||
{pageView === PAGE_VIEW.START_NEW_CONFERENCE && (
|
sipUA.current?.call(`conf:${name}`);
|
||||||
<NewConference
|
|
||||||
handleCancel={() => {
|
|
||||||
setPageView(PAGE_VIEW.DIAL_PAD);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -9,23 +9,41 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
VStack,
|
VStack,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { FormEvent } from "react";
|
import { FormEvent, useState } from "react";
|
||||||
import OutlineBox from "src/components/outline-box";
|
import OutlineBox from "src/components/outline-box";
|
||||||
|
|
||||||
type JoinConferenceProbs = {
|
type JoinConferenceProbs = {
|
||||||
|
conferenceId?: string;
|
||||||
|
callSid: string;
|
||||||
handleCancel: () => void;
|
handleCancel: () => void;
|
||||||
|
call: (conference: string) => void;
|
||||||
};
|
};
|
||||||
export const JoinConference = ({ handleCancel }: JoinConferenceProbs) => {
|
export const JoinConference = ({
|
||||||
|
conferenceId,
|
||||||
|
handleCancel,
|
||||||
|
call,
|
||||||
|
}: JoinConferenceProbs) => {
|
||||||
|
const [conferenceName, setConferenceName] = useState(conferenceId || "");
|
||||||
const handleSubmit = (e: FormEvent) => {
|
const handleSubmit = (e: FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
call(conferenceName);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Box as="form" onSubmit={handleSubmit} w="full">
|
<Box as="form" onSubmit={handleSubmit} w="full">
|
||||||
<VStack spacing={4} mt="20px" w="full">
|
<VStack spacing={4} mt="20px" w="full">
|
||||||
<Text fontWeight="bold">Joining conference</Text>
|
<Text fontWeight="bold">
|
||||||
|
{!!conferenceId ? "Joining" : "Start"} conference
|
||||||
|
</Text>
|
||||||
<FormControl id="conference_name">
|
<FormControl id="conference_name">
|
||||||
<FormLabel>Conference name</FormLabel>
|
<FormLabel>Conference name</FormLabel>
|
||||||
<Input type="text" placeholder="Name" isRequired />
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="Name"
|
||||||
|
isRequired
|
||||||
|
value={conferenceName}
|
||||||
|
onChange={(e) => setConferenceName(e.target.value)}
|
||||||
|
disabled={!!conferenceId}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
<OutlineBox title="Join as">
|
<OutlineBox title="Join as">
|
||||||
@@ -35,17 +53,17 @@ export const JoinConference = ({ handleCancel }: JoinConferenceProbs) => {
|
|||||||
|
|
||||||
<FormControl id="speak_only_to">
|
<FormControl id="speak_only_to">
|
||||||
<FormLabel>Speak only to</FormLabel>
|
<FormLabel>Speak only to</FormLabel>
|
||||||
<Input type="text" placeholder="agent" isRequired />
|
<Input type="text" placeholder="agent" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
<FormControl id="tag">
|
<FormControl id="tag">
|
||||||
<FormLabel>Tag</FormLabel>
|
<FormLabel>Tag</FormLabel>
|
||||||
<Input type="text" placeholder="tags" isRequired />
|
<Input type="text" placeholder="tags" />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</OutlineBox>
|
</OutlineBox>
|
||||||
<HStack w="full">
|
<HStack w="full">
|
||||||
<Button colorScheme="jambonz" type="submit" w="full">
|
<Button colorScheme="jambonz" type="submit" w="full">
|
||||||
Start Conference
|
{!!conferenceId ? "Join conference" : "Start conference"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
import {
|
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
Checkbox,
|
|
||||||
FormControl,
|
|
||||||
FormLabel,
|
|
||||||
HStack,
|
|
||||||
Input,
|
|
||||||
Text,
|
|
||||||
VStack,
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
import { FormEvent } from "react";
|
|
||||||
import OutlineBox from "src/components/outline-box";
|
|
||||||
|
|
||||||
type NewConferenceProbs = {
|
|
||||||
handleCancel: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const NewConference = ({ handleCancel }: NewConferenceProbs) => {
|
|
||||||
const handleSubmit = (e: FormEvent) => {
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Box as="form" onSubmit={handleSubmit} w="full">
|
|
||||||
<VStack spacing={4} mt="20px" w="full">
|
|
||||||
<Text fontWeight="bold" fontSize="2xl">
|
|
||||||
Start new conference
|
|
||||||
</Text>
|
|
||||||
<FormControl id="conference_name">
|
|
||||||
<FormLabel>Conference name</FormLabel>
|
|
||||||
<Input type="text" placeholder="Name" isRequired />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<OutlineBox title="Join as">
|
|
||||||
<Checkbox colorScheme="jambonz">Full participant</Checkbox>
|
|
||||||
<Checkbox colorScheme="jambonz">Muted</Checkbox>
|
|
||||||
<Checkbox colorScheme="jambonz">Coach mode</Checkbox>
|
|
||||||
|
|
||||||
<FormControl id="speak_only_to">
|
|
||||||
<FormLabel>Speak only to</FormLabel>
|
|
||||||
<Input type="text" placeholder="agent" isRequired />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormControl id="tag">
|
|
||||||
<FormLabel>Tag</FormLabel>
|
|
||||||
<Input type="text" placeholder="tags" isRequired />
|
|
||||||
</FormControl>
|
|
||||||
</OutlineBox>
|
|
||||||
<HStack w="full">
|
|
||||||
<Button colorScheme="jambonz" type="submit" w="full">
|
|
||||||
Start Conference
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
colorScheme="grey"
|
|
||||||
type="button"
|
|
||||||
w="full"
|
|
||||||
textColor="black"
|
|
||||||
onClick={handleCancel}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</HStack>
|
|
||||||
</VStack>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default NewConference;
|
|
||||||
Reference in New Issue
Block a user