mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-16 03:32:17 +08:00
render svg using webview
This commit is contained in:
parent
8af1495df5
commit
38849a8739
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
|
@ -38,7 +38,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm add @mihomo-party/sysproxy-win32-${{ matrix.arch }}-msvc
|
pnpm add @mihomo-party/sysproxy-win32-${{ matrix.arch }}-msvc
|
||||||
pnpm add @resvg/resvg-js-win32-${{ matrix.arch }}-msvc
|
|
||||||
pnpm prepare --${{ matrix.arch }}
|
pnpm prepare --${{ matrix.arch }}
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
|
@ -96,7 +95,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm add @mihomo-party/sysproxy-linux-${{ matrix.arch }}-gnu
|
pnpm add @mihomo-party/sysproxy-linux-${{ matrix.arch }}-gnu
|
||||||
pnpm add @resvg/resvg-js-linux-${{ matrix.arch }}-gnu
|
|
||||||
pnpm prepare --${{ matrix.arch }}
|
pnpm prepare --${{ matrix.arch }}
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
|
@ -154,7 +152,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm add @mihomo-party/sysproxy-darwin-${{ matrix.arch }}
|
pnpm add @mihomo-party/sysproxy-darwin-${{ matrix.arch }}
|
||||||
pnpm add @resvg/resvg-js-darwin-${{ matrix.arch }}
|
|
||||||
pnpm prepare --${{ matrix.arch }}
|
pnpm prepare --${{ matrix.arch }}
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
"adm-zip": "^0.5.15",
|
"adm-zip": "^0.5.15",
|
||||||
"axios": "^1.7.5",
|
"axios": "^1.7.5",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"svg2img": "1.0.0-beta.2",
|
|
||||||
"webdav": "^5.7.1",
|
"webdav": "^5.7.1",
|
||||||
"ws": "^8.18.0",
|
"ws": "^8.18.0",
|
||||||
"yaml": "^2.5.0"
|
"yaml": "^2.5.0"
|
||||||
|
|
861
pnpm-lock.yaml
861
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -1,20 +1,11 @@
|
||||||
import axios, { AxiosInstance } from 'axios'
|
import axios, { AxiosInstance } from 'axios'
|
||||||
import { getAppConfig, getControledMihomoConfig } from '../config'
|
import { getAppConfig, getControledMihomoConfig } from '../config'
|
||||||
import templateIcon from '../../../resources/iconTemplate.png?asset'
|
|
||||||
import svgIcon from '../../../resources/iconTemplate@2x.png?asset'
|
|
||||||
import { mainWindow } from '..'
|
import { mainWindow } from '..'
|
||||||
import WebSocket from 'ws'
|
import WebSocket from 'ws'
|
||||||
import { tray } from '../resolve/tray'
|
import { tray } from '../resolve/tray'
|
||||||
import { calcTraffic } from '../utils/calc'
|
import { calcTraffic } from '../utils/calc'
|
||||||
import { getRuntimeConfig } from './factory'
|
import { getRuntimeConfig } from './factory'
|
||||||
import { nativeImage } from 'electron'
|
|
||||||
import parseSvg from '../utils/parseSvg'
|
|
||||||
|
|
||||||
const icon = nativeImage.createFromPath(svgIcon)
|
|
||||||
icon.setTemplateImage(true)
|
|
||||||
const base64 = icon.toPNG().toString('base64')
|
|
||||||
let hasShowTraffic = false
|
|
||||||
let drawing = false
|
|
||||||
let axiosIns: AxiosInstance = null!
|
let axiosIns: AxiosInstance = null!
|
||||||
let mihomoTrafficWs: WebSocket | null = null
|
let mihomoTrafficWs: WebSocket | null = null
|
||||||
let trafficRetry = 10
|
let trafficRetry = 10
|
||||||
|
@ -180,7 +171,6 @@ export const stopMihomoTraffic = (): void => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mihomoTraffic = async (): Promise<void> => {
|
const mihomoTraffic = async (): Promise<void> => {
|
||||||
const { showTraffic = true } = await getAppConfig()
|
|
||||||
const controledMihomoConfig = await getControledMihomoConfig()
|
const controledMihomoConfig = await getControledMihomoConfig()
|
||||||
let server = controledMihomoConfig['external-controller']
|
let server = controledMihomoConfig['external-controller']
|
||||||
const secret = controledMihomoConfig.secret ?? ''
|
const secret = controledMihomoConfig.secret ?? ''
|
||||||
|
@ -194,38 +184,6 @@ const mihomoTraffic = async (): Promise<void> => {
|
||||||
const json = JSON.parse(data) as IMihomoTrafficInfo
|
const json = JSON.parse(data) as IMihomoTrafficInfo
|
||||||
trafficRetry = 10
|
trafficRetry = 10
|
||||||
mainWindow?.webContents.send('mihomoTraffic', json)
|
mainWindow?.webContents.send('mihomoTraffic', json)
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
if (showTraffic) {
|
|
||||||
if (drawing) return
|
|
||||||
drawing = true
|
|
||||||
const svgContent = `
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156 36">
|
|
||||||
<image height='36' width='36' href='data:image/png;base64,${base64}'/>
|
|
||||||
<text x='40' y='15' font-size='18' font-family="PingFang SC" font-weight='bold' text-anchor='start'>↑</text>
|
|
||||||
<text x='40' y='34' font-size='18' font-family="PingFang SC" font-weight='bold' text-anchor='start'>↓</text>
|
|
||||||
<text x='156' y='15' font-size='18' font-family="PingFang SC" font-weight='bold' text-anchor='end'>${calcTraffic(json.up)}/s</text>
|
|
||||||
<text x='156' y='34' font-size='18' font-family="PingFang SC" font-weight='bold' text-anchor='end'>${calcTraffic(json.down)}/s</text>
|
|
||||||
</svg>`
|
|
||||||
try {
|
|
||||||
const buffer = await parseSvg(svgContent)
|
|
||||||
const image = nativeImage.createFromBuffer(buffer).resize({ height: 16 })
|
|
||||||
image.setTemplateImage(true)
|
|
||||||
tray?.setImage(image)
|
|
||||||
hasShowTraffic = true
|
|
||||||
} catch (e) {
|
|
||||||
// ignore
|
|
||||||
} finally {
|
|
||||||
drawing = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (hasShowTraffic) {
|
|
||||||
const icon = nativeImage.createFromPath(templateIcon)
|
|
||||||
icon.setTemplateImage(true)
|
|
||||||
tray?.setImage(icon)
|
|
||||||
hasShowTraffic = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (process.platform !== 'linux') {
|
if (process.platform !== 'linux') {
|
||||||
tray?.setToolTip(
|
tray?.setToolTip(
|
||||||
'↑' +
|
'↑' +
|
||||||
|
|
|
@ -237,6 +237,11 @@ export async function createTray(): Promise<void> {
|
||||||
if (!useDockIcon) {
|
if (!useDockIcon) {
|
||||||
app.dock.hide()
|
app.dock.hide()
|
||||||
}
|
}
|
||||||
|
ipcMain.on('trayIconUpdate', async (_, png: string) => {
|
||||||
|
const image = nativeImage.createFromDataURL(png).resize({ height: 16 })
|
||||||
|
image.setTemplateImage(true)
|
||||||
|
tray?.setImage(image)
|
||||||
|
})
|
||||||
tray?.addListener('right-click', async () => {
|
tray?.addListener('right-click', async () => {
|
||||||
if (mainWindow?.isVisible()) {
|
if (mainWindow?.isVisible()) {
|
||||||
mainWindow?.close()
|
mainWindow?.close()
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
import { Worker } from 'worker_threads'
|
|
||||||
|
|
||||||
export default function parseSvg(svgStr: string): Promise<Buffer> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const worker = new Worker(workerString, {
|
|
||||||
eval: true,
|
|
||||||
env: {
|
|
||||||
__dirname
|
|
||||||
},
|
|
||||||
workerData: svgStr
|
|
||||||
})
|
|
||||||
worker.on('message', resolve)
|
|
||||||
worker.on('error', reject)
|
|
||||||
worker.on('exit', (code) => {
|
|
||||||
if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const workerString = `
|
|
||||||
const { parentPort, workerData } = require('worker_threads')
|
|
||||||
const path = require('path')
|
|
||||||
const svg2img = require(path.resolve(process.env.__dirname, '../../node_modules/svg2img'))
|
|
||||||
|
|
||||||
const svgStr = workerData
|
|
||||||
svg2img(svgStr, (err, buffer) => {
|
|
||||||
if (err) {
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
parentPort?.postMessage(buffer)
|
|
||||||
})
|
|
||||||
`
|
|
|
@ -6,7 +6,7 @@
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
<meta
|
<meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src *"
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data:;"
|
||||||
/>
|
/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -122,6 +122,7 @@ const Connections: React.FC = () => {
|
||||||
<TableCell>{item.metadata.process || item.metadata.sourceIP}</TableCell>
|
<TableCell>{item.metadata.process || item.metadata.sourceIP}</TableCell>
|
||||||
<TableCell className="max-w-[100px] text-ellipsis whitespace-nowrap overflow-hidden">
|
<TableCell className="max-w-[100px] text-ellipsis whitespace-nowrap overflow-hidden">
|
||||||
{item.metadata.host ||
|
{item.metadata.host ||
|
||||||
|
item.metadata.sniffHost ||
|
||||||
item.metadata.remoteDestination ||
|
item.metadata.remoteDestination ||
|
||||||
item.metadata.destinationIP}
|
item.metadata.destinationIP}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
|
@ -1,21 +1,33 @@
|
||||||
export function calcTraffic(byte: number): string {
|
export function calcTraffic(byte: number): string {
|
||||||
if (byte < 1024) return `${byte} B`
|
if (byte < 1024) return `${byte} B`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} KB`
|
if (byte < 1024) return `${formatNumString(byte)} KB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} MB`
|
if (byte < 1024) return `${formatNumString(byte)} MB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} GB`
|
if (byte < 1024) return `${formatNumString(byte)} GB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} TB`
|
if (byte < 1024) return `${formatNumString(byte)} TB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} PB`
|
if (byte < 1024) return `${formatNumString(byte)} PB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} EB`
|
if (byte < 1024) return `${formatNumString(byte)} EB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
if (byte < 1024) return `${byte.toFixed(2)} ZB`
|
if (byte < 1024) return `${formatNumString(byte)} ZB`
|
||||||
byte /= 1024
|
byte /= 1024
|
||||||
return `${byte.toFixed(2)} YB`
|
return `${formatNumString(byte)} YB`
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatNumString(num: number): string {
|
||||||
|
let str = num.toFixed(2)
|
||||||
|
if (str.length <= 5) return str
|
||||||
|
if (str.length == 6) {
|
||||||
|
str = num.toFixed(1)
|
||||||
|
return str
|
||||||
|
} else {
|
||||||
|
str = Math.round(num).toString()
|
||||||
|
return str
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calcPercent(
|
export function calcPercent(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user