import { Box, Button, InputAdornment, List, ListItem, ListItemText, MenuItem, Select, TextField, styled, } from '@mui/material' import { convertFileSrc } from '@tauri-apps/api/core' import { join } from '@tauri-apps/api/path' import { open as openDialog } from '@tauri-apps/plugin-dialog' import { exists } from '@tauri-apps/plugin-fs' import { forwardRef, useEffect, useImperativeHandle, useState } from 'react' import { useTranslation } from 'react-i18next' import { BaseDialog, DialogRef, Switch, TooltipIcon } from '@/components/base' import { DEFAULT_HOVER_DELAY } from '@/components/proxy/proxy-group-navigator' import { useVerge } from '@/hooks/use-verge' import { useWindowDecorations } from '@/hooks/use-window' import { copyIconFile, getAppDir } from '@/services/cmds' import { mutate } from '@/services/mutate' import { showNotice } from '@/services/notice-service' import getSystem from '@/utils/get-system' import { GuardState } from './guard-state' const OS = getSystem() const clampHoverDelay = (value: number) => { if (!Number.isFinite(value)) { return DEFAULT_HOVER_DELAY } return Math.min(5000, Math.max(0, Math.round(value))) } const getIcons = async (icon_dir: string, name: string) => { const updateTime = localStorage.getItem(`icon_${name}_update_time`) || '' const icon_png = await join(icon_dir, `${name}-${updateTime}.png`) const icon_ico = await join(icon_dir, `${name}-${updateTime}.ico`) return { icon_png, icon_ico, } } export const LayoutViewer = forwardRef((_, ref) => { const { t } = useTranslation() const { verge, patchVerge, mutateVerge } = useVerge() const [open, setOpen] = useState(false) const [commonIcon, setCommonIcon] = useState('') const [sysproxyIcon, setSysproxyIcon] = useState('') const [tunIcon, setTunIcon] = useState('') const { decorated, toggleDecorations } = useWindowDecorations() useEffect(() => { initIconPath() }, []) async function initIconPath() { const appDir = await getAppDir() const icon_dir = await join(appDir, 'icons') const { icon_png: common_icon_png, icon_ico: common_icon_ico } = await getIcons(icon_dir, 'common') const { icon_png: sysproxy_icon_png, icon_ico: sysproxy_icon_ico } = await getIcons(icon_dir, 'sysproxy') const { icon_png: tun_icon_png, icon_ico: tun_icon_ico } = await getIcons( icon_dir, 'tun', ) if (await exists(common_icon_ico)) { setCommonIcon(common_icon_ico) } else { setCommonIcon(common_icon_png) } if (await exists(sysproxy_icon_ico)) { setSysproxyIcon(sysproxy_icon_ico) } else { setSysproxyIcon(sysproxy_icon_png) } if (await exists(tun_icon_ico)) { setTunIcon(tun_icon_ico) } else { setTunIcon(tun_icon_png) } } useImperativeHandle(ref, () => ({ open: () => setOpen(true), close: () => setOpen(false), })) const onSwitchFormat = (_e: any, value: boolean) => value const onError = (err: any) => { showNotice.error(err) } const onChangeData = (patch: Partial) => { mutateVerge({ ...verge, ...patch }, false) } return ( setOpen(false)} onCancel={() => setOpen(false)} > { await toggleDecorations() }} > onChangeData({ traffic_graph: e })} onGuard={(e) => patchVerge({ traffic_graph: e })} > onChangeData({ enable_memory_usage: e })} onGuard={(e) => patchVerge({ enable_memory_usage: e })} > onChangeData({ enable_group_icon: e })} onGuard={(e) => patchVerge({ enable_group_icon: e })} > onChangeData({ pause_render_traffic_stats_on_blur: e }) } onGuard={(e) => patchVerge({ pause_render_traffic_stats_on_blur: e }) } > e.target.value} onChange={(value) => onChangeData({ notice_position: value })} onGuard={(value) => patchVerge({ notice_position: value })} > {t('settings.components.verge.layout.fields.hoverNavigator')} } /> onChangeData({ enable_hover_jump_navigator: e })} onGuard={(e) => patchVerge({ enable_hover_jump_navigator: e })} > {t( 'settings.components.verge.layout.fields.hoverNavigatorDelay', )} } /> clampHoverDelay(Number(e.target.value))} onChange={(value) => onChangeData({ hover_jump_navigator_delay: clampHoverDelay(value), }) } onGuard={(value) => patchVerge({ hover_jump_navigator_delay: clampHoverDelay(value) }) } > {t('shared.units.milliseconds')} ), }, htmlInput: { min: 0, max: 5000, step: 20, }, }} /> e.target.value} onChange={(value) => onChangeData({ menu_icon: value })} onGuard={(value) => patchVerge({ menu_icon: value })} > onChangeData({ collapse_navbar: e })} onGuard={(e) => patchVerge({ collapse_navbar: e })} > {OS === 'macos' && ( e.target.value} onChange={(e) => onChangeData({ tray_icon: e })} onGuard={(e) => patchVerge({ tray_icon: e })} > )} {OS === 'macos' && ( onChangeData({ enable_tray_speed: e })} onGuard={(e) => patchVerge({ enable_tray_speed: e })} > )} {/* {OS === "macos" && ( onChangeData({ enable_tray_icon: e })} onGuard={(e) => patchVerge({ enable_tray_icon: e })} > )} */} e.target.value} onChange={(value) => onChangeData({ tray_proxy_groups_display_mode: value }) } onGuard={(value) => patchVerge({ tray_proxy_groups_display_mode: value }) } > onChangeData({ tray_inline_outbound_modes: e })} onGuard={(e) => patchVerge({ tray_inline_outbound_modes: e })} > onChangeData({ common_tray_icon: e })} onGuard={(e) => patchVerge({ common_tray_icon: e })} > onChangeData({ sysproxy_tray_icon: e })} onGuard={(e) => patchVerge({ sysproxy_tray_icon: e })} > onChangeData({ tun_tray_icon: e })} onGuard={(e) => patchVerge({ tun_tray_icon: e })} > ) }) const Item = styled(ListItem)(() => ({ padding: '5px 2px', }))