From 0f643579197cd53549bd8277cbea67ec42fd8216 Mon Sep 17 00:00:00 2001 From: Hamid Afghan Date: Fri, 30 Oct 2026 19:07:42 +0100 Subject: [PATCH 1/2] Hide remote actions during calls --- resources/js/components/chat/call.tsx | 8 +- .../components/chat/conversation-thread.tsx | 104 ++++++++++-------- 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/resources/js/components/chat/call.tsx b/resources/js/components/chat/call.tsx index 393b1bcb6..f3b1c9bcc 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(); @@ -114,7 +114,7 @@ export function CallButton({ isCompact: boolean; onClick: () => void; }) { - const isOnCall = useIsBusy(); + const isOnCall = useIsOnCall(); const { auth } = usePage().props; if (!auth.remotes) { @@ -163,7 +163,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; diff --git a/resources/js/components/chat/conversation-thread.tsx b/resources/js/components/chat/conversation-thread.tsx index 98ac2f3d3..063e1445f 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, + useIsOnCall, } from '@/components/chat/call'; import { LiftedMessage, @@ -1707,6 +1708,7 @@ function Composer({ const voiceNote = useVoiceNote(showError); const isVoicing = voiceNote.state.status !== 'idle'; + const isOnCall = useIsOnCall(); const pushVoiceNote = async () => { const voice = await voiceNote.stop(); @@ -1928,67 +1930,73 @@ function Composer({ isCompact ? 'size-9' : 'size-10', )} /> - - - + {!isOnCall && ( + + + + + + + + {trimmed !== '' || hasImages + ? 'Voice notes go on their own' + : 'Record a voice note (max. 1 min)'} + + + )} + {!isOnCall && ( + + - - - - {trimmed !== '' || hasImages - ? 'Voice notes go on their own' - : 'Record a voice note (max. 1 min)'} - - - - - - - {pingLabel} - + + {pingLabel} + + )} Date: Fri, 30 Oct 2026 20:06:43 +0100 Subject: [PATCH 2/2] Fix call action state --- resources/js/components/chat/call.tsx | 12 +++++++++++- .../js/components/chat/conversation-thread.tsx | 15 +++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/resources/js/components/chat/call.tsx b/resources/js/components/chat/call.tsx index f3b1c9bcc..629ccc5a2 100644 --- a/resources/js/components/chat/call.tsx +++ b/resources/js/components/chat/call.tsx @@ -102,6 +102,16 @@ export function useIsOnCall(): 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. */ @@ -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 063e1445f..e4ef404d4 100644 --- a/resources/js/components/chat/conversation-thread.tsx +++ b/resources/js/components/chat/conversation-thread.tsx @@ -21,7 +21,7 @@ import { CallButton, CallConsole, OrgCallConsole, - useIsOnCall, + useIsCallActive, } from '@/components/chat/call'; import { LiftedMessage, @@ -1708,7 +1708,14 @@ function Composer({ const voiceNote = useVoiceNote(showError); const isVoicing = voiceNote.state.status !== 'idle'; - const isOnCall = useIsOnCall(); + const isCallActive = useIsCallActive(); + const discardVoiceNote = voiceNote.discard; + + useEffect(() => { + if (isCallActive && isVoicing) { + discardVoiceNote(); + } + }, [discardVoiceNote, isCallActive, isVoicing]); const pushVoiceNote = async () => { const voice = await voiceNote.stop(); @@ -1930,7 +1937,7 @@ function Composer({ isCompact ? 'size-9' : 'size-10', )} /> - {!isOnCall && ( + {!isCallActive && ( @@ -1964,7 +1971,7 @@ function Composer({ )} - {!isOnCall && ( + {!isCallActive && (