ਹੈੱਡਲੈੱਸ ਹੁੱਕ
useThunderPhone ਹੁੱਕ ਤੁਹਾਨੂੰ ਯੂਜ਼ਰ ਇੰਟਰਫੇਸ ਉੱਤੇ ਪੂਰਾ ਕੰਟਰੋਲ ਦਿੰਦਾ ਹੈ, ਜਦੋਂ ਕਿ ThunderPhone ਵੌਇਸ ਸੈਸ਼ਨ, ਆਡੀਓ ਰੂਟਿੰਗ ਅਤੇ ਕਨੈਕਸ਼ਨ ਸਟੇਟ ਨੂੰ ਮੈਨੇਜ ਕਰਦਾ ਹੈ। ਇਸਨੂੰ ਤਦ ਵਰਤੋ ਜਦੋਂ ਤੁਸੀਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਕਸਟਮ UI ਚਾਹੁੰਦੇ ਹੋ -- ਆਪਣੇ ਬਟਨ, ਲੇਆਉਟ, ਐਨੀਮੇਸ਼ਨ ਅਤੇ ਬ੍ਰਾਂਡਿੰਗ -- ਜਦੋਂ ਕਿ ThunderPhone ਅੰਦਰੂਨੀ ਤੌਰ 'ਤੇ ਸਭ ਕੁਝ ਸੰਭਾਲਦਾ ਹੈ।
ਹੈਡਲੈੱਸ ਹੁੱਕ ਕਦੋਂ ਵਰਤਣਾ ਹੈ
ਪਹਿਲਾਂ ਤੋਂ ਬਣਿਆ ThunderPhoneWidget ਕੰਪੋਨੈਂਟ ਜ਼ਿਆਦਾਤਰ ਵਰਤੋਂ ਮਾਮਲਿਆਂ ਨੂੰ ਕਵਰ ਕਰਦਾ ਹੈ, ਪਰ ਜਦੋਂ ਤੁਹਾਨੂੰ ਇਹ ਚਾਹੀਦਾ ਹੋਵੇ ਤਾਂ ਹੈਡਲੈੱਸ ਹੁੱਕ ਵਰਤੋ:
- ਪੂਰੀ ਤਰ੍ਹਾਂ ਕਸਟਮ ਕਾਲ UI ਜੋ ਤੁਹਾਡੀ ਐਪ ਦੇ ਡਿਜ਼ਾਈਨ ਸਿਸਟਮ ਨਾਲ ਮੇਲ ਖਾਂਦਾ ਹੋਵੇ
- ਰੀਅਲ-ਟਾਈਮ ਆਡੀਓ ਲੈਵਲਾਂ ਦੁਆਰਾ ਚਲਾਏ ਜਾਣ ਵਾਲੇ ਆਡੀਓ-ਰੀਐਕਟਿਵ ਵਿਜ਼ੁਅਲਾਈਜ਼ੇਸ਼ਨ (ਵੇਵਫਾਰਮ, ਔਰਬ, ਪਲਸਿੰਗ ਇੰਡੀਕੇਟਰ)
- ਕਸਟਮ ਕਾਲ ਫਲੋ, ਜਿਵੇਂ ਕਾਲ ਤੋਂ ਪਹਿਲਾਂ ਦੇ ਫਾਰਮ, ਕਾਲ ਤੋਂ ਬਾਅਦ ਦੇ ਸਰਵੇਖਣ ਜਾਂ ਵੌਇਸ ਦੇ ਨਾਲ ਇਨਲਾਈਨ ਚੈਟ
- ਮੌਜੂਦਾ ਕੰਪੋਨੈਂਟ ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਇੰਟੀਗ੍ਰੇਸ਼ਨ (Material UI, Chakra, Radix, ਆਦਿ)
ਇੰਸਟਾਲੇਸ਼ਨ
npm install @thunderphone/widget
ਮੁੱਢਲੀ ਵਰਤੋਂ
import { useThunderPhone } from '@thunderphone/widget'
function CustomCallButton() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
})
const handleClick = () => {
if (phone.state === 'connected') {
phone.disconnect()
} else {
phone.connect()
}
}
return (
<>
<button onClick={handleClick} disabled={phone.state === 'connecting'}>
{phone.state === 'connecting'
? 'Connecting...'
: phone.state === 'connected'
? 'End call'
: 'Start call'}
</button>
{phone.audio}
</>
)
}
ਵਿਕਲਪ
UseThunderPhoneOptions ਰਾਹੀਂ ਇਹ ਵਿਕਲਪ useThunderPhone ਨੂੰ ਪਾਸ ਕਰੋ:
| ਵਿਕਲਪ | ਕਿਸਮ | ਲਾਜ਼ਮੀ | ਡਿਫੌਲਟ | ਵੇਰਵਾ |
|---|---|---|---|---|
publishableKey | string | ਹਾਂ | -- | ਪਬਲਿਸ਼ੇਬਲ API ਕੀ (pk_live_...)। ਏਜੰਟ ਨੂੰ ਕੀ ਦੀ ਵਿਜਿਟ ਕਨਫਿਗਰੇਸ਼ਨ ਤੋਂ ਆਪਣੇ ਆਪ ਨਿਰਧਾਰਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। |
apiBase | string | ਨਹੀਂ | 'https://api.thunderphone.com/v1' | API ਬੇਸ URL ਓਵਰਰਾਈਡ। |
language | string | ਨਹੀਂ | -- | ਪ੍ਰਤੀ-ਸੈਸ਼ਨ ਭਾਸ਼ਾ ਓਵਰਰਾਈਡ -- ਇੱਕ ਭਾਸ਼ਾ ਕੋਡ ਜਾਂ ਲੋਕੇਲ ਜਿਵੇਂ en, es, ਜਾਂ fr-FR। ਸੈੱਟ ਨਾ ਹੋਣ 'ਤੇ, ਏਜੰਟ ਦੀ ਕਨਫਿਗਰ ਕੀਤੀ ਭਾਸ਼ਾ ਲਾਗੂ ਹੁੰਦੀ ਹੈ। |
voice | string | ਨਹੀਂ | -- | ਪ੍ਰਤੀ-ਸੈਸ਼ਨ ਵੌਇਸ ਓਵਰਰਾਈਡ -- ਇੱਕ ਵੌਇਸ ਨਾਮ ਜਿਵੇਂ maria। ਸੈੱਟ ਨਾ ਹੋਣ 'ਤੇ, ਏਜੰਟ ਦੀ ਕਨਫਿਗਰ ਕੀਤੀ ਵੌਇਸ ਲਾਗੂ ਹੁੰਦੀ ਹੈ। |
context | string | ਨਹੀਂ | -- | ਏਜੰਟ ਨੂੰ ਪਾਸ ਕੀਤਾ ਜਾਣ ਵਾਲਾ ਪ੍ਰਤੀ-ਸੈਸ਼ਨ ਤੱਥਾਤਮਕ ਪੇਜ ਜਾਂ ਸਾਈਟ ਸੰਦਰਭ। ਸਰਵਰ-ਸਾਈਡ 'ਤੇ 12,000 ਅੱਖਰਾਂ ਤੱਕ ਸੰਖੇਪ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। |
onConnect | () => void | ਨਹੀਂ | -- | ਵੌਇਸ ਸੈਸ਼ਨ ਕਨੈਕਟ ਹੋਣ 'ਤੇ ਕਾਲ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। |
onDisconnect | () => void | ਨਹੀਂ | -- | ਸੈਸ਼ਨ ਖਤਮ ਹੋਣ 'ਤੇ ਕਾਲ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। |
onError | (error) => void | ਨਹੀਂ | -- | ਗਲਤੀਆਂ ਹੋਣ 'ਤੇ ਕਾਲ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। Error ਵਿੱਚ error (ਕੋਡ) ਅਤੇ message ਫੀਲਡ ਹੁੰਦੇ ਹਨ। |
ringtone | boolean | string | ਨਹੀਂ | false | ਕਨੈਕਟ ਕਰਦੇ ਸਮੇਂ ਰਿੰਗਟੋਨ ਚਲਾਓ। ਡਿਫੌਲਟ ਰਿੰਗਟੋਨ ਲਈ true, ਜਾਂ ਕਸਟਮ ਆਡੀਓ ਲਈ URL ਸਟ੍ਰਿੰਗ। |
ਵਾਪਸੀ ਮੁੱਲ
ਹੁੱਕ ਇੱਕ UseThunderPhoneReturn ਆਬਜੈਕਟ ਵਾਪਸ ਕਰਦਾ ਹੈ:
| ਪ੍ਰਾਪਰਟੀ | ਕਿਸਮ | ਵੇਰਵਾ |
|---|---|---|
state | 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error' | ਮੌਜੂਦਾ ਕਨੈਕਸ਼ਨ ਸਥਿਤੀ। |
connect | () => void | ਵੌਇਸ ਸੈਸ਼ਨ ਸ਼ੁਰੂ ਕਰੋ। |
disconnect | () => void | ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਖਤਮ ਕਰੋ। |
toggleMute | () => void | ਮਾਈਕ੍ਰੋਫੋਨ ਮਿਊਟ ਨੂੰ ਚਾਲੂ/ਬੰਦ ਕਰੋ। |
isMuted | boolean | ਕੀ ਮਾਈਕ੍ਰੋਫੋਨ ਇਸ ਵੇਲੇ ਮਿਊਟ ਹੈ। |
error | string | undefined | ਜਦੋਂ ਸਥਿਤੀ 'error' ਹੋਵੇ ਤਾਂ ਗਲਤੀ ਸੁਨੇਹਾ। |
agentName | string | undefined | ਕਨੈਕਟ ਕੀਤੇ ਏਜੰਟ ਦਾ ਡਿਸਪਲੇ ਨਾਮ। |
audioLevel | number | ਬੰਦ ਕੀਤਾ ਗਿਆ -- ਹਮੇਸ਼ਾ 0। ਪਿੱਛਲੀ ਅਨੁਕੂਲਤਾ ਲਈ ਰੱਖਿਆ ਗਿਆ ਇੱਕ ਸਥਿਰ ਪਲੇਸਹੋਲਡਰ; ਇਹ ਕਦੇ ਅੱਪਡੇਟ ਨਹੀਂ ਹੁੰਦਾ। ਇਸ ਦੀ ਬਜਾਏ audioLevelRef.current ਪੜ੍ਹੋ। |
audioLevelRef | React.RefObject<number> | ਇੱਕ ਬਦਲਣਯੋਗ ਰੈਫ ਜਿਸ ਵਿੱਚ ਰੀਅਲ-ਟਾਈਮ ਆਡੀਓ ਪੱਧਰ (0--1) ਹੁੰਦਾ ਹੈ -- ਏਜੰਟ ਦੀ ਆਵਾਜ਼ ਅਤੇ ਵਿਜ਼ਿਟਰ ਦੇ ਮਾਈਕ੍ਰੋਫੋਨ ਵਿੱਚੋਂ ਵੱਧ ਉੱਚਾ -- ਜੋ ਹਰ ਐਨੀਮੇਸ਼ਨ ਫਰੇਮ 'ਤੇ, React ਦੇ ਰੈਂਡਰ ਚੱਕਰ ਤੋਂ ਬਾਹਰ, ਅੱਪਡੇਟ ਹੁੰਦਾ ਹੈ। ਨਿਰਵਿਘਨ, ਬਿਨਾਂ ਅਟਕਣ ਵਾਲੀਆਂ ਐਨੀਮੇਸ਼ਨਾਂ ਲਈ requestAnimationFrame ਲੂਪਾਂ ਦੇ ਅੰਦਰ audioLevelRef.current ਪੜ੍ਹੋ, ਜਾਂ ਜਦੋਂ ਤੁਹਾਨੂੰ React ਸਥਿਤੀ ਵਿੱਚ ਮੁੱਲ ਦੀ ਲੋੜ ਹੋਵੇ ਤਾਂ ਇਸਨੂੰ ਕਿਸੇ ਅੰਤਰਾਲ 'ਤੇ ਸੈਂਪਲ ਕਰੋ। |
audio | ReactNode | ਅਦਿੱਖ ਐਲੀਮੈਂਟ ਜੋ ਆਡੀਓ ਕਨੈਕਸ਼ਨ ਸੰਭਾਲਦਾ ਹੈ -- ਰੈਂਡਰ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ। |
ਆਡੀਓ-ਪ੍ਰਤੀਕਿਰਿਆਸ਼ੀਲ UI
audioLevelRef ref ਤੁਹਾਨੂੰ React re-render ਟ੍ਰਿਗਰ ਕੀਤੇ ਬਿਨਾਂ ਫ੍ਰੇਮ-ਰੇਟ ਆਡੀਓ ਪੱਧਰ ਦਿੰਦਾ ਹੈ, ਜਿਸ ਨਾਲ ਇਹ ਸੁਚਾਰੂ ਵੇਵਫਾਰਮ ਵਿਜ਼ੁਅਲਾਈਜ਼ੇਸ਼ਨਾਂ, ਧੜਕਦੇ ਔਰਬਾਂ ਜਾਂ ਗੱਲਬਾਤ ਨਾਲ ਜੁੜੀ ਕਿਸੇ ਵੀ ਐਨੀਮੇਸ਼ਨ ਨੂੰ ਚਲਾਉਣ ਲਈ ਆਦਰਸ਼ ਬਣਦਾ ਹੈ। ਪੱਧਰ ਉਸ ਸਰੋਤ ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ ਜੋ ਵੱਧ ਉੱਚਾ ਹੋਵੇ: ਏਜੰਟ ਦੀ ਆਵਾਜ਼ ਜਾਂ ਵਿਜ਼ਟਰ ਦਾ ਮਾਈਕ੍ਰੋਫ਼ੋਨ।
ਵੇਵਫਾਰਮ ਉਦਾਹਰਨ
import { useRef, useEffect } from 'react'
import { useThunderPhone } from '@thunderphone/widget'
function WaveformCall() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
})
const canvasRef = useRef<HTMLCanvasElement>(null)
useEffect(() => {
if (phone.state !== 'connected') return
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext('2d')!
let animId: number
const draw = () => {
const level = phone.audioLevelRef.current ?? 0
ctx.clearRect(0, 0, canvas.width, canvas.height)
// Draw bars that react to audio level
const barCount = 24
const barWidth = canvas.width / barCount
for (let i = 0; i < barCount; i++) {
const distance = Math.abs(i - barCount / 2) / (barCount / 2)
const height = level * canvas.height * (1 - distance * 0.6)
const y = (canvas.height - height) / 2
ctx.fillStyle = '#0ea5e9'
ctx.fillRect(i * barWidth + 1, y, barWidth - 2, height)
}
animId = requestAnimationFrame(draw)
}
animId = requestAnimationFrame(draw)
return () => cancelAnimationFrame(animId)
}, [phone.state, phone.audioLevelRef])
return (
<div>
{phone.state === 'connected' && (
<canvas ref={canvasRef} width={240} height={80} />
)}
<button
onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}
disabled={phone.state === 'connecting'}
>
{phone.state === 'connected' ? 'End call' : 'Start call'}
</button>
{phone.audio}
</div>
)
}
ਧੜਕਦੇ ਔਰਬ ਦੀ ਉਦਾਹਰਨ
import { useRef, useEffect } from 'react'
import { useThunderPhone } from '@thunderphone/widget'
function PulsingOrb() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
})
const orbRef = useRef<HTMLDivElement>(null)
useEffect(() => {
if (phone.state !== 'connected') return
let animId: number
const animate = () => {
const level = phone.audioLevelRef.current ?? 0
if (orbRef.current) {
const scale = 1 + level * 0.5
orbRef.current.style.transform = `scale(${scale})`
orbRef.current.style.opacity = `${0.6 + level * 0.4}`
}
animId = requestAnimationFrame(animate)
}
animId = requestAnimationFrame(animate)
return () => cancelAnimationFrame(animId)
}, [phone.state, phone.audioLevelRef])
return (
<div style={{ textAlign: 'center' }}>
<div
ref={orbRef}
style={{
width: 80,
height: 80,
borderRadius: '50%',
background: '#0ea5e9',
margin: '20px auto',
transition: 'transform 0.05s ease-out',
}}
/>
<button
onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}
disabled={phone.state === 'connecting'}
>
{phone.state === 'connected' ? 'End call' : 'Call'}
</button>
{phone.audio}
</div>
)
}
ਬੋਲਣ ਦੇ ਸੂਚਕ ਦੀ ਉਦਾਹਰਨ
ਵਾਲਿਊਮ ਦੇ ਨਾਲ ਬਦਲਣ ਵਾਲੇ React-rendered UI ਲਈ -- ਜਿਵੇਂ ਥ੍ਰੈਸ਼ਹੋਲਡ-ਅਧਾਰਿਤ "ਬੋਲ ਰਿਹਾ ਹੈ" ਬੈਜ -- audioLevelRef.current ਨੂੰ ਕਿਸੇ ਅੰਤਰਾਲ 'ਤੇ ਸੈਂਪਲ ਕਰੋ ਅਤੇ ਨਤੀਜਾ state ਵਿੱਚ ਸਟੋਰ ਕਰੋ:
import { useEffect, useState } from 'react'
import { useThunderPhone } from '@thunderphone/widget'
function SpeakingBadge() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
})
const [speaking, setSpeaking] = useState(false)
useEffect(() => {
if (phone.state !== 'connected') {
setSpeaking(false)
return
}
const interval = setInterval(() => {
setSpeaking((phone.audioLevelRef.current ?? 0) > 0.1)
}, 100)
return () => clearInterval(interval)
}, [phone.state, phone.audioLevelRef])
return (
<div>
{phone.state === 'connected' && (
<span>{speaking ? 'Speaking' : 'Listening'}</span>
)}
<button onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}>
{phone.state === 'connected' ? 'End call' : 'Start call'}
</button>
{phone.audio}
</div>
)
}
ਸਟੇਟ ਮਸ਼ੀਨ
state ਪ੍ਰਾਪਰਟੀ ਇਸ ਲਾਈਫਸਾਈਕਲ ਦੀ ਪਾਲਣਾ ਕਰਦੀ ਹੈ:
idle --> connecting --> connected --> disconnected --> idle (after 1.5s)
\
--> error (stays until connect() is called again)
| ਸਟੇਟ | ਵੇਰਵਾ |
|---|---|
idle | ਕੋਈ ਸਰਗਰਮ ਸੈਸ਼ਨ ਨਹੀਂ। connect() ਨੂੰ ਕਾਲ ਕਰਨ ਲਈ ਤਿਆਰ। |
connecting | ਸੈਸ਼ਨ ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ। ਇਸ ਸਟੇਟ ਦੌਰਾਨ ਕਾਲ ਬਟਨ ਨੂੰ ਅਯੋਗ ਕਰੋ। |
connected | ਵੌਇਸ ਸੈਸ਼ਨ ਸਰਗਰਮ ਹੈ। ਯੂਜ਼ਰ ਏਜੰਟ ਨਾਲ ਗੱਲ ਕਰ ਰਿਹਾ ਹੈ। |
disconnected | ਸੈਸ਼ਨ ਸਹੀ ਢੰਗ ਨਾਲ ਸਮਾਪਤ ਹੋ ਗਿਆ ਹੈ। 1.5 ਸਕਿੰਟਾਂ ਬਾਅਦ ਆਪਣੇ ਆਪ ਵਾਪਸ idle ਵਿੱਚ ਤਬਦੀਲ ਹੋ ਜਾਂਦਾ ਹੈ। |
error | ਕੁਝ ਗਲਤ ਹੋਇਆ। ਸੁਨੇਹੇ ਲਈ phone.error ਦੀ ਜਾਂਚ ਕਰੋ। ਸਟੇਟ ਆਪਣੇ ਆਪ ਸਾਫ਼ ਨਹੀਂ ਹੁੰਦੀ -- connect() ਨੂੰ ਦੁਬਾਰਾ ਕਾਲ ਕਰਨ ਨਾਲ ਇੱਕ ਨਵੀਂ ਕੋਸ਼ਿਸ਼ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ ਅਤੇ ਗਲਤੀ ਰੀਸੈਟ ਹੋ ਜਾਂਦੀ ਹੈ। |
ਉਦਾਹਰਨਾਂ
ਮਿਊਟ ਕੰਟਰੋਲ ਨਾਲ
import { useThunderPhone } from '@thunderphone/widget'
function CallWithMute() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
})
return (
<div>
{phone.state === 'connected' && (
<div>
<p>Talking to {phone.agentName ?? 'Agent'}</p>
<button onClick={phone.toggleMute}>
{phone.isMuted ? 'Unmute' : 'Mute'}
</button>
<button onClick={phone.disconnect}>End call</button>
</div>
)}
{phone.state !== 'connected' && (
<button
onClick={phone.connect}
disabled={phone.state === 'connecting'}
>
{phone.state === 'connecting' ? 'Connecting...' : 'Call support'}
</button>
)}
{phone.state === 'error' && (
<p style={{ color: 'red' }}>{phone.error}</p>
)}
{phone.audio}
</div>
)
}
ਰਿੰਗਟੋਨ ਨਾਲ
ਫ਼ੋਨ ਕਾਲ ਦਾ ਅਨੁਕਰਣ ਕਰਨ ਲਈ ਕਨੈਕਟ ਹੋਣ ਦੌਰਾਨ ਰਿੰਗਿੰਗ ਆਵਾਜ਼ ਚਲਾਓ:
import { useThunderPhone } from '@thunderphone/widget'
function PhoneCallButton() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
ringtone: true, // or a custom URL: 'https://example.com/ringtone.mp3'
})
return (
<>
<button
onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}
disabled={phone.state === 'connecting'}
>
{phone.state === 'connecting'
? 'Ringing...'
: phone.state === 'connected'
? 'Hang up'
: 'Call'}
</button>
{phone.audio}
</>
)
}
ਰਿੰਗਟੋਨ connecting ਸਥਿਤੀ ਦੌਰਾਨ ਲੂਪ ਹੁੰਦੀ ਹੈ ਅਤੇ ਏਜੰਟ ਦੇ ਕਨੈਕਟ ਹੋਣ 'ਤੇ ਹੌਲੀ-ਹੌਲੀ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ। ਬਿਲਟ-ਇਨ ਡਿਫਾਲਟ ਰਿੰਗਟੋਨ ਲਈ true ਦਿਓ ਜਾਂ ਆਪਣੀ ਆਡੀਓ ਫ਼ਾਈਲ ਵਰਤਣ ਲਈ URL ਸਟਰਿੰਗ ਦਿਓ।
ਇਵੈਂਟ ਕਾਲਬੈਕਸ ਨਾਲ
import { useThunderPhone } from '@thunderphone/widget'
function TrackedCallButton() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
onConnect: () => {
analytics.track('call_started')
},
onDisconnect: () => {
analytics.track('call_ended')
},
onError: (error) => {
analytics.track('call_error', { code: error.error, message: error.message })
},
})
return (
<>
<button
onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}
disabled={phone.state === 'connecting'}
>
{phone.state === 'connected' ? 'Hang up' : 'Talk to AI'}
</button>
{phone.audio}
</>
)
}
ਪੂਰਾ ਕਸਟਮ UI
import { useThunderPhone } from '@thunderphone/widget'
function FullCustomUI() {
const phone = useThunderPhone({
publishableKey: 'pk_live_your_publishable_key',
})
return (
<div className="call-panel">
<div className="call-status">
{phone.state === 'idle' && <span>Ready</span>}
{phone.state === 'connecting' && <span className="pulse">Connecting...</span>}
{phone.state === 'connected' && (
<span>On call with {phone.agentName}</span>
)}
{phone.state === 'error' && <span className="error">{phone.error}</span>}
</div>
<div className="call-controls">
{phone.state === 'connected' ? (
<>
<button className="mute-btn" onClick={phone.toggleMute}>
{phone.isMuted ? 'Unmute' : 'Mute'}
</button>
<button className="end-btn" onClick={phone.disconnect}>
End
</button>
</>
) : (
<button
className="start-btn"
onClick={phone.connect}
disabled={phone.state === 'connecting'}
>
Start call
</button>
)}
</div>
{/* Required -- handles audio under the hood */}
{phone.audio}
</div>
)
}
ਸੁਝਾਅ
phone.audio ਨੂੰ ਹਮੇਸ਼ਾ ਰੈਂਡਰ ਕਰੋ
phone.audio ਐਲੀਮੈਂਟ ਦਿਖਾਈ ਨਹੀਂ ਦਿੰਦਾ, ਪਰ ਲਾਜ਼ਮੀ ਹੈ। ਇਸਨੂੰ ਆਪਣੇ JSX ਵਿੱਚ ਕਿਤੇ ਵੀ ਰੱਖੋ -- ਇਹ ਕੋਈ ਦਿੱਖਣਯੋਗ DOM ਰੈਂਡਰ ਨਹੀਂ ਕਰਦਾ, ਪਰ ਅੰਦਰੂਨੀ ਤੌਰ 'ਤੇ WebRTC ਆਡੀਓ ਕਨੈਕਸ਼ਨ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ।
ਕਨੈਕਟ ਹੋਣ ਦੌਰਾਨ ਬਟਨ ਅਯੋਗ ਕਰੋ
connecting ਸਥਿਤੀ 1-3 ਸਕਿੰਟ ਤੱਕ ਰਹਿ ਸਕਦੀ ਹੈ। ਡੁਪਲੀਕੇਟ ਕਨੈਕਸ਼ਨ ਕੋਸ਼ਿਸ਼ਾਂ ਨੂੰ ਰੋਕਣ ਲਈ ਇਸ ਸਥਿਤੀ ਦੌਰਾਨ ਕਾਲ ਬਟਨ ਅਯੋਗ ਕਰੋ।
ਗਲਤੀ ਸਥਿਤੀ ਨੂੰ ਸੁਚੱਜੇ ਢੰਗ ਨਾਲ ਸੰਭਾਲੋ
ਜਦੋਂ ਸਥਿਤੀ error ਹੋਵੇ, ਤਾਂ ਵਰਤੋਂਕਾਰ ਨੂੰ phone.error ਦਿਖਾਓ ਅਤੇ ਆਪਣਾ ਕਾਲ ਬਟਨ ਸਮਰੱਥ ਰੱਖੋ। ਹੂਕ ਆਪਣੇ ਆਪ error ਸਥਿਤੀ ਤੋਂ ਬਾਹਰ ਨਹੀਂ ਨਿਕਲਦਾ -- connect() ਨੂੰ ਦੁਬਾਰਾ ਕਾਲ ਕਰਨ ਨਾਲ ਨਵੀਂ ਕੋਸ਼ਿਸ਼ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ ਅਤੇ ਪਿਛਲੀ ਗਲਤੀ ਸਾਫ਼ ਹੋ ਜਾਂਦੀ ਹੈ।
ਸਾਈਡ ਇਫੈਕਟਸ ਲਈ ਕਾਲਬੈਕ ਵਰਤੋ
onConnect, onDisconnect, ਅਤੇ onError ਕਾਲਬੈਕ, ਸਥਿਤੀ ਨੂੰ ਪੋਲ ਕੀਤੇ ਬਿਨਾਂ ਐਨਾਲਿਟਿਕਸ, ਲੌਗਿੰਗ, ਜਾਂ ਐਪਲੀਕੇਸ਼ਨ ਦੇ ਹੋਰ ਲੌਜਿਕ ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਨ ਲਈ ਆਦਰਸ਼ ਹਨ।
audioLevelRef ਤੋਂ ਆਡੀਓ ਪੱਧਰ ਪੜ੍ਹੋ
audioLevelRef ਇਕੱਲਾ ਲਾਈਵ ਆਡੀਓ-ਪੱਧਰ ਸਰੋਤ ਹੈ। ਵੇਵਫਾਰਮਾਂ ਵਰਗੀਆਂ ਸੁਚੱਜੀਆਂ ਐਨੀਮੇਸ਼ਨਾਂ ਲਈ requestAnimationFrame ਦੇ ਅੰਦਰ audioLevelRef.current ਪੜ੍ਹੋ (ref ਪੜ੍ਹਨ ਨਾਲ ਰੀ-ਰੈਂਡਰ ਨਹੀਂ ਹੁੰਦੇ), ਜਾਂ ਇਸਨੂੰ ਕਿਸੇ ਇੰਟਰਵਲ 'ਤੇ ਸੈਂਪਲ ਕਰੋ ਅਤੇ React-ਰੈਂਡਰ ਕੀਤੇ UI ਲਈ ਨਤੀਜਾ ਸਥਿਤੀ ਵਿੱਚ ਸਟੋਰ ਕਰੋ। audioLevel ਨੰਬਰ ਹੁਣ ਅਪ੍ਰਚਲਿਤ ਹੈ ਅਤੇ ਹਮੇਸ਼ਾ 0 ਰਹਿੰਦਾ ਹੈ -- ਇਸ 'ਤੇ ਲੌਜਿਕ ਨਾ ਬਣਾਓ।