import { useForm, type UseFormReturn } from 'react-hook-form'; import { useEffect } from 'react'; import cls from 'classnames'; import { api } from '~renderer/utils/api'; import { ConfigWtfSchema } from '~common/schemas'; import zodResolver from '~renderer/utils/zodResolver'; import useScrollHint from '~renderer/utils/useScrollHint'; import { useT } from '~renderer/i18n'; import TextButton from '../styled/TextButton'; import CheckboxInput from '../form/CheckboxInput'; import NumberGrabInput from '../form/NumberGrabInput'; type ItemProps = { type?: 'checkbox' | 'number'; id: keyof ConfigWtfSchema; label: string; recommended?: boolean; text: string; min?: number; max?: number; step?: number; sensitivity?: number; form: UseFormReturn; }; const Item = ({ type = 'checkbox', id, label, recommended, text, form, ...props }: ItemProps) => { const { watch, setValue, register } = form; const setOpts = { shouldTouch: true, shouldDirty: true, shouldValidate: true } as const; const watched = type === 'checkbox' ? watch(id) : undefined; const registered = type === 'number' ? register(id) : undefined; return ( <>

{label}

{type === 'checkbox' && ( setValue(id, v, setOpts)} className="justify-self-center" /> )} {type === 'number' && registered && ( setValue(id, v, setOpts)} /> )}

{text}

); }; const TweaksTab = () => { const t = useT(); const { data: pref } = api.preferences.get.useQuery(); const setPref = api.preferences.set.useMutation(); const applyPatch = api.patcher.apply.useMutation(); const verify = api.updater.verify.useMutation(); const form = useForm({ defaultValues: pref?.config ?? {}, resolver: zodResolver(ConfigWtfSchema) }); const { handleSubmit, reset, formState } = form; const { data: hw } = api.general.hardware.useQuery(); const recommendedFarClip = hw?.recommendedFarClip; const farClipValue = form.watch('farClip'); const farClipText = t('tweaks.farClip.text') + (recommendedFarClip != null ? ' ' + t('tweaks.farClip.recommendedHint', { value: recommendedFarClip }) : ''); const isApplying = setPref.isLoading || applyPatch.isLoading || verify.isLoading; useEffect(() => { pref && reset(pref.config); }, [reset, pref]); const scrollRef = useScrollHint(); return (
{ await setPref.mutateAsync({ config, farClipUserSet: true }); await applyPatch.mutateAsync(); await verify.mutateAsync(); reset(config); })} className="tw-surface flex min-h-0 flex-grow flex-col gap-3" >

{t('tweaks.cameraHeading')}

{t('tweaks.soundsHeading')}


{applyPatch.isError ? ( {t('tweaks.applyFailed', { message: applyPatch.error?.message ?? '' })} ) : ( <> {t('tweaks.highlighted')} {' '} {t('tweaks.recommendedNote')} )}

{ const config = recommendedFarClip != null ? { ...ConfigWtfSchema.parse({}), farClip: recommendedFarClip } : ConfigWtfSchema.parse({}); await setPref.mutateAsync({ config, farClipUserSet: false }); reset(config); }} > {t('tweaks.reset')} {(formState.isDirty || isApplying) && ( {t('tweaks.apply')} )}
); }; export default TweaksTab;