Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Logo } from "@components/Icons"
import { Idle, Ringing, InCall } from "@screens/index"
import dayjs from "dayjs"
import React, { useState, useEffect, useRef } from "react"
import { UserAgent, Registerer, SessionState, RegistererState } from "sip.js"
import { UserAgent, Registerer, SessionState, RegistererState, Inviter } from "sip.js"

import config from "@root/config"

Expand All @@ -27,6 +27,7 @@ const App = () => {
const [loading, setLoading] = useState<boolean>(false)
const [registered, setRegistered] = useState<boolean>(false)
const [muted, setMuted] = useState<boolean>(false)
const [nextRequest, setNextRequest] = useState<boolean>(false)
const [stats, setStats] = useState({ contacts: 0 })

const eventListener = useRef<SIPEventListener>()
Expand Down Expand Up @@ -88,13 +89,37 @@ const App = () => {
registerer.unregister()
}

const outboundCall = () => {
if (!ua) return

const target = UserAgent.makeURI(`sip:${config.dst}@${config.host}`)
if (!target) {
throw new Error("Failed to create target URI.")
}

const outboundSession = new Inviter(ua, target, {
sessionDescriptionHandlerOptions: {
constraints: { audio: true, video: false }
}
})

outboundSession.invite()
setSession(outboundSession)
setLoading(true)
setInvite({ ...invite, startedAt: dayjs().toDate() })

logger.log("send invite => ")
}

const hangup = () => {
logger.log("hangup", nextRequest)
setLoading(false)
if (!session) return

if (invite.answeredAt) return session.bye()
if (invite.answeredAt) return session.bye().catch(e => logger.error(e))
// @ts-ignore
session.cancel()
logger.log("hangup", nextRequest)
}

const handleMute = () => {
Expand All @@ -104,16 +129,31 @@ const App = () => {

}

const next = () => {
setNextRequest(true)
hangup()
}

const sessionListener = (newState: SessionState) => {
if (!session) return

const terminate = () => {
logger.log("terminate", nextRequest)

cleanupMedia()
setLoading(false)

setMuted(false)
toggleMicro(session, false)
setInvite({ startedAt: null, answeredAt: null })
logger.log("terminate")
logger.log("terminate", nextRequest)
if(nextRequest) {
outboundCall()
setLoading(true)
setNextRequest(false)
return
}

setLoading(false)
}

switch (newState) {
Expand Down Expand Up @@ -158,18 +198,8 @@ const App = () => {

const getScreen = () => {
if (loading) return <Ringing loading={loading} hangup={hangup} />

if (invite.answeredAt) return <InCall answeredAt={invite.answeredAt} muted={muted} handleMute={handleMute} hangup={hangup}/>

return (
<Idle
ua={ua}
registered={registered}
setSession={setSession}
setLoading={setLoading}
setStartedAt={startedAt => setInvite({ ...invite, startedAt })}
/>
)
if (invite.answeredAt) return <InCall answeredAt={invite.answeredAt} muted={muted} handleMute={handleMute} hangup={hangup} next={next}/>
return <Idle registered={registered} outboundCall={outboundCall} />
}

return (
Expand Down
34 changes: 2 additions & 32 deletions src/screens/Idle/index.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,13 @@
import dayjs from "dayjs"
import React from "react"
import { UserAgent, Inviter, Session } from "sip.js"

import config from "@root/config"

import styles from "../style.m.scss"
import logger from "@helpers/logger"

type Props = {
ua: UserAgent | null
registered: boolean
setSession: (session: Session) => void
setLoading: (loading: boolean) => void
setStartedAt: (startedAt: Date) => void
outboundCall: () => void
}

const Idle: React.FC<Props> = ({ ua, registered, setSession, setLoading, setStartedAt }) => {
const outboundCall = () => {
if (!ua) return

const target = UserAgent.makeURI(`sip:${config.dst}@${config.host}`)
if (!target) {
throw new Error("Failed to create target URI.")
}

const outboundSession = new Inviter(ua, target, {
sessionDescriptionHandlerOptions: {
constraints: { audio: true, video: false }
}
})

outboundSession.invite()
setSession(outboundSession)
setLoading(true)
setStartedAt(dayjs().toDate())

logger.log("send invite => ")
}

const Idle: React.FC<Props> = ({ registered, outboundCall }) => {
return (
<>
<div className={styles.main}>
Expand Down
23 changes: 14 additions & 9 deletions src/screens/InCall/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react"

import {CallDurationTimer} from '@root/components/CallDurationTimer';
import {Mic, MicOff} from '@root/components/Icons';
import { CallDurationTimer } from "@root/components/CallDurationTimer"
import { Mic, MicOff } from "@root/components/Icons"

import styles from "../style.m.scss"

Expand All @@ -10,14 +10,14 @@ type Props = {
muted: boolean
handleMute: () => void
hangup: () => void
}
next: () => void
}

const InCall: React.FC<Props> = ({ answeredAt, muted, handleMute, hangup }) => {
const InCall: React.FC<Props> = ({ answeredAt, muted, handleMute, hangup, next }) => {
return (
<>
<div className={styles.main}>
<CallDurationTimer answeredAt={answeredAt} className={styles.timer}/>

<CallDurationTimer answeredAt={answeredAt} className={styles.timer} />
</div>

<div className={styles.actions}>
Expand All @@ -27,9 +27,14 @@ const InCall: React.FC<Props> = ({ answeredAt, muted, handleMute, hangup }) => {
</div>
)}

<button className={styles.cancelButton} onClick={hangup} >
Завершить
</button>
<div className={styles.buttons}>
<button className={styles.darkButton} onClick={hangup}>
Завершить
</button>
<button className={styles.darkButton} onClick={next}>
Следующий
</button>
</div>
</div>
</>
)
Expand Down
4 changes: 2 additions & 2 deletions src/screens/Ringing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ const Ringing: React.FC<Props> = ({ loading, hangup }) => {
</div>

<div className={styles.actions}>
<button className={styles.cancelButton} onClick={hangup} >
Завершить
<button className={styles.darkButton} onClick={hangup} >
Отменить поиск
</button>
</div>
</>
Expand Down
7 changes: 6 additions & 1 deletion src/screens/style.m.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
}
}

.buttons {
display: flex;
gap: 12px
}

button {
outline: none;
border: none;
Expand All @@ -78,7 +83,7 @@
}
}

&.cancelButton {
&.darkButton {
background-color: rgba(255, 255, 255, 0.10);
&:hover {
background-color: rgba(255, 255, 255, 0.07);
Expand Down