mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-02-10 11:40:28 +08:00
chore: ensure ESLint passes and format code
This commit is contained in:
parent
e9c72ce448
commit
842e7f1002
@ -336,9 +336,11 @@ function getSysproxyNodeName() {
|
|||||||
|
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'win32':
|
case 'win32':
|
||||||
if (arch === 'x64') return isWin7Build ? 'sysproxy.win32-x64-msvc-win7.node' : 'sysproxy.win32-x64-msvc.node'
|
if (arch === 'x64')
|
||||||
|
return isWin7Build ? 'sysproxy.win32-x64-msvc-win7.node' : 'sysproxy.win32-x64-msvc.node'
|
||||||
if (arch === 'arm64') return 'sysproxy.win32-arm64-msvc.node'
|
if (arch === 'arm64') return 'sysproxy.win32-arm64-msvc.node'
|
||||||
if (arch === 'ia32') return isWin7Build ? 'sysproxy.win32-ia32-msvc-win7.node' : 'sysproxy.win32-ia32-msvc.node'
|
if (arch === 'ia32')
|
||||||
|
return isWin7Build ? 'sysproxy.win32-ia32-msvc-win7.node' : 'sysproxy.win32-ia32-msvc.node'
|
||||||
break
|
break
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
if (arch === 'x64') return 'sysproxy.darwin-x64.node'
|
if (arch === 'x64') return 'sysproxy.darwin-x64.node'
|
||||||
|
|||||||
@ -37,7 +37,10 @@ export async function getControledMihomoConfig(force = false): Promise<Partial<I
|
|||||||
// 清理端口字段中的 NaN 值,恢复为默认值
|
// 清理端口字段中的 NaN 值,恢复为默认值
|
||||||
const portFields = ['mixed-port', 'socks-port', 'port', 'redir-port', 'tproxy-port'] as const
|
const portFields = ['mixed-port', 'socks-port', 'port', 'redir-port', 'tproxy-port'] as const
|
||||||
for (const field of portFields) {
|
for (const field of portFields) {
|
||||||
if (typeof controledMihomoConfig[field] !== 'number' || Number.isNaN(controledMihomoConfig[field])) {
|
if (
|
||||||
|
typeof controledMihomoConfig[field] !== 'number' ||
|
||||||
|
Number.isNaN(controledMihomoConfig[field])
|
||||||
|
) {
|
||||||
controledMihomoConfig[field] = defaultControledMihomoConfig[field]
|
controledMihomoConfig[field] = defaultControledMihomoConfig[field]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,8 +67,7 @@ export async function changeCurrentProfile(id: string): Promise<void> {
|
|||||||
// 使用队列确保 profile 切换串行执行,避免竞态条件
|
// 使用队列确保 profile 切换串行执行,避免竞态条件
|
||||||
let taskError: unknown = null
|
let taskError: unknown = null
|
||||||
changeProfileQueue = changeProfileQueue
|
changeProfileQueue = changeProfileQueue
|
||||||
.catch(() => {
|
.catch(() => {})
|
||||||
})
|
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
const { current } = await getProfileConfig()
|
const { current } = await getProfileConfig()
|
||||||
if (current === id) return
|
if (current === id) return
|
||||||
@ -221,7 +220,7 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
const newItem: IProfileItem = {
|
const newItem: IProfileItem = {
|
||||||
id,
|
id,
|
||||||
name: item.name || (item.type === 'remote' ? 'Remote File' : 'Local File'),
|
name: item.name || (item.type === 'remote' ? 'Remote File' : 'Local File'),
|
||||||
type: item.type!,
|
type: item.type || 'local',
|
||||||
url: item.url,
|
url: item.url,
|
||||||
substore: item.substore || false,
|
substore: item.substore || false,
|
||||||
interval: item.interval || 0,
|
interval: item.interval || 0,
|
||||||
@ -255,18 +254,18 @@ export async function createProfile(item: Partial<IProfileItem>): Promise<IProfi
|
|||||||
substore: newItem.substore || false
|
substore: newItem.substore || false
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchSub = (useProxy: boolean, timeout: number) =>
|
const fetchSub = (useProxy: boolean, timeout: number) =>
|
||||||
fetchAndValidateSubscription({ ...baseOptions, useProxy, timeout })
|
fetchAndValidateSubscription({ ...baseOptions, useProxy, timeout })
|
||||||
|
|
||||||
let result: FetchResult
|
let result: FetchResult
|
||||||
if (newItem.useProxy || newItem.substore) {
|
if (newItem.useProxy || newItem.substore) {
|
||||||
result = await fetchSub(newItem.useProxy!, userItemTimeoutMs)
|
result = await fetchSub(Boolean(newItem.useProxy), userItemTimeoutMs)
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
result = await fetchSub(false, userItemTimeoutMs)
|
result = await fetchSub(false, userItemTimeoutMs)
|
||||||
} catch (directError) {
|
} catch (directError) {
|
||||||
try {
|
try {
|
||||||
// smart fallback
|
// smart fallback
|
||||||
result = await fetchSub(true, subscriptionTimeout)
|
result = await fetchSub(true, subscriptionTimeout)
|
||||||
} catch {
|
} catch {
|
||||||
throw directError
|
throw directError
|
||||||
|
|||||||
@ -44,11 +44,7 @@ async function getOriginDNS(): Promise<void> {
|
|||||||
async function setDNS(dns: string): Promise<void> {
|
async function setDNS(dns: string): Promise<void> {
|
||||||
const service = await getDefaultService()
|
const service = await getDefaultService()
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
await axios.post('http://localhost/dns', { service, dns }, { socketPath: helperSocketPath })
|
||||||
'http://localhost/dns',
|
|
||||||
{ service, dns },
|
|
||||||
{ socketPath: helperSocketPath }
|
|
||||||
)
|
|
||||||
} catch {
|
} catch {
|
||||||
// fallback to osascript if helper not available
|
// fallback to osascript if helper not available
|
||||||
const shell = `networksetup -setdnsservers "${service}" ${dns}`
|
const shell = `networksetup -setdnsservers "${service}" ${dns}`
|
||||||
|
|||||||
@ -135,10 +135,7 @@ interface CoreConfig {
|
|||||||
|
|
||||||
// 准备核心配置
|
// 准备核心配置
|
||||||
async function prepareCore(detached: boolean, skipStop = false): Promise<CoreConfig> {
|
async function prepareCore(detached: boolean, skipStop = false): Promise<CoreConfig> {
|
||||||
const [appConfig, mihomoConfig] = await Promise.all([
|
const [appConfig, mihomoConfig] = await Promise.all([getAppConfig(), getControledMihomoConfig()])
|
||||||
getAppConfig(),
|
|
||||||
getControledMihomoConfig()
|
|
||||||
])
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
core = 'mihomo',
|
core = 'mihomo',
|
||||||
@ -215,7 +212,10 @@ function spawnCoreProcess(config: CoreConfig): ChildProcess {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (process.platform === 'win32' && proc.pid) {
|
if (process.platform === 'win32' && proc.pid) {
|
||||||
os.setPriority(proc.pid, os.constants.priority[cpuPriority as keyof typeof os.constants.priority])
|
os.setPriority(
|
||||||
|
proc.pid,
|
||||||
|
os.constants.priority[cpuPriority as keyof typeof os.constants.priority]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!detached) {
|
if (!detached) {
|
||||||
@ -294,7 +294,10 @@ function setupCoreListeners(
|
|||||||
new Promise((innerResolve) => {
|
new Promise((innerResolve) => {
|
||||||
proc.stdout?.on('data', async (innerData) => {
|
proc.stdout?.on('data', async (innerData) => {
|
||||||
if (
|
if (
|
||||||
innerData.toString().toLowerCase().includes('start initial compatible provider default')
|
innerData
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes('start initial compatible provider default')
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
mainWindow?.webContents.send('groupsUpdated')
|
mainWindow?.webContents.send('groupsUpdated')
|
||||||
|
|||||||
@ -191,7 +191,9 @@ async function checkHighPrivilegeMihomoProcess(): Promise<boolean> {
|
|||||||
for (const executable of mihomoExecutables) {
|
for (const executable of mihomoExecutables) {
|
||||||
try {
|
try {
|
||||||
const { stdout } = await execPromise(`ps aux | grep ${executable} | grep -v grep`)
|
const { stdout } = await execPromise(`ps aux | grep ${executable} | grep -v grep`)
|
||||||
const lines = stdout.split('\n').filter((line) => line.trim() && line.includes(executable))
|
const lines = stdout
|
||||||
|
.split('\n')
|
||||||
|
.filter((line) => line.trim() && line.includes(executable))
|
||||||
|
|
||||||
if (lines.length > 0) {
|
if (lines.length > 0) {
|
||||||
foundProcesses = true
|
foundProcesses = true
|
||||||
@ -337,7 +339,9 @@ export async function showErrorDialog(title: string, message: string): Promise<v
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function validateTunPermissionsOnStartup(_restartCore: () => Promise<void>): Promise<void> {
|
export async function validateTunPermissionsOnStartup(
|
||||||
|
_restartCore: () => Promise<void>
|
||||||
|
): Promise<void> {
|
||||||
const { getControledMihomoConfig } = await import('../config')
|
const { getControledMihomoConfig } = await import('../config')
|
||||||
const { tun } = await getControledMihomoConfig()
|
const { tun } = await getControledMihomoConfig()
|
||||||
|
|
||||||
@ -349,7 +353,9 @@ export async function validateTunPermissionsOnStartup(_restartCore: () => Promis
|
|||||||
|
|
||||||
if (!hasPermissions) {
|
if (!hasPermissions) {
|
||||||
// 启动时没有权限,静默禁用 TUN,不弹窗打扰用户
|
// 启动时没有权限,静默禁用 TUN,不弹窗打扰用户
|
||||||
managerLogger.warn('TUN is enabled but insufficient permissions detected, auto-disabling TUN...')
|
managerLogger.warn(
|
||||||
|
'TUN is enabled but insufficient permissions detected, auto-disabling TUN...'
|
||||||
|
)
|
||||||
await patchControledMihomoConfig({ tun: { enable: false } })
|
await patchControledMihomoConfig({ tun: { enable: false } })
|
||||||
|
|
||||||
const { mainWindow } = await import('../index')
|
const { mainWindow } = await import('../index')
|
||||||
|
|||||||
@ -114,9 +114,7 @@ async function disableSysProxy(): Promise<void> {
|
|||||||
await stopPacServer()
|
await stopPacServer()
|
||||||
|
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
await helperRequest(() =>
|
await helperRequest(() => axios.get('http://localhost/off', { socketPath: helperSocketPath }))
|
||||||
axios.get('http://localhost/off', { socketPath: helperSocketPath })
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// Windows / Linux 直接使用 sysproxy-rs
|
// Windows / Linux 直接使用 sysproxy-rs
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import { spawnSync } from 'child_process'
|
||||||
import plist from 'plist'
|
import plist from 'plist'
|
||||||
import { findBestAppPath, isIOSApp } from './icon'
|
import { findBestAppPath, isIOSApp } from './icon'
|
||||||
import { spawnSync } from 'child_process'
|
|
||||||
|
|
||||||
export async function getAppName(appPath: string): Promise<string> {
|
export async function getAppName(appPath: string): Promise<string> {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
@ -20,7 +20,7 @@ export async function getAppName(appPath: string): Promise<string> {
|
|||||||
try {
|
try {
|
||||||
const appName = getLocalizedAppName(targetPath)
|
const appName = getLocalizedAppName(targetPath)
|
||||||
if (appName) return appName
|
if (appName) return appName
|
||||||
} catch (err) {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ export async function getAppName(appPath: string): Promise<string> {
|
|||||||
} else {
|
} else {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,8 +74,7 @@ export async function request<T = unknown>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanup = (): void => {
|
const cleanup = (): void => {}
|
||||||
}
|
|
||||||
|
|
||||||
setupProxy()
|
setupProxy()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { createWriteStream, createReadStream , existsSync, rmSync } from 'fs'
|
import { createWriteStream, createReadStream, existsSync, rmSync } from 'fs'
|
||||||
import { writeFile } from 'fs/promises'
|
import { writeFile } from 'fs/promises'
|
||||||
import { execSync } from 'child_process'
|
import { execSync } from 'child_process'
|
||||||
import { platform } from 'os'
|
import { platform } from 'os'
|
||||||
|
|||||||
@ -190,7 +190,10 @@ async function initFiles(): Promise<void> {
|
|||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const code = (error as NodeJS.ErrnoException).code
|
const code = (error as NodeJS.ErrnoException).code
|
||||||
// 文件被占用或权限问题,如果目标已存在则跳过
|
// 文件被占用或权限问题,如果目标已存在则跳过
|
||||||
if ((code === 'EPERM' || code === 'EBUSY' || code === 'EACCES') && existsSync(targetPath)) {
|
if (
|
||||||
|
(code === 'EPERM' || code === 'EBUSY' || code === 'EACCES') &&
|
||||||
|
existsSync(targetPath)
|
||||||
|
) {
|
||||||
await initLogger.warn(`Skipping ${file}: file is in use or permission denied`)
|
await initLogger.warn(`Skipping ${file}: file is in use or permission denied`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -318,7 +321,11 @@ async function migrateMihomoConfig(): Promise<void> {
|
|||||||
config['skip-auth-prefixes'][0] === '127.0.0.1/32' &&
|
config['skip-auth-prefixes'][0] === '127.0.0.1/32' &&
|
||||||
!config['skip-auth-prefixes'].includes('::1/128')
|
!config['skip-auth-prefixes'].includes('::1/128')
|
||||||
) {
|
) {
|
||||||
patches['skip-auth-prefixes'] = ['127.0.0.1/32', '::1/128', ...config['skip-auth-prefixes'].slice(1)]
|
patches['skip-auth-prefixes'] = [
|
||||||
|
'127.0.0.1/32',
|
||||||
|
'::1/128',
|
||||||
|
...config['skip-auth-prefixes'].slice(1)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他默认值
|
// 其他默认值
|
||||||
|
|||||||
@ -12,7 +12,12 @@ export let mainWindow: BrowserWindow | null = null
|
|||||||
let quitTimeout: NodeJS.Timeout | null = null
|
let quitTimeout: NodeJS.Timeout | null = null
|
||||||
|
|
||||||
export async function createWindow(): Promise<void> {
|
export async function createWindow(): Promise<void> {
|
||||||
const { useWindowFrame = false, silentStart = false, autoQuitWithoutCore = false, autoQuitWithoutCoreDelay = 60 } = await getAppConfig()
|
const {
|
||||||
|
useWindowFrame = false,
|
||||||
|
silentStart = false,
|
||||||
|
autoQuitWithoutCore = false,
|
||||||
|
autoQuitWithoutCoreDelay = 60
|
||||||
|
} = await getAppConfig()
|
||||||
const mainWindowState = windowStateKeeper({
|
const mainWindowState = windowStateKeeper({
|
||||||
defaultWidth: 800,
|
defaultWidth: 800,
|
||||||
defaultHeight: 600,
|
defaultHeight: 600,
|
||||||
@ -47,7 +52,11 @@ export async function createWindow(): Promise<void> {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mainWindowState.manage(mainWindow)
|
mainWindowState.manage(mainWindow)
|
||||||
setupWindowEvents(mainWindow, mainWindowState, { silentStart, autoQuitWithoutCore, autoQuitWithoutCoreDelay })
|
setupWindowEvents(mainWindow, mainWindowState, {
|
||||||
|
silentStart,
|
||||||
|
autoQuitWithoutCore,
|
||||||
|
autoQuitWithoutCoreDelay
|
||||||
|
})
|
||||||
|
|
||||||
if (is.dev) {
|
if (is.dev) {
|
||||||
mainWindow.webContents.openDevTools()
|
mainWindow.webContents.openDevTools()
|
||||||
|
|||||||
@ -34,8 +34,10 @@ function getBindingName() {
|
|||||||
const win7 = isWindows7()
|
const win7 = isWindows7()
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'win32':
|
case 'win32':
|
||||||
if (arch === 'x64') return win7 ? 'sysproxy.win32-x64-msvc-win7.node' : 'sysproxy.win32-x64-msvc.node'
|
if (arch === 'x64')
|
||||||
if (arch === 'ia32') return win7 ? 'sysproxy.win32-ia32-msvc-win7.node' : 'sysproxy.win32-ia32-msvc.node'
|
return win7 ? 'sysproxy.win32-x64-msvc-win7.node' : 'sysproxy.win32-x64-msvc.node'
|
||||||
|
if (arch === 'ia32')
|
||||||
|
return win7 ? 'sysproxy.win32-ia32-msvc-win7.node' : 'sysproxy.win32-ia32-msvc.node'
|
||||||
if (arch === 'arm64') return 'sysproxy.win32-arm64-msvc.node'
|
if (arch === 'arm64') return 'sysproxy.win32-arm64-msvc.node'
|
||||||
break
|
break
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
|
|||||||
@ -169,4 +169,4 @@ const ConnectionItem = memo(ConnectionItemComponent, (prevProps, nextProps) => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
export default ConnectionItem
|
export default ConnectionItem
|
||||||
|
|||||||
@ -126,7 +126,9 @@ const ProxyProvider: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
title={
|
title={
|
||||||
provider.vehicleType === 'File' ? t('common.editor.edit') : t('common.viewer.view')
|
provider.vehicleType === 'File'
|
||||||
|
? t('common.editor.edit')
|
||||||
|
: t('common.viewer.view')
|
||||||
}
|
}
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -138,7 +138,9 @@ const RuleProvider: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
isIconOnly
|
isIconOnly
|
||||||
title={
|
title={
|
||||||
provider.vehicleType === 'File' ? t('common.editor.edit') : t('common.viewer.view')
|
provider.vehicleType === 'File'
|
||||||
|
? t('common.editor.edit')
|
||||||
|
: t('common.viewer.view')
|
||||||
}
|
}
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -53,12 +53,14 @@ const OverrideConfigContextWrapper: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
)
|
)
|
||||||
|
|
||||||
const setOverrideConfig = useCallback(
|
const setOverrideConfig = useCallback(
|
||||||
(cfg: IOverrideConfig) => withErrorHandling(() => set(cfg), 'common.error.saveOverrideConfigFailed')(),
|
(cfg: IOverrideConfig) =>
|
||||||
|
withErrorHandling(() => set(cfg), 'common.error.saveOverrideConfigFailed')(),
|
||||||
[withErrorHandling]
|
[withErrorHandling]
|
||||||
)
|
)
|
||||||
|
|
||||||
const addOverrideItem = useCallback(
|
const addOverrideItem = useCallback(
|
||||||
(item: Partial<IOverrideItem>) => withErrorHandling(() => add(item), 'common.error.addOverrideFailed')(),
|
(item: Partial<IOverrideItem>) =>
|
||||||
|
withErrorHandling(() => add(item), 'common.error.addOverrideFailed')(),
|
||||||
[withErrorHandling]
|
[withErrorHandling]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,7 +70,8 @@ const OverrideConfigContextWrapper: React.FC<{ children: ReactNode }> = ({ child
|
|||||||
)
|
)
|
||||||
|
|
||||||
const updateOverrideItem = useCallback(
|
const updateOverrideItem = useCallback(
|
||||||
(item: IOverrideItem) => withErrorHandling(() => update(item), 'common.error.updateOverrideFailed')(),
|
(item: IOverrideItem) =>
|
||||||
|
withErrorHandling(() => update(item), 'common.error.updateOverrideFailed')(),
|
||||||
[withErrorHandling]
|
[withErrorHandling]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,25 @@
|
|||||||
import BasePage from '@renderer/components/base/base-page'
|
import BasePage from '@renderer/components/base/base-page'
|
||||||
import { mihomoCloseAllConnections, mihomoCloseConnection, getIconDataURL, getAppName } from '@renderer/utils/ipc'
|
import {
|
||||||
|
mihomoCloseAllConnections,
|
||||||
|
mihomoCloseConnection,
|
||||||
|
getIconDataURL,
|
||||||
|
getAppName
|
||||||
|
} from '@renderer/utils/ipc'
|
||||||
import { Key, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { Key, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { Badge, Button, Divider, Input, Select, SelectItem, Tab, Tabs , Dropdown, DropdownTrigger, DropdownMenu, DropdownItem } from '@heroui/react'
|
import {
|
||||||
|
Badge,
|
||||||
|
Button,
|
||||||
|
Divider,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
SelectItem,
|
||||||
|
Tab,
|
||||||
|
Tabs,
|
||||||
|
Dropdown,
|
||||||
|
DropdownTrigger,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownItem
|
||||||
|
} from '@heroui/react'
|
||||||
import { calcTraffic } from '@renderer/utils/calc'
|
import { calcTraffic } from '@renderer/utils/calc'
|
||||||
import ConnectionItem from '@renderer/components/connections/connection-item'
|
import ConnectionItem from '@renderer/components/connections/connection-item'
|
||||||
import ConnectionTable from '@renderer/components/connections/connection-table'
|
import ConnectionTable from '@renderer/components/connections/connection-table'
|
||||||
@ -239,7 +257,7 @@ const Connections: React.FC = () => {
|
|||||||
: `data:image/png;base64,${rawBase64}`
|
: `data:image/png;base64,${rawBase64}`
|
||||||
|
|
||||||
let processedDataURL = fullDataURL
|
let processedDataURL = fullDataURL
|
||||||
if (platform != 'darwin') {
|
if (platform !== 'darwin') {
|
||||||
processedDataURL = await cropAndPadTransparent(fullDataURL)
|
processedDataURL = await cropAndPadTransparent(fullDataURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -78,4 +78,4 @@ function clearHalfIconCache(): void {
|
|||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,10 @@ export async function cropAndPadTransparent(
|
|||||||
const canvas = document.createElement('canvas')
|
const canvas = document.createElement('canvas')
|
||||||
canvas.width = img.width
|
canvas.width = img.width
|
||||||
canvas.height = img.height
|
canvas.height = img.height
|
||||||
const ctx = canvas.getContext('2d')!
|
const ctx = canvas.getContext('2d')
|
||||||
|
if (!ctx) {
|
||||||
|
throw new Error('Failed to get 2D context')
|
||||||
|
}
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
ctx.drawImage(img, 0, 0)
|
ctx.drawImage(img, 0, 0)
|
||||||
|
|
||||||
@ -59,7 +62,10 @@ export async function cropAndPadTransparent(
|
|||||||
const outCanvas = document.createElement('canvas')
|
const outCanvas = document.createElement('canvas')
|
||||||
outCanvas.width = finalSize
|
outCanvas.width = finalSize
|
||||||
outCanvas.height = finalSize
|
outCanvas.height = finalSize
|
||||||
const outCtx = outCanvas.getContext('2d')!
|
const outCtx = outCanvas.getContext('2d')
|
||||||
|
if (!outCtx) {
|
||||||
|
throw new Error('Failed to get 2D context')
|
||||||
|
}
|
||||||
outCtx.clearRect(0, 0, finalSize, finalSize)
|
outCtx.clearRect(0, 0, finalSize, finalSize)
|
||||||
outCtx.drawImage(
|
outCtx.drawImage(
|
||||||
canvas,
|
canvas,
|
||||||
@ -74,4 +80,4 @@ export async function cropAndPadTransparent(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return outCanvas.toDataURL('image/png')
|
return outCanvas.toDataURL('image/png')
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user