open file

This commit is contained in:
pompurin404 2024-08-30 23:23:16 +08:00
parent c5c90caa1b
commit df41310237
No known key found for this signature in database
6 changed files with 77 additions and 36 deletions

View File

@ -1,9 +1,17 @@
import { exec, execFile, execSync } from 'child_process'
import { dialog, nativeTheme } from 'electron'
import { dialog, nativeTheme, shell } from 'electron'
import { readFile } from 'fs/promises'
import path from 'path'
import { promisify } from 'util'
import { exePath, mihomoCorePath, resourcesDir, resourcesFilesDir, taskDir } from '../utils/dirs'
import {
exePath,
mihomoCorePath,
overridePath,
profilePath,
resourcesDir,
resourcesFilesDir,
taskDir
} from '../utils/dirs'
import { copyFileSync, writeFileSync } from 'fs'
export function getFilePath(ext: string[]): string[] | undefined {
@ -18,6 +26,15 @@ export async function readTextFile(filePath: string): Promise<string> {
return await readFile(filePath, 'utf8')
}
export function openFile(type: 'profile' | 'override', id: string, ext?: 'yaml' | 'js'): void {
if (type === 'profile') {
shell.openPath(profilePath(id))
}
if (type === 'override') {
shell.openPath(overridePath(id, ext || 'js'))
}
}
export async function openUWPTool(): Promise<void> {
const execFilePromise = promisify(execFile)
const uwpToolPath = path.join(resourcesDir(), 'files', 'enableLoopback.exe')

View File

@ -49,7 +49,14 @@ import {
import { isEncryptionAvailable, manualGrantCorePermition, restartCore } from '../core/manager'
import { triggerSysProxy } from '../sys/sysproxy'
import { checkUpdate, downloadAndInstallUpdate } from '../resolve/autoUpdater'
import { getFilePath, openUWPTool, readTextFile, setNativeTheme, setupFirewall } from '../sys/misc'
import {
getFilePath,
openFile,
openUWPTool,
readTextFile,
setNativeTheme,
setupFirewall
} from '../sys/misc'
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
import { isPortable, setPortable } from './dirs'
import { listWebdavBackups, webdavBackup, webdavDelete, webdavRestore } from '../resolve/backup'
@ -171,6 +178,7 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('setNativeTheme', (_e, theme) => {
setNativeTheme(theme)
})
ipcMain.handle('openFile', (_e, type, id, ext) => openFile(type, id, ext))
ipcMain.handle('copyEnv', ipcErrorWrapper(copyEnv))
ipcMain.handle('alert', (_e, msg) => {
dialog.showErrorBox('Mihomo Party', msg)

View File

@ -7,23 +7,7 @@ interface Props {
connection: IMihomoConnectionDetail
onClose: () => void
}
// sourceIP: string
// destinationIP: string
// destinationGeoIP: string
// destinationIPASN: string
// sourcePort: string
// destinationPort: string
// inboundIP: string
// inboundPort: string
// inboundName: string
// inboundUser: string
// host: string
// dnsMode: string
// specialProxy: string
// specialRules: string
// remoteDestination: string
// dscp: number
// sniffHost: string
const ConnectionDetailModal: React.FC<Props> = (props) => {
const { connection, onClose } = props
return (

View File

@ -16,6 +16,7 @@ import EditInfoModal from './edit-info-modal'
import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import ExecLogModal from './exec-log-modal'
import { openFile } from '@renderer/utils/ipc'
interface Props {
info: IOverrideItem
@ -48,6 +49,13 @@ const menuItems: MenuItem[] = [
color: 'default',
className: ''
} as MenuItem,
{
key: 'open-file',
label: '打开文件',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'exec-log',
label: '执行日志',
@ -68,8 +76,8 @@ const OverrideItem: React.FC<Props> = (props) => {
const { info, addOverrideItem, removeOverrideItem, mutateOverrideConfig, updateOverrideItem } =
props
const [updating, setUpdating] = useState(false)
const [openInfo, setOpenInfo] = useState(false)
const [openFile, setOpenFile] = useState(false)
const [openInfoEditor, setOpenInfoEditor] = useState(false)
const [openFileEditor, setOpenFileEditor] = useState(false)
const [openLog, setOpenLog] = useState(false)
const {
attributes,
@ -87,11 +95,15 @@ const OverrideItem: React.FC<Props> = (props) => {
const onMenuAction = (key: Key): void => {
switch (key) {
case 'edit-info': {
setOpenInfo(true)
setOpenInfoEditor(true)
break
}
case 'edit-file': {
setOpenFile(true)
setOpenFileEditor(true)
break
}
case 'open-file': {
openFile('override', info.id, info.ext)
break
}
case 'exec-log': {
@ -128,17 +140,17 @@ const OverrideItem: React.FC<Props> = (props) => {
zIndex: isDragging ? 'calc(infinity)' : undefined
}}
>
{openFile && (
{openFileEditor && (
<EditFileModal
id={info.id}
language={info.ext === 'yaml' ? 'yaml' : 'javascript'}
onClose={() => setOpenFile(false)}
onClose={() => setOpenFileEditor(false)}
/>
)}
{openInfo && (
{openInfoEditor && (
<EditInfoModal
item={info}
onClose={() => setOpenInfo(false)}
onClose={() => setOpenInfoEditor(false)}
updateOverrideItem={updateOverrideItem}
/>
)}
@ -148,7 +160,7 @@ const OverrideItem: React.FC<Props> = (props) => {
isPressable
onPress={() => {
if (disableOpen) return
setOpenFile(true)
setOpenFileEditor(true)
}}
>
<CardBody>

View File

@ -18,6 +18,7 @@ import EditFileModal from './edit-file-modal'
import EditInfoModal from './edit-info-modal'
import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { openFile } from '@renderer/utils/ipc'
interface Props {
info: IProfileItem
@ -51,8 +52,8 @@ const ProfileItem: React.FC<Props> = (props) => {
const total = extra?.total ?? 0
const [updating, setUpdating] = useState(false)
const [selecting, setSelecting] = useState(false)
const [openInfo, setOpenInfo] = useState(false)
const [openFile, setOpenFile] = useState(false)
const [openInfoEditor, setOpenInfoEditor] = useState(false)
const [openFileEditor, setOpenFileEditor] = useState(false)
const {
attributes,
listeners,
@ -78,6 +79,13 @@ const ProfileItem: React.FC<Props> = (props) => {
{
key: 'edit-file',
label: '编辑文件',
showDivider: false,
color: 'default',
className: ''
} as MenuItem,
{
key: 'open-file',
label: '打开文件',
showDivider: true,
color: 'default',
className: ''
@ -105,11 +113,15 @@ const ProfileItem: React.FC<Props> = (props) => {
const onMenuAction = async (key: Key): Promise<void> => {
switch (key) {
case 'edit-info': {
setOpenInfo(true)
setOpenInfoEditor(true)
break
}
case 'edit-file': {
setOpenFile(true)
setOpenFileEditor(true)
break
}
case 'open-file': {
openFile('profile', info.id)
break
}
case 'delete': {
@ -147,11 +159,11 @@ const ProfileItem: React.FC<Props> = (props) => {
zIndex: isDragging ? 'calc(infinity)' : undefined
}}
>
{openFile && <EditFileModal id={info.id} onClose={() => setOpenFile(false)} />}
{openInfo && (
{openFileEditor && <EditFileModal id={info.id} onClose={() => setOpenFileEditor(false)} />}
{openInfoEditor && (
<EditInfoModal
item={info}
onClose={() => setOpenInfo(false)}
onClose={() => setOpenInfoEditor(false)}
updateProfileItem={updateProfileItem}
/>
)}

View File

@ -297,6 +297,14 @@ export async function setNativeTheme(theme: 'system' | 'light' | 'dark'): Promis
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setNativeTheme', theme))
}
export async function openFile(
type: 'profile' | 'override',
id: string,
ext?: 'yaml' | 'js'
): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('openFile', type, id, ext))
}
export async function registerShortcut(
oldShortcut: string,
newShortcut: string,