mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
[feature] create toogle gid for advanced settings
This commit is contained in:
@@ -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<boolean>;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
items: Item[];
|
||||
};
|
||||
|
||||
export function SettingToogleSwitchGrid({ items }: Props) {
|
||||
|
||||
const handleItemChange = (item: Item, state: boolean) => {
|
||||
item.onChange?.(state);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5">
|
||||
{items.map((item) => (
|
||||
<div key={item.text} className="flex justify-between items-center bg-theme-1 py-2 px-3 rounded-md gap-5">
|
||||
<div className="flex flex-col justify-center gap-px grow">
|
||||
<h2 className="font-bold">{item.text}</h2>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400">{item.desc}</p>
|
||||
</div>
|
||||
<ToogleSwitch checked={item.checked} className="shrink-0 h-7 w-12" onChange={checked => handleItemChange(item, checked)} middleWare={item.middleWare}/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -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<boolean>;
|
||||
}
|
||||
|
||||
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 (
|
||||
<label className={cn("flex cursor-pointer select-none items-center h-8 w-14", className, classNames?.container)} htmlFor={uuid}>
|
||||
<div className='relative size-full rounded-full p-1 bg-neutral-500 transition-colors duration-200' style={{ backgroundColor: isChecked && backgroundColor }}>
|
||||
<input
|
||||
id={uuid}
|
||||
type='checkbox'
|
||||
checked={isChecked}
|
||||
onChange={handleCheckboxChange}
|
||||
className='sr-only peer'
|
||||
/>
|
||||
<div
|
||||
className={cn("dot top-0 left-0 flex h-full aspect-square items-center justify-center rounded-full transition duration-200 peer-checked:translate-x-full", classNames?.dot)}
|
||||
style={{ backgroundColor: dotColor }}
|
||||
>
|
||||
{isChecked && <span className="text-current" style={{ color: textColor }}>
|
||||
<svg
|
||||
width='11'
|
||||
height='8'
|
||||
viewBox='0 0 11 8'
|
||||
fill='none'
|
||||
>
|
||||
<path
|
||||
d='M10.0915 0.951972L10.0867 0.946075L10.0813 0.940568C9.90076 0.753564 9.61034 0.753146 9.42927 0.939309L4.16201 6.22962L1.58507 3.63469C1.40401 3.44841 1.11351 3.44879 0.932892 3.63584C0.755703 3.81933 0.755703 4.10875 0.932892 4.29224L0.932878 4.29225L0.934851 4.29424L3.58046 6.95832C3.73676 7.11955 3.94983 7.2 4.1473 7.2C4.36196 7.2 4.55963 7.11773 4.71406 6.9584L10.0468 1.60234C10.2436 1.4199 10.2421 1.1339 10.0915 0.951972ZM4.2327 6.30081L4.2317 6.2998C4.23206 6.30015 4.23237 6.30049 4.23269 6.30082L4.2327 6.30081Z'
|
||||
fill='currentColor'
|
||||
stroke='currentColor'
|
||||
strokeWidth='0.4'
|
||||
/>
|
||||
</svg>
|
||||
</span>}
|
||||
{!isChecked && <span className="text-current" style={{ color: textColor }}>
|
||||
<svg
|
||||
className='h-4 w-4 stroke-current'
|
||||
fill='black'
|
||||
viewBox='0 0 24 24'
|
||||
>
|
||||
<path
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
strokeWidth='2'
|
||||
d='M6 18L18 6M6 6l12 12'
|
||||
/>
|
||||
</svg>
|
||||
</span>}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
@@ -9,5 +9,5 @@ export function useConstant<T>(fn: () => T): T {
|
||||
ref.current = { v: fn() };
|
||||
}
|
||||
|
||||
return ref.current.v;
|
||||
return ref.current?.v;
|
||||
}
|
||||
|
||||
@@ -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<boolean> => {
|
||||
if(enabled === hardwareAcceleration){ return false; }
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const toogleShowSupporters = () => {
|
||||
setShowSupporters(show => !show);
|
||||
};
|
||||
@@ -500,6 +511,14 @@ export function SettingsPage() {
|
||||
</div>
|
||||
</SettingContainer>
|
||||
</SettingContainer>
|
||||
|
||||
<SettingContainer title="Advanced" description="Changes these stettings only if your are sure of what you are doing">
|
||||
<SettingToogleSwitchGrid items={[
|
||||
{ checked: hardwareAcceleration, text: "Hadware Acceleration", desc: "Enable Hardware Acceleration to use your GPU and improve BSManager's performance. Turn this off if you're experiencing frame drops.", middleWare: onChangeHardwareAcceleration },
|
||||
{ checked: useSymlink, text: "Use Symlink", desc: "Use Symlinks instead of Junctions to link folders. Turn this on only if you really need it.", onChange: () => {} },
|
||||
]}/>
|
||||
</SettingContainer>
|
||||
|
||||
<Tippy content={isChangelogAvailable ? t("pages.settings.changelogs.open") : t("pages.settings.changelogs.not-founds")} placement="left" className="font-bold bg-main-color-3">
|
||||
<div className="!bg-light-main-color-1 dark:!bg-main-color-1 rounded-md py-1 px-2 font-bold float-right mb-5 hover:brightness-125 h-auto w-auto">
|
||||
<BsmButton onClick={handleVersionClick} text={`v${appVersion}`} withBar={false} typeColor="none"/>
|
||||
|
||||
Reference in New Issue
Block a user