diff --git a/src/script/components/AppNotification/AppNotification.tsx b/src/script/components/AppNotification/AppNotification.tsx
index 7cc2d74cdd9..54e37e21ad4 100644
--- a/src/script/components/AppNotification/AppNotification.tsx
+++ b/src/script/components/AppNotification/AppNotification.tsx
@@ -52,7 +52,7 @@ const APP_NOTIFICATION_SELECTOR = '#app-notification';
// Small delay to ensure rendering is complete.
// In some cases (switching between windows) the notification is not displayed without this delay.
// It's caused by the rendering behavior of the toast library (injecting the into the DOM node).
-const ACTION_DELAY_MS = 1;
+const ACTION_DELAY_MS = 100;
// Stores React roots for different windows (activeWindow).
// Each window (identified by its 'name' property or 'default' if not available) gets its own root.
diff --git a/src/script/components/calling/CallingCell/usePressSpaceToUnmute/usePressSpaceToUnmute.ts b/src/script/components/calling/CallingCell/usePressSpaceToUnmute/usePressSpaceToUnmute.ts
index 189ada7574a..010806ca3f8 100644
--- a/src/script/components/calling/CallingCell/usePressSpaceToUnmute/usePressSpaceToUnmute.ts
+++ b/src/script/components/calling/CallingCell/usePressSpaceToUnmute/usePressSpaceToUnmute.ts
@@ -61,11 +61,14 @@ export const usePressSpaceToUnmute = ({callState, toggleMute, isMuted, enabled}:
holdDelayMs: HOLD_DELAY_MS,
onHold: () => {
if (!isMuted()) {
- return;
+ return false;
}
+
toggleMute(false);
micOnNotification.show();
amplify.publish(WebAppEvents.ANALYTICS.EVENT, EventName.CALLING.PRESS_SPACE_TO_UNMUTE);
+
+ return true;
},
onRelease: () => {
toggleMute(true);
diff --git a/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.test.ts b/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.test.ts
index 4f8bb1fc99b..02ff54347f5 100644
--- a/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.test.ts
+++ b/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.test.ts
@@ -26,7 +26,7 @@ import {useKeyPressAndHold} from './useKeyPressAndHold';
jest.useFakeTimers();
describe('useKeyPressAndHold', () => {
- const mockOnHold = jest.fn();
+ const mockOnHold = jest.fn().mockReturnValue(true);
const mockOnRelease = jest.fn();
const defaultProps = {
key: KEY.SPACE,
@@ -67,22 +67,37 @@ describe('useKeyPressAndHold', () => {
expect(mockOnRelease).toHaveBeenCalledTimes(1);
});
- it("doesn't trigger onHold if key is released before holdDelay", () => {
+ it('calls onRelease only when onHold returns true', () => {
renderHook(() => useKeyPressAndHold(defaultProps));
act(() => {
- window.dispatchEvent(new KeyboardEvent('keydown', {key: KEY.SPACE}));
+ window.dispatchEvent(new KeyboardEvent('keyup', {key: KEY.SPACE}));
});
+ expect(mockOnRelease).not.toHaveBeenCalled();
+
act(() => {
- jest.advanceTimersByTime(100);
+ window.dispatchEvent(new KeyboardEvent('keydown', {key: KEY.SPACE}));
+ jest.advanceTimersByTime(200);
window.dispatchEvent(new KeyboardEvent('keyup', {key: KEY.SPACE}));
});
- expect(mockOnHold).not.toHaveBeenCalled();
+ expect(mockOnHold).toHaveBeenCalledTimes(1);
expect(mockOnRelease).toHaveBeenCalledTimes(1);
});
+ it("doesn't call onRelease only when onHold returns false", () => {
+ renderHook(() => useKeyPressAndHold({...defaultProps, onHold: jest.fn().mockReturnValue(false)}));
+
+ act(() => {
+ window.dispatchEvent(new KeyboardEvent('keydown', {key: KEY.SPACE}));
+ jest.advanceTimersByTime(200);
+ window.dispatchEvent(new KeyboardEvent('keyup', {key: KEY.SPACE}));
+ });
+
+ expect(mockOnRelease).toHaveBeenCalledTimes(0);
+ });
+
it("doesn't respond to key events when disabled", () => {
renderHook(() => useKeyPressAndHold({...defaultProps, enabled: false}));
diff --git a/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.ts b/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.ts
index 24d225d1e4e..eba92b7d9fa 100644
--- a/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.ts
+++ b/src/script/hooks/useKeyPressAndHold/useKeyPressAndHold.ts
@@ -23,7 +23,7 @@ import {KEY} from 'Util/KeyboardUtil';
interface KeyPressAndHoldParams {
key: (typeof KEY)[keyof typeof KEY];
- onHold: () => void;
+ onHold: () => boolean;
onRelease: () => void;
holdDelayMs: number;
enabled?: boolean;
@@ -41,6 +41,7 @@ export const useKeyPressAndHold = ({
const hasTriggeredRef = useRef(false);
const holdTimeoutRef = useRef | null>(null);
const isKeyDownRef = useRef(false);
+ const isPressHandledRef = useRef(false);
const handlePress = useCallback(() => {
if (holdTimeoutRef.current) {
@@ -52,8 +53,9 @@ export const useKeyPressAndHold = ({
return;
}
- onHold();
+ const called = onHold();
hasTriggeredRef.current = true;
+ isPressHandledRef.current = called;
}, holdDelayMs);
}, [onHold, holdDelayMs]);
@@ -66,8 +68,14 @@ export const useKeyPressAndHold = ({
const handleRelease = useCallback(() => {
clearHoldTimeout();
- onRelease();
hasTriggeredRef.current = false;
+
+ if (!isPressHandledRef.current) {
+ return;
+ }
+
+ onRelease();
+ isPressHandledRef.current = false;
}, [onRelease, clearHoldTimeout]);
const handleKeyDown = useCallback(