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}
+
+ )}