updating calling layout

This commit is contained in:
Roland Osborne 2025-01-27 15:26:16 -08:00
parent 2cab7e36ab
commit 7efd88f272
2 changed files with 87 additions and 12 deletions

View File

@ -16,6 +16,42 @@ export function Calling({ callCard }: { callCard: string }) {
const [connecting, setConnecting] = useState(false);
const [ending, setEnding] = useState(false);
const {height, width} = useWindowDimensions();
const [applyingVideo, setApplyingVideo] = useState(false);
const [applyingAudio, setApplyingAudio] = useState(false);
const toggleVideo = async () => {
if (!applyingVideo) {
setApplyingVideo(true);
try {
if (state.video && state.videoEnabled) {
await actions.disableVideo();
} else if (state.video && !state.videoEnabled) {
await actions.enableVideo();
}
} catch (err) {
console.log(err);
setAlert(true);
}
setApplyingVideo(false);
}
}
const toggleAudio = async () => {
if (!applyingAudio) {
setApplyingAudio(true);
try {
if (state.audio && state.audioEnabled) {
await actions.disableAudio();
} else if (state.audio && !state.audioEnabled) {
await actions.enableAudio();
}
} catch (err) {
console.log(err);
setAlert(true);
}
setApplyingAudio(false);
}
}
const end = async () => {
if (!ending) {
@ -112,8 +148,8 @@ export function Calling({ callCard }: { callCard: string }) {
{ state.calling && state.loaded && (
<View style={{ ...styles.overlap, bottom: frameOffset }}>
<View style={{ paddingTop: 8, paddingBottom: 8, paddingLeft: 16, paddingRight: 16, gap: 16, display: 'flex', flexDirection: 'row', borderRadius: 16, backgroundColor: 'rgba(128,128,128,0.5)' }}>
<IconButton style={styles.closeIcon} iconColor="white" containerColor={Colors.primary} icon="microphone" compact="true" mode="contained" size={32} onPress={end} />
<IconButton style={styles.closeIcon} iconColor="white" containerColor={Colors.primary} icon="video-outline" compact="true" mode="contained" size={32} onPress={end} />
<IconButton style={styles.closeIcon} iconColor="white" containerColor={Colors.primary} icon={state.audioEnabled ? 'microphone-off' : 'microphone'} loading={applyingAudio} disabled={!state.audio} compact="true" mode="contained" size={32} onPress={toggleAudio} />
<IconButton style={styles.closeIcon} iconColor="white" containerColor={Colors.primary} icon={state.videoEnabled ? 'video-off-outline' : 'video-outline'} loading={applyingVideo} disabled={!state.video} compact="true" mode="contained" size={32} onPress={toggleVideo} />
<IconButton style={styles.closeIcon} iconColor="white" containerColor={Colors.danger} icon="phone-hangup-outline" compact="true" mode="contained" size={32} onPress={end} />
</View>
</View>

View File

@ -29,6 +29,12 @@ export function useCalling() {
failed: false,
loaded: false,
panelOffset: 0,
stream: null,
audio: null,
audioEnabled: false,
video: null,
videoEnabled: false,
videoAdded: false,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -68,14 +74,16 @@ export function useCalling() {
facingMode: 'user'
}
});
for (const track of stream.getTracks()) {
if (track.kind === 'audio') {
peer.addTrack(track, stream);
}
if (track.kind === 'video') {
track.enabled = false;
}
const audio = stream.getTracks().find(track => track.kind === 'audio');
const video = stream.getTracks().find(track => track.kind === 'video');
if (audio) {
audio.enabled = true;
peer.addTrack(audio, stream);
}
if (video) {
video.enabled = false;
}
updateState({ audio, video, stream, audioAdded: true, audioEnabled: true, videoAdded: false, videoEnabled: false });
} catch (err) {
console.log(err);
updateState({ failed: true });
@ -88,7 +96,7 @@ export function useCalling() {
console.log(err);
}
call.current = null;
updateState({ calling: null, failed: false });
updateState({ calling: null, failed: false, audio: null, video: null });
}
}
}
@ -207,7 +215,7 @@ export function useCalling() {
console.log(err);
}
call.current = null;
updateState({ calling: null });
updateState({ calling: null, audio: null, video: null });
},
accept: async (callId: string, call: Call) => {
if (call.current) {
@ -251,7 +259,38 @@ export function useCalling() {
} else {
updateState({ panelOffset: ((height - width) - 80) / 2, loaded: true });
}
}
},
enableAudio: async () => {
if (!call.current || !state.audio || !state.audioAdded) {
throw new Error('cannot unmute audio');
}
state.audio.enabled = true;
updateState({ audioEnabled: true });
},
disableAudio: () => {
if (!call.current || !state.audio || !state.audioAdded) {
throw new Error('cannot mute audio');
}
state.audio.enabled = false;
updateState({ audioEnabled: false });
},
enableVideo: () => {
if (!call.current || !state.video) {
throw new Error('cannot start video');
}
if (!state.videoAdded) {
call.current.peer.addTrack(state.video, state.stream);
}
state.video.enabled = true;
updateState({ videoAdded: true, videoEnabled: true });
},
disableVideo: () => {
if (!call.current || !state.video) {
throw new Error('cannot stop video');
}
state.video.enabled = false;
updateState({ videoEnabled: false });
},
}
return { state, actions }