fixing the tray customization issue

This commit is contained in:
coolcoala
2025-08-03 11:12:25 +03:00
parent 445eaadac3
commit 01be6ae70a
2 changed files with 107 additions and 85 deletions

View File

@@ -36,6 +36,7 @@ import {
SelectValue, SelectValue,
} from "@/components/ui/select"; } from "@/components/ui/select";
import getSystem from "@/utils/get-system"; import getSystem from "@/utils/get-system";
import { Loader2 } from "lucide-react";
const OS = getSystem(); const OS = getSystem();
@@ -69,6 +70,9 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { verge, patchVerge, mutateVerge } = useVerge(); const { verge, patchVerge, mutateVerge } = useVerge();
const [localConfig, setLocalConfig] = useState<Partial<IVergeConfig>>({});
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [commonIcon, setCommonIcon] = useState(""); const [commonIcon, setCommonIcon] = useState("");
const [sysproxyIcon, setSysproxyIcon] = useState(""); const [sysproxyIcon, setSysproxyIcon] = useState("");
@@ -96,28 +100,26 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
}, []); }, []);
useEffect(() => { useEffect(() => {
if (open) initIconPath(); if (open) {
}, [open, initIconPath]); setLocalConfig(verge ?? {});
initIconPath();
}
}, [open, verge, initIconPath]);
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
open: () => setOpen(true), open: () => setOpen(true),
close: () => setOpen(false), close: () => setOpen(false),
})); }));
const onSwitchFormat = (_e: any, value: boolean) => value; const handleConfigChange = (patch: Partial<IVergeConfig>) => {
const onError = (err: any) => { setLocalConfig(prev => ({ ...prev, ...patch }));
showNotice("error", err.message || err.toString());
};
const onChangeData = (patch: Partial<IVergeConfig>) => {
mutateVerge({ ...verge, ...patch }, false);
}; };
const handleIconChange = useLockFn( const handleIconChange = useLockFn(
async (type: "common" | "sysproxy" | "tun") => { async (type: "common" | "sysproxy" | "tun") => {
const key = `${type}_tray_icon` as keyof IVergeConfig; const key = `${type}_tray_icon` as keyof IVergeConfig;
if (verge?.[key]) { if (localConfig[key]) {
onChangeData({ [key]: false }); handleConfigChange({ [key]: false });
await patchVerge({ [key]: false });
} else { } else {
const selected = await openDialog({ const selected = await openDialog({
directory: false, directory: false,
@@ -128,12 +130,23 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
const path = Array.isArray(selected) ? selected[0] : selected; const path = Array.isArray(selected) ? selected[0] : selected;
await copyIconFile(path, type); await copyIconFile(path, type);
await initIconPath(); await initIconPath();
onChangeData({ [key]: true }); handleConfigChange({ [key]: true });
await patchVerge({ [key]: true });
} }
} }
}, });
);
const handleSave = useLockFn(async () => {
setLoading(true);
try {
await patchVerge(localConfig);
showNotice("success", t("Settings saved successfully"));
setOpen(false);
} catch (err: any) {
showNotice("error", err.message || err.toString());
} finally {
setLoading(false);
}
});
return ( return (
<Dialog open={open} onOpenChange={setOpen}> <Dialog open={open} onOpenChange={setOpen}>
@@ -143,55 +156,66 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
</DialogHeader> </DialogHeader>
<div className="py-4 space-y-1"> <div className="py-4 space-y-1">
<SettingRow label={t("Memory Usage")}> {OS === "macos" && (
<GuardState <>
value={verge?.enable_memory_usage ?? true} <SettingRow label={t("Tray Icon")}>
valueProps="checked" <Select
onCatch={onError} onValueChange={(value) => handleConfigChange({ tray_icon: value as any })}
onFormat={onSwitchFormat} value={localConfig.tray_icon ?? "monochrome"}
onChange={(e) => onChangeData({ enable_memory_usage: e })}
onGuard={(e) => patchVerge({ enable_memory_usage: e })}
> >
<Switch /> <SelectTrigger className="w-40 h-8"><SelectValue /></SelectTrigger>
</GuardState> <SelectContent>
<SelectItem value="monochrome">{t("Monochrome")}</SelectItem>
<SelectItem value="colorful">{t("Colorful")}</SelectItem>
</SelectContent>
</Select>
</SettingRow> </SettingRow>
<SettingRow label={t("Proxy Group Icon")}> <SettingRow label={t("Enable Tray Icon")}>
<GuardState <Switch
value={verge?.enable_group_icon ?? true} checked={localConfig.enable_tray_icon ?? true}
valueProps="checked" onCheckedChange={(checked) => handleConfigChange({ enable_tray_icon: checked })}
onCatch={onError} />
onFormat={onSwitchFormat} </SettingRow>
onChange={(e) => onChangeData({ enable_group_icon: e })} </>
onGuard={(e) => patchVerge({ enable_group_icon: e })} )}
>
<Switch /> <SettingRow label={t("Common Tray Icon")}>
</GuardState> <Button variant="outline" size="sm" className="h-8" onClick={() => handleIconChange("common")}>
{localConfig.common_tray_icon && commonIcon && (
<img src={convertFileSrc(commonIcon)} className="h-5 mr-2" alt="common tray icon" />
)}
{localConfig.common_tray_icon ? t("Clear") : t("Browse")}
</Button>
</SettingRow> </SettingRow>
<SettingRow <SettingRow label={t("System Proxy Tray Icon")}>
label={t("Hover Jump Navigator")} <Button variant="outline" size="sm" className="h-8" onClick={() => handleIconChange("sysproxy")}>
extra={<TooltipIcon tooltip={t("Hover Jump Navigator Info")} />} {localConfig.sysproxy_tray_icon && sysproxyIcon && (
> <img src={convertFileSrc(sysproxyIcon)} className="h-5 mr-2" alt="system proxy tray icon" />
<GuardState )}
value={verge?.enable_hover_jump_navigator ?? true} {localConfig.sysproxy_tray_icon ? t("Clear") : t("Browse")}
valueProps="checked" </Button>
onCatch={onError} </SettingRow>
onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ enable_hover_jump_navigator: e })} <SettingRow label={t("Tun Tray Icon")}>
onGuard={(e) => patchVerge({ enable_hover_jump_navigator: e })} <Button variant="outline" size="sm" className="h-8" onClick={() => handleIconChange("tun")}>
> {localConfig.tun_tray_icon && tunIcon && (
<Switch /> <img src={convertFileSrc(tunIcon)} className="h-5 mr-2" alt="tun mode tray icon" />
</GuardState> )}
{localConfig.tun_tray_icon ? t("Clear") : t("Browse")}
</Button>
</SettingRow> </SettingRow>
</div> </div>
<DialogFooter> <DialogFooter>
<DialogClose asChild> <DialogClose asChild>
<Button type="button" variant="outline"> <Button type="button" variant="outline">{t("Cancel")}</Button>
{t("Close")}
</Button>
</DialogClose> </DialogClose>
<Button type="button" onClick={handleSave} disabled={loading}>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{t("Save")}
</Button>
</DialogFooter> </DialogFooter>
</DialogContent> </DialogContent>
</Dialog> </Dialog>

View File

@@ -201,11 +201,9 @@ const SettingVergeBasic = ({ onError }: Props) => {
onFormat={(v) => v} onFormat={(v) => v}
onChange={(e) => onChangeData({ tray_event: e })} onChange={(e) => onChangeData({ tray_event: e })}
onGuard={(e) => patchVerge({ tray_event: e })} onGuard={(e) => patchVerge({ tray_event: e })}
onChangeProps="onValueChange"
> >
<Select <Select>
onValueChange={(value) => onChangeData({ tray_event: value })}
value={tray_event}
>
<SelectTrigger className="w-40 h-8"> <SelectTrigger className="w-40 h-8">
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>