optimize various components

This commit is contained in:
jeffvli
2025-11-18 13:25:27 -08:00
parent 5ce88759c2
commit a8361fad31
3 changed files with 64 additions and 28 deletions
@@ -1,4 +1,4 @@
import { ChangeEvent, CSSProperties, KeyboardEvent, useRef, useState } from 'react'; import { ChangeEvent, CSSProperties, KeyboardEvent, useEffect, useRef, useState } from 'react';
import { shallow } from 'zustand/shallow'; import { shallow } from 'zustand/shallow';
import { useSettingsStore } from '/@/renderer/store'; import { useSettingsStore } from '/@/renderer/store';
@@ -58,10 +58,24 @@ export const SearchInput = ({
} }
}; };
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
const handleButtonClick = () => { const handleButtonClick = () => {
setIsInputMode(true); setIsInputMode(true);
setTimeout(() => { if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
ref?.current?.focus(); ref?.current?.focus();
timeoutRef.current = null;
}, 0); }, 0);
}; };
+12 -5
View File
@@ -42,6 +42,7 @@ export const useFastAverageColor = (args: {
}); });
useEffect(() => { useEffect(() => {
let isMounted = true;
const fac = new FastAverageColor(); const fac = new FastAverageColor();
if (src && srcLoaded) { if (src && srcLoaded) {
@@ -56,35 +57,41 @@ export const useFastAverageColor = (args: {
mode: 'speed', mode: 'speed',
}) })
.then((color) => { .then((color) => {
if (isMounted) {
idRef.current = id; idRef.current = id;
return setBackground({ setBackground({
background: color.rgb, background: color.rgb,
isDark: color.isDark, isDark: color.isDark,
isLight: color.isLight, isLight: color.isLight,
}); });
setIsLoading(false);
}
}) })
.catch((e) => { .catch((e) => {
if (isMounted) {
console.error('Error fetching average color', e); console.error('Error fetching average color', e);
idRef.current = id; idRef.current = id;
return setBackground({ setBackground({
background: 'rgba(0, 0, 0, 0)', background: 'rgba(0, 0, 0, 0)',
isDark: true, isDark: true,
isLight: false, isLight: false,
}); });
})
.finally(() => {
setIsLoading(false); setIsLoading(false);
}
}); });
} else if (srcLoaded) { } else if (srcLoaded) {
if (isMounted) {
idRef.current = id; idRef.current = id;
return setBackground({ setBackground({
background: 'var(--theme-colors-foreground-muted)', background: 'var(--theme-colors-foreground-muted)',
isDark: true, isDark: true,
isLight: false, isLight: false,
}); });
} }
}
return () => { return () => {
isMounted = false;
fac.destroy(); fac.destroy();
}; };
}, [algorithm, srcLoaded, src, id]); }, [algorithm, srcLoaded, src, id]);
+17 -2
View File
@@ -2,7 +2,7 @@ import type { ButtonVariant, ButtonProps as MantineButtonProps } from '@mantine/
import { ElementProps, Button as MantineButton } from '@mantine/core'; import { ElementProps, Button as MantineButton } from '@mantine/core';
import clsx from 'clsx'; import clsx from 'clsx';
import { forwardRef, useCallback, useRef, useState } from 'react'; import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
import styles from './button.module.css'; import styles from './button.module.css';
@@ -117,20 +117,35 @@ interface TimeoutButtonProps extends ButtonProps {
export const TimeoutButton = ({ timeoutProps, ...props }: TimeoutButtonProps) => { export const TimeoutButton = ({ timeoutProps, ...props }: TimeoutButtonProps) => {
const [, setTimeoutRemaining] = useState(timeoutProps.duration); const [, setTimeoutRemaining] = useState(timeoutProps.duration);
const [isRunning, setIsRunning] = useState(false); const [isRunning, setIsRunning] = useState(false);
const intervalRef = useRef(0); const intervalRef = useRef<null | number>(null);
const callback = () => { const callback = () => {
timeoutProps.callback(); timeoutProps.callback();
setTimeoutRemaining(timeoutProps.duration); setTimeoutRemaining(timeoutProps.duration);
if (intervalRef.current !== null) {
clearInterval(intervalRef.current); clearInterval(intervalRef.current);
intervalRef.current = null;
}
setIsRunning(false); setIsRunning(false);
}; };
const { clear, start } = useTimeout(callback, timeoutProps.duration); const { clear, start } = useTimeout(callback, timeoutProps.duration);
useEffect(() => {
return () => {
if (intervalRef.current !== null) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
};
}, []);
const startTimeout = useCallback(() => { const startTimeout = useCallback(() => {
if (isRunning) { if (isRunning) {
if (intervalRef.current !== null) {
clearInterval(intervalRef.current); clearInterval(intervalRef.current);
intervalRef.current = null;
}
setIsRunning(false); setIsRunning(false);
clear(); clear();
} else { } else {