mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-07 01:22:15 +08:00
143 lines
4.0 KiB
TypeScript
143 lines
4.0 KiB
TypeScript
import { styled, Typography } from '@mui/material'
|
|
import { useLockFn } from 'ahooks'
|
|
import { forwardRef, useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
import { BaseDialog, DialogRef, Switch } from '@/components/base'
|
|
import { useVerge } from '@/hooks/use-verge'
|
|
import { showNotice } from '@/services/notice-service'
|
|
|
|
import { useSettingDialog } from '../settings-search-context'
|
|
|
|
import { HotkeyInput } from './hotkey-input'
|
|
|
|
const ItemWrapper = styled('div')`
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 8px;
|
|
`
|
|
|
|
const HOTKEY_FUNC = [
|
|
'open_or_close_dashboard',
|
|
'clash_mode_rule',
|
|
'clash_mode_global',
|
|
'clash_mode_direct',
|
|
'toggle_system_proxy',
|
|
'toggle_tun_mode',
|
|
'entry_lightweight_mode',
|
|
'reactivate_profiles',
|
|
] as const
|
|
|
|
const HOTKEY_FUNC_LABELS: Record<(typeof HOTKEY_FUNC)[number], string> = {
|
|
open_or_close_dashboard:
|
|
'settings.modals.hotkey.functions.openOrCloseDashboard',
|
|
clash_mode_rule: 'settings.modals.hotkey.functions.rule',
|
|
clash_mode_global: 'settings.modals.hotkey.functions.global',
|
|
clash_mode_direct: 'settings.modals.hotkey.functions.direct',
|
|
toggle_system_proxy: 'settings.modals.hotkey.functions.toggleSystemProxy',
|
|
toggle_tun_mode: 'settings.modals.hotkey.functions.toggleTunMode',
|
|
entry_lightweight_mode:
|
|
'settings.modals.hotkey.functions.entryLightweightMode',
|
|
reactivate_profiles: 'settings.modals.hotkey.functions.reactivateProfiles',
|
|
}
|
|
|
|
export const HotkeyViewer = forwardRef<DialogRef>((props, ref) => {
|
|
const { t } = useTranslation()
|
|
const [open, setOpen] = useState(false)
|
|
|
|
const { verge, patchVerge } = useVerge()
|
|
|
|
const [hotkeyMap, setHotkeyMap] = useState<Record<string, string[]>>({})
|
|
const [enableGlobalHotkey, setEnableGlobalHotkey] = useState(
|
|
verge?.enable_global_hotkey ?? true,
|
|
)
|
|
|
|
useSettingDialog(ref, 'hotkey-viewer', open, () => ({
|
|
open: () => {
|
|
setOpen(true)
|
|
|
|
const map = {} as typeof hotkeyMap
|
|
|
|
verge?.hotkeys?.forEach((text) => {
|
|
const [func, key] = text.split(',').map((e) => e.trim())
|
|
|
|
if (!func || !key) return
|
|
|
|
map[func] = key
|
|
.split('+')
|
|
.map((e) => e.trim())
|
|
.map((k) => (k === 'PLUS' ? '+' : k))
|
|
})
|
|
|
|
setHotkeyMap(map)
|
|
},
|
|
close: () => setOpen(false),
|
|
}))
|
|
|
|
const onSave = useLockFn(async () => {
|
|
const hotkeys = Object.entries(hotkeyMap)
|
|
.map(([func, keys]) => {
|
|
if (!func || !keys?.length) return ''
|
|
|
|
const key = keys
|
|
.map((k) => k.trim())
|
|
.filter(Boolean)
|
|
.map((k) => (k === '+' ? 'PLUS' : k))
|
|
.join('+')
|
|
|
|
if (!key) return ''
|
|
return `${func},${key}`
|
|
})
|
|
.filter(Boolean)
|
|
|
|
try {
|
|
await patchVerge({
|
|
hotkeys,
|
|
enable_global_hotkey: enableGlobalHotkey,
|
|
})
|
|
setOpen(false)
|
|
} catch (err) {
|
|
showNotice.error(err)
|
|
}
|
|
})
|
|
|
|
return (
|
|
<BaseDialog
|
|
open={open}
|
|
title={t('settings.modals.hotkey.title')}
|
|
contentSx={{ width: 450, maxHeight: 380 }}
|
|
okBtn={t('shared.actions.save')}
|
|
cancelBtn={t('shared.actions.cancel')}
|
|
onClose={() => setOpen(false)}
|
|
onCancel={() => setOpen(false)}
|
|
onOk={onSave}
|
|
>
|
|
<span data-settings-dialog="hotkey-viewer" />
|
|
<ItemWrapper
|
|
data-setting-target="settings.modals.hotkey.toggles.enableGlobal"
|
|
style={{ marginBottom: 16 }}
|
|
>
|
|
<Typography>
|
|
{t('settings.modals.hotkey.toggles.enableGlobal')}
|
|
</Typography>
|
|
<Switch
|
|
edge="end"
|
|
checked={enableGlobalHotkey}
|
|
onChange={(e) => setEnableGlobalHotkey(e.target.checked)}
|
|
/>
|
|
</ItemWrapper>
|
|
|
|
{HOTKEY_FUNC.map((func) => (
|
|
<ItemWrapper key={func} data-setting-target={HOTKEY_FUNC_LABELS[func]}>
|
|
<Typography>{t(HOTKEY_FUNC_LABELS[func])}</Typography>
|
|
<HotkeyInput
|
|
value={hotkeyMap[func] ?? []}
|
|
onChange={(v) => setHotkeyMap((m) => ({ ...m, [func]: v }))}
|
|
/>
|
|
</ItemWrapper>
|
|
))}
|
|
</BaseDialog>
|
|
)
|
|
})
|