diff --git a/src/components/game/empty.tsx b/src/components/game/empty.tsx index 578618d..6e02051 100644 --- a/src/components/game/empty.tsx +++ b/src/components/game/empty.tsx @@ -1,13 +1,20 @@ import React, { useEffect, useState } from 'react'; import { Text } from 'ink'; +import { useTheme } from '~/hooks/use-theme'; const CHARACTERS = ['-', '_'] as const; const TIMEOUT = 700; export function Empty() { const [charIndex, setCharIndex] = useState(0); + const { animationsEnabled } = useTheme(); useEffect(() => { + if (!animationsEnabled) { + setCharIndex(0); + return; + } + const timeout = setTimeout(() => { const newIndex = (charIndex + 1) <= (CHARACTERS.length - 1) ? charIndex + 1 : 0; setCharIndex(newIndex); @@ -16,7 +23,7 @@ export function Empty() { return () => { clearTimeout(timeout); }; - }, [charIndex]); + }, [animationsEnabled, charIndex]); return ( {CHARACTERS[charIndex]} diff --git a/src/components/game/messages.tsx b/src/components/game/messages.tsx index 42c15b3..ccec658 100644 --- a/src/components/game/messages.tsx +++ b/src/components/game/messages.tsx @@ -11,7 +11,7 @@ import { useTheme } from '~/hooks/use-theme.js'; export function Messages() { const { board, pos, state, isInactive, setIsInactive } = useSudoku(); - const { theme } = useTheme(); + const { theme, animationsEnabled } = useTheme(); const [inactivityTimeout, setInactivityTimeout] = useState(); useEffect(() => { @@ -48,11 +48,13 @@ export function Messages() { // sort of an easter egg isInactive && - Are you still here? + Are you still here? { + animationsEnabled && + } } { diff --git a/src/components/logo.tsx b/src/components/logo.tsx index 8fb10cb..50647fa 100644 --- a/src/components/logo.tsx +++ b/src/components/logo.tsx @@ -9,7 +9,7 @@ const TYPING_SPEED = 100; export function Logo() { const [title, setTitle] = useState(TITLE[0]); const [isCompleted, setIsCompleted] = useState(false); - const { theme } = useTheme(); + const { theme, animationsEnabled } = useTheme(); useEffect(() => { if (isCompleted) return; @@ -31,6 +31,6 @@ export function Logo() { }); return ( - + ); } \ No newline at end of file diff --git a/src/components/update/update-suspense.tsx b/src/components/update/update-suspense.tsx index 0820cbb..1a7b628 100644 --- a/src/components/update/update-suspense.tsx +++ b/src/components/update/update-suspense.tsx @@ -24,14 +24,14 @@ if (isUnicodeSupported()) { } export function UpdateSuspense() { - const { theme } = useTheme(); + const { theme, animationsEnabled } = useTheme(); const randomSpinner = randomArrEl(spinners); - const Loader = () => ( + const Loader = () => animationsEnabled ? ( - ); + ) : ~; return ( diff --git a/src/core/init.ts b/src/core/init.ts index 7d3a5cc..0929e7e 100644 --- a/src/core/init.ts +++ b/src/core/init.ts @@ -40,7 +40,7 @@ export function init() { const { setSettings } = useSettings.getState(); const { setReplays } = useReplays.getState(); const { setIsUpdateCheckingEnabled } = useUpdate.getState(); - const { setTheme } = useTheme.getState(); + const { setTheme, setAnimationsEnabled } = useTheme.getState(); setOptions(options); setOnSubmit(async value => { @@ -128,6 +128,15 @@ export function init() { setTheme(value); }, }, + { + type: 'boolean', + name: 'Animations', + description: 'Enable or disable animations.', + value: true, + onChange(value) { + setAnimationsEnabled(value); + }, + }, { type: 'boolean', name: 'Enable Cache', @@ -147,7 +156,7 @@ export function init() { if (value) checkForUpdates(); }, - } + }, ]; if (cachedSettings) { diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts index 7806c4a..d683743 100644 --- a/src/hooks/use-theme.ts +++ b/src/hooks/use-theme.ts @@ -7,6 +7,8 @@ import type { RequiredDeep } from 'type-fest'; interface ThemeState { theme: RequiredDeep; setTheme(themeName: string): void; + animationsEnabled: boolean; + setAnimationsEnabled(animationsEnabled: boolean): void; } export const useTheme = create(set => ({ @@ -15,4 +17,8 @@ export const useTheme = create(set => ({ const theme = themes.find(({ name }) => name === themeName) || hacker; set({ theme }); }, + animationsEnabled: true, + setAnimationsEnabled(animationsEnabled) { + set({ animationsEnabled }); + } })); \ No newline at end of file