diff --git a/resources/js/components/chat/call.tsx b/resources/js/components/chat/call.tsx index 393b1bcb6..629ccc5a2 100644 --- a/resources/js/components/chat/call.tsx +++ b/resources/js/components/chat/call.tsx @@ -89,9 +89,9 @@ function useRingingOrgCall(): OrgCall | null { } /** - * Whether the user is on a call of either kind, which keeps them from starting or joining another. + * Whether the user is placing, receiving, or participating in a call of either kind. */ -function useIsBusy(): boolean { +export function useIsOnCall(): boolean { const call = useCall(); const orgCall = useOrgCall(); @@ -102,6 +102,16 @@ function useIsBusy(): boolean { ); } +/** + * Whether the composer should hide actions that do not make sense while a call is ringing or underway. + */ +export function useIsCallActive(): boolean { + const isOnCall = useIsOnCall(); + const ringingOrgCall = useRingingOrgCall(); + + return isOnCall || ringingOrgCall !== null; +} + /** * Sits next to Ping in a remote's composer and asks the composer to confirm the call in place. */ @@ -114,7 +124,7 @@ export function CallButton({ isCompact: boolean; onClick: () => void; }) { - const isOnCall = useIsBusy(); + const isOnCall = useIsOnCall(); const { auth } = usePage().props; if (!auth.remotes) { @@ -163,7 +173,7 @@ export function CallConsole({ onConfirmingChange: (isConfirming: boolean) => void; }) { const call = useCall(); - const isOnCall = useIsBusy(); + const isOnCall = useIsOnCall(); const handle = `@${partner.handle}`; const isThisCall = call.status !== 'idle' && call.partner.handle === partner.handle; @@ -724,7 +734,7 @@ export function OrgCallConsole({ onConfirmingChange: (isConfirming: boolean) => void; }) { const call = useOrgCall(); - const isOnCall = useIsBusy(); + const isOnCall = useIsOnCall(); const ongoing = useOngoingOrgCalls().find((candidate) => candidate.org.id === org.id) ?? null; diff --git a/resources/js/components/chat/conversation-thread.tsx b/resources/js/components/chat/conversation-thread.tsx index 98ac2f3d3..e4ef404d4 100644 --- a/resources/js/components/chat/conversation-thread.tsx +++ b/resources/js/components/chat/conversation-thread.tsx @@ -21,6 +21,7 @@ import { CallButton, CallConsole, OrgCallConsole, + useIsCallActive, } from '@/components/chat/call'; import { LiftedMessage, @@ -1707,6 +1708,14 @@ function Composer({ const voiceNote = useVoiceNote(showError); const isVoicing = voiceNote.state.status !== 'idle'; + const isCallActive = useIsCallActive(); + const discardVoiceNote = voiceNote.discard; + + useEffect(() => { + if (isCallActive && isVoicing) { + discardVoiceNote(); + } + }, [discardVoiceNote, isCallActive, isVoicing]); const pushVoiceNote = async () => { const voice = await voiceNote.stop(); @@ -1928,67 +1937,73 @@ function Composer({ isCompact ? 'size-9' : 'size-10', )} /> - - - + {!isCallActive && ( + + + + + + + + {trimmed !== '' || hasImages + ? 'Voice notes go on their own' + : 'Record a voice note (max. 1 min)'} + + + )} + {!isCallActive && ( + + - - - - {trimmed !== '' || hasImages - ? 'Voice notes go on their own' - : 'Record a voice note (max. 1 min)'} - - - - - - - {pingLabel} - + + {pingLabel} + + )}