From eef1be096ae8cce91a21d64082e650bf955bdb9a Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Fri, 3 Jan 2025 11:16:59 -0700 Subject: [PATCH] fix(app, components): Fix display suspending when idle time set to "never" (#17180) Closes RQA-3813 --- app/src/App/OnDeviceDisplayApp.tsx | 5 ++-- app/src/local-resources/config/constants.ts | 1 - app/src/local-resources/config/index.ts | 1 - .../local-resources/dom-utils/constants.ts | 2 ++ .../hooks/__tests__/useScreenIdle.test.ts | 24 +++++++++++++------ .../local-resources/dom-utils/hooks/index.ts | 1 + .../dom-utils/hooks/useScreenIdle.ts | 12 ++++++---- app/src/local-resources/dom-utils/index.ts | 1 + .../TouchScreenSleep.tsx | 2 +- app/src/redux/config/selectors.ts | 2 +- components/src/hooks/index.ts | 1 - 11 files changed, 33 insertions(+), 19 deletions(-) delete mode 100644 app/src/local-resources/config/constants.ts delete mode 100644 app/src/local-resources/config/index.ts create mode 100644 app/src/local-resources/dom-utils/constants.ts rename components/src/hooks/__tests__/useIdle.test.ts => app/src/local-resources/dom-utils/hooks/__tests__/useScreenIdle.test.ts (62%) rename components/src/hooks/useIdle.ts => app/src/local-resources/dom-utils/hooks/useScreenIdle.ts (82%) diff --git a/app/src/App/OnDeviceDisplayApp.tsx b/app/src/App/OnDeviceDisplayApp.tsx index 6e8c78449f0..5337965fc52 100644 --- a/app/src/App/OnDeviceDisplayApp.tsx +++ b/app/src/App/OnDeviceDisplayApp.tsx @@ -9,7 +9,6 @@ import { COLORS, OVERFLOW_AUTO, POSITION_RELATIVE, - useIdle, useScrolling, } from '@opentrons/components' import { ApiHostProvider } from '@opentrons/react-api-client' @@ -52,7 +51,7 @@ import { updateConfigValue, } from '/app/redux/config' import { updateBrightness } from '/app/redux/shell' -import { SLEEP_NEVER_MS } from '/app/local-resources/config' +import { useScreenIdle, SLEEP_NEVER_MS } from '/app/local-resources/dom-utils' import { useProtocolReceiptToast, useSoftwareUpdatePoll } from './hooks' import { ODDTopLevelRedirects } from './ODDTopLevelRedirects' import { ReactQueryDevtools } from '/app/App/tools' @@ -166,7 +165,7 @@ export const OnDeviceDisplayApp = (): JSX.Element => { initialState: false, } const dispatch = useDispatch() - const isIdle = useIdle(sleepTime, options) + const isIdle = useScreenIdle(sleepTime, options) useEffect(() => { if (isIdle) { diff --git a/app/src/local-resources/config/constants.ts b/app/src/local-resources/config/constants.ts deleted file mode 100644 index 1c7b0e2727d..00000000000 --- a/app/src/local-resources/config/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const SLEEP_NEVER_MS = 604800000 diff --git a/app/src/local-resources/config/index.ts b/app/src/local-resources/config/index.ts deleted file mode 100644 index f87cf0102a1..00000000000 --- a/app/src/local-resources/config/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './constants' diff --git a/app/src/local-resources/dom-utils/constants.ts b/app/src/local-resources/dom-utils/constants.ts new file mode 100644 index 00000000000..f48e8566837 --- /dev/null +++ b/app/src/local-resources/dom-utils/constants.ts @@ -0,0 +1,2 @@ +// See RQA-3813 and associated PR. We are stuck using this hardcoded number to mean "never" or migrate the on-filesystem value. +export const SLEEP_NEVER_MS = 604800000 diff --git a/components/src/hooks/__tests__/useIdle.test.ts b/app/src/local-resources/dom-utils/hooks/__tests__/useScreenIdle.test.ts similarity index 62% rename from components/src/hooks/__tests__/useIdle.test.ts rename to app/src/local-resources/dom-utils/hooks/__tests__/useScreenIdle.test.ts index 8063c317325..e449b0cd82e 100644 --- a/components/src/hooks/__tests__/useIdle.test.ts +++ b/app/src/local-resources/dom-utils/hooks/__tests__/useScreenIdle.test.ts @@ -1,6 +1,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' import { renderHook } from '@testing-library/react' -import { useIdle } from '../useIdle' +import { useScreenIdle } from '../useScreenIdle' +import { SLEEP_NEVER_MS } from '/app/local-resources/dom-utils' const MOCK_EVENTS: Array = [ 'mousedown', @@ -20,19 +21,19 @@ describe('useIdle', () => { it('should return the default initialState', () => { const mockTime = 1000 - const { result } = renderHook(() => useIdle(mockTime)) + const { result } = renderHook(() => useScreenIdle(mockTime)) expect(result.current).toBe(true) }) it('should return the given initialState', () => { const mockTime = 1000 - const { result } = renderHook(() => useIdle(mockTime, MOCK_OPTIONS)) + const { result } = renderHook(() => useScreenIdle(mockTime, MOCK_OPTIONS)) expect(result.current).toBe(false) }) it('should return true after 1000ms', () => { const mockTime = 1000 - const { result } = renderHook(() => useIdle(mockTime, MOCK_OPTIONS)) + const { result } = renderHook(() => useScreenIdle(mockTime, MOCK_OPTIONS)) expect(result.current).toBe(false) setTimeout(() => { expect(result.current).toBe(true) @@ -41,7 +42,7 @@ describe('useIdle', () => { it('should return true after 180,000ms - 3min', () => { const mockTime = 60 * 1000 * 3 - const { result } = renderHook(() => useIdle(mockTime, MOCK_OPTIONS)) + const { result } = renderHook(() => useScreenIdle(mockTime, MOCK_OPTIONS)) expect(result.current).toBe(false) setTimeout(() => { expect(result.current).toBe(true) @@ -50,7 +51,7 @@ describe('useIdle', () => { it('should return true after 180,0000ms - 30min', () => { const mockTime = 60 * 1000 * 30 - const { result } = renderHook(() => useIdle(mockTime, MOCK_OPTIONS)) + const { result } = renderHook(() => useScreenIdle(mockTime, MOCK_OPTIONS)) expect(result.current).toBe(false) setTimeout(() => { expect(result.current).toBe(true) @@ -59,10 +60,19 @@ describe('useIdle', () => { it('should return true after 3,600,000ms - 1 hour', () => { const mockTime = 60 * 1000 * 60 - const { result } = renderHook(() => useIdle(mockTime, MOCK_OPTIONS)) + const { result } = renderHook(() => useScreenIdle(mockTime, MOCK_OPTIONS)) expect(result.current).toBe(false) setTimeout(() => { expect(result.current).toBe(true) }, 3600001) }) + + it(`should always return false if the idle time is exactly ${SLEEP_NEVER_MS}`, () => { + const mockTime = SLEEP_NEVER_MS + const { result } = renderHook(() => useScreenIdle(mockTime, MOCK_OPTIONS)) + expect(result.current).toBe(false) + setTimeout(() => { + expect(result.current).toBe(false) + }, 604800001) + }) }) diff --git a/app/src/local-resources/dom-utils/hooks/index.ts b/app/src/local-resources/dom-utils/hooks/index.ts index 2098c90e0c3..97edf1a5b1d 100644 --- a/app/src/local-resources/dom-utils/hooks/index.ts +++ b/app/src/local-resources/dom-utils/hooks/index.ts @@ -1 +1,2 @@ export * from './useScrollPosition' +export * from './useScreenIdle' diff --git a/components/src/hooks/useIdle.ts b/app/src/local-resources/dom-utils/hooks/useScreenIdle.ts similarity index 82% rename from components/src/hooks/useIdle.ts rename to app/src/local-resources/dom-utils/hooks/useScreenIdle.ts index 7fea9f832ca..d36c6cfb326 100644 --- a/components/src/hooks/useIdle.ts +++ b/app/src/local-resources/dom-utils/hooks/useScreenIdle.ts @@ -1,4 +1,5 @@ import { useState, useEffect, useRef } from 'react' +import { SLEEP_NEVER_MS } from '/app/local-resources/dom-utils' const USER_EVENTS: Array = [ 'click', @@ -29,7 +30,7 @@ const DEFAULT_OPTIONS = { * @param {object} options (events that the app need to check, initialState: initial state true => idle) * @returns {boolean} */ -export function useIdle( +export function useScreenIdle( idleTime: number, options?: Partial<{ events: Array @@ -48,9 +49,12 @@ export function useIdle( window.clearTimeout(idleTimer.current) } - idleTimer.current = window.setTimeout(() => { - setIdle(true) - }, idleTime) + // See RQA-3813 and associated PR. + if (idleTime !== SLEEP_NEVER_MS) { + idleTimer.current = window.setTimeout(() => { + setIdle(true) + }, idleTime) + } } events.forEach(event => { diff --git a/app/src/local-resources/dom-utils/index.ts b/app/src/local-resources/dom-utils/index.ts index fc78d35129c..907d7e254c1 100644 --- a/app/src/local-resources/dom-utils/index.ts +++ b/app/src/local-resources/dom-utils/index.ts @@ -1 +1,2 @@ export * from './hooks' +export * from './constants' diff --git a/app/src/organisms/ODD/RobotSettingsDashboard/TouchScreenSleep.tsx b/app/src/organisms/ODD/RobotSettingsDashboard/TouchScreenSleep.tsx index cb123b261be..3872d79ba21 100644 --- a/app/src/organisms/ODD/RobotSettingsDashboard/TouchScreenSleep.tsx +++ b/app/src/organisms/ODD/RobotSettingsDashboard/TouchScreenSleep.tsx @@ -14,7 +14,7 @@ import { getOnDeviceDisplaySettings, updateConfigValue, } from '/app/redux/config' -import { SLEEP_NEVER_MS } from '/app/local-resources/config' +import { SLEEP_NEVER_MS } from '/app/local-resources/dom-utils' import type { ChangeEvent } from 'react' import type { Dispatch } from '/app/redux/types' diff --git a/app/src/redux/config/selectors.ts b/app/src/redux/config/selectors.ts index dea9cc3f171..cdbe9bb22c6 100644 --- a/app/src/redux/config/selectors.ts +++ b/app/src/redux/config/selectors.ts @@ -1,5 +1,5 @@ import { createSelector } from 'reselect' -import { SLEEP_NEVER_MS } from '/app/local-resources/config' +import { SLEEP_NEVER_MS } from '/app/local-resources/dom-utils' import type { State } from '../types' import type { Config, diff --git a/components/src/hooks/index.ts b/components/src/hooks/index.ts index 6ae0015d1e0..14a4de52c71 100644 --- a/components/src/hooks/index.ts +++ b/components/src/hooks/index.ts @@ -2,7 +2,6 @@ export * from './useConditionalConfirm' export * from './useDrag' -export * from './useIdle' export * from './useInterval' export * from './useLongPress' export * from './useMountEffect'