diff --git a/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx b/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx new file mode 100644 index 00000000..acd79d56 --- /dev/null +++ b/src/renderer/components/settings/setting-toogle-switch-grid.component.tsx @@ -0,0 +1,34 @@ +import { ToogleSwitch } from "../shared/toogle-switch.component"; + +type Item = { + text: string; + desc?: string; + checked?: boolean; + onChange?: (isChecked: boolean) => void; + middleWare?: (newState: boolean) => boolean|Promise; +}; + +type Props = { + items: Item[]; +}; + +export function SettingToogleSwitchGrid({ items }: Props) { + + const handleItemChange = (item: Item, state: boolean) => { + item.onChange?.(state); + }; + + return ( +
+ {items.map((item) => ( +
+
+

{item.text}

+

{item.desc}

+
+ handleItemChange(item, checked)} middleWare={item.middleWare}/> +
+ ))} +
+ ) +} diff --git a/src/renderer/components/shared/toogle-switch.component.tsx b/src/renderer/components/shared/toogle-switch.component.tsx new file mode 100644 index 00000000..4a564357 --- /dev/null +++ b/src/renderer/components/shared/toogle-switch.component.tsx @@ -0,0 +1,117 @@ +import { useEffect, useMemo, useState } from "react" +import { getCorrectTextColor } from "renderer/helpers/correct-text-color"; +import { cn } from "renderer/helpers/css-class.helpers"; +import { useConstant } from "renderer/hooks/use-constant.hook"; +import { useThemeColor } from "renderer/hooks/use-theme-color.hook"; +import { noop } from "shared/helpers/function.helpers"; +import { isPromise } from "shared/helpers/promise.helpers"; + +type Props = { + checked?: boolean; + className?: string; + classNames?: { + container?: string; + dot?: string; + active?: string; + inactive?: string; + } + bgColor?: string; + onChange?: (isChecked: boolean) => void; + middleWare?: (newState: boolean) => boolean|Promise; +} + +export function ToogleSwitch({ checked, className, classNames, bgColor, onChange, middleWare }: Props) { + + const uuid = useConstant(() => crypto.randomUUID()); + const [isChecked, setIsChecked] = useState(!!checked); + const { firstColor } = useThemeColor(); + const backgroundColor = useMemo(() => bgColor ?? firstColor, [bgColor, firstColor]); + const dotColor = useMemo(() => { + return getCorrectTextColor(backgroundColor); + }, [backgroundColor]); + const textColor = useMemo(() => { + return getCorrectTextColor(dotColor) + }, [dotColor]); + + useEffect(() => { + if (checked !== undefined) { + setIsChecked(checked); + } + }, [checked]); + + useEffect(() => { + if (onChange) { + onChange(isChecked); + } + }, [isChecked]); + + const handleCheckboxChange = () => { + if (middleWare) { + setIsChecked(prev => { + const newState = !prev; + console.log('newState', newState); + const result = middleWare(newState); + if (isPromise(result)) { + result.then(shouldChange => { + if (shouldChange) { + setIsChecked(newState); + } + }).catch(noop); + } else if (result) { + setIsChecked(newState); + } + return prev; + }); + } else { + setIsChecked(prev => !prev); + } + } + + return ( + + ) +} diff --git a/src/renderer/hooks/use-constant.hook.ts b/src/renderer/hooks/use-constant.hook.ts index 7f4317bc..6bfb0c74 100644 --- a/src/renderer/hooks/use-constant.hook.ts +++ b/src/renderer/hooks/use-constant.hook.ts @@ -9,5 +9,5 @@ export function useConstant(fn: () => T): T { ref.current = { v: fn() }; } - return ref.current.v; + return ref.current?.v; } diff --git a/src/renderer/pages/settings-page.component.tsx b/src/renderer/pages/settings-page.component.tsx index a90e9870..baa45363 100644 --- a/src/renderer/pages/settings-page.component.tsx +++ b/src/renderer/pages/settings-page.component.tsx @@ -43,6 +43,7 @@ import { AutoUpdaterService } from "renderer/services/auto-updater.service"; import BeatWaitingImg from "../../../assets/images/apngs/beat-waiting.png"; import { logRenderError } from "renderer"; import { BSLauncherService } from "renderer/services/bs-launcher.service"; +import { SettingToogleSwitchGrid } from "renderer/components/settings/setting-toogle-switch-grid.component"; export function SettingsPage() { @@ -92,6 +93,8 @@ export function SettingsPage() { const [playlistsDeepLinkEnabled, setPlaylistsDeepLinkEnabled] = useState(false); const [modelsDeepLinkEnabled, setModelsDeepLinkEnabled] = useState(false); const [hasDownloaderSession, setHasDownloaderSession] = useState(false); + const [hardwareAcceleration, setHardwareAcceleration] = useState(true); + const [useSymlink, setUseSymlink] = useState(false); const appVersion = useObservable(() => ipcService.sendV2("current-version")); const [isChangelogAvailable, setIsChangelogAvailable] = useState(true); @@ -219,6 +222,14 @@ export function SettingsPage() { }); }; + const onChangeHardwareAcceleration = async (enabled: boolean): Promise => { + if(enabled === hardwareAcceleration){ return false; } + + + + return true; + }; + const toogleShowSupporters = () => { setShowSupporters(show => !show); }; @@ -500,6 +511,14 @@ export function SettingsPage() { + + + {} }, + ]}/> + +