feat: 统一应用品牌图标并修复 macOS 打包路径
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 27 KiB |
@@ -25,6 +25,7 @@ extraResources:
|
|||||||
filter:
|
filter:
|
||||||
- '**/*'
|
- '**/*'
|
||||||
win:
|
win:
|
||||||
|
icon: icon.ico
|
||||||
# WCDB's Windows runtime checks the host executable name. The dev runtime is
|
# WCDB's Windows runtime checks the host executable name. The dev runtime is
|
||||||
# electron.exe, so keep the packaged executable compatible while preserving
|
# electron.exe, so keep the packaged executable compatible while preserving
|
||||||
# WechatExplorer as the product/shortcut name.
|
# WechatExplorer as the product/shortcut name.
|
||||||
@@ -37,6 +38,7 @@ nsis:
|
|||||||
uninstallDisplayName: ${productName}
|
uninstallDisplayName: ${productName}
|
||||||
createDesktopShortcut: always
|
createDesktopShortcut: always
|
||||||
mac:
|
mac:
|
||||||
|
icon: icon.icns
|
||||||
entitlementsInherit: build/entitlements.mac.plist
|
entitlementsInherit: build/entitlements.mac.plist
|
||||||
extendInfo:
|
extendInfo:
|
||||||
# The bundled WCDB bridge accepts Electron as its internal host name. The
|
# The bundled WCDB bridge accepts Electron as its internal host name. The
|
||||||
@@ -51,6 +53,7 @@ mac:
|
|||||||
dmg:
|
dmg:
|
||||||
artifactName: ${name}-${version}-${arch}.${ext}
|
artifactName: ${name}-${version}-${arch}.${ext}
|
||||||
linux:
|
linux:
|
||||||
|
icon: icon.png
|
||||||
target:
|
target:
|
||||||
- AppImage
|
- AppImage
|
||||||
- snap
|
- snap
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 27 KiB |
@@ -11,6 +11,7 @@ import {
|
|||||||
dialog
|
dialog
|
||||||
} from 'electron'
|
} from 'electron'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
|
import { existsSync } from 'fs'
|
||||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||||
import icon from '../../resources/icon.png?asset'
|
import icon from '../../resources/icon.png?asset'
|
||||||
import { WechatDb } from './wechat-db'
|
import { WechatDb } from './wechat-db'
|
||||||
@@ -75,6 +76,9 @@ const keyServiceMac = new KeyServiceMac()
|
|||||||
const keyServiceWin = new KeyServiceWin()
|
const keyServiceWin = new KeyServiceWin()
|
||||||
let tray: Tray | null = null
|
let tray: Tray | null = null
|
||||||
|
|
||||||
|
const packagedIconPath = join(process.resourcesPath, 'resources', 'icon.png')
|
||||||
|
const appIconPath = existsSync(packagedIconPath) ? packagedIconPath : icon
|
||||||
|
|
||||||
// WCDB's Windows runtime checks the host application name during wcdb_init.
|
// WCDB's Windows runtime checks the host application name during wcdb_init.
|
||||||
// Mirroring WeFlow's name unblocks the -1006 init failure on Windows.
|
// Mirroring WeFlow's name unblocks the -1006 init failure on Windows.
|
||||||
app.setName(process.platform === 'win32' ? 'WeFlow' : 'WechatExplorer')
|
app.setName(process.platform === 'win32' ? 'WeFlow' : 'WechatExplorer')
|
||||||
@@ -99,7 +103,7 @@ function createWindow(): void {
|
|||||||
height: 800,
|
height: 800,
|
||||||
show: false,
|
show: false,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
...(process.platform === 'linux' ? { icon } : {}),
|
icon: appIconPath,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload: join(__dirname, '../preload/index.js'),
|
preload: join(__dirname, '../preload/index.js'),
|
||||||
sandbox: false
|
sandbox: false
|
||||||
@@ -140,7 +144,9 @@ app.whenReady().then(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 涓虹獥鍙h缃簲鐢ㄧ▼搴忕敤鎴锋ā鍨?ID
|
// 涓虹獥鍙h缃簲鐢ㄧ▼搴忕敤鎴锋ā鍨?ID
|
||||||
electronApp.setAppUserModelId('com.electron')
|
electronApp.setAppUserModelId('com.wechatexplorer.app')
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') app.dock?.setIcon(appIconPath)
|
||||||
|
|
||||||
// 鍦ㄥ紑鍙戠幆澧冧腑榛樿鎸?F12 鎵撳紑鎴栧叧闂?DevTools
|
// 鍦ㄥ紑鍙戠幆澧冧腑榛樿鎸?F12 鎵撳紑鎴栧叧闂?DevTools
|
||||||
// 鍦ㄧ敓浜х幆澧冧腑蹇界暐 CommandOrControl + R
|
// 鍦ㄧ敓浜х幆澧冧腑蹇界暐 CommandOrControl + R
|
||||||
@@ -674,8 +680,12 @@ function buildTrayMenu(): Menu {
|
|||||||
function setupTray(): void {
|
function setupTray(): void {
|
||||||
if (tray) return
|
if (tray) return
|
||||||
try {
|
try {
|
||||||
const image = nativeImage.createFromPath(join(__dirname, '../../resources/icon.png'))
|
const image = nativeImage.createFromPath(appIconPath)
|
||||||
tray = new Tray(image.isEmpty() ? nativeImage.createEmpty() : image)
|
const traySize = process.platform === 'darwin' ? 20 : 24
|
||||||
|
const trayImage = image.isEmpty()
|
||||||
|
? nativeImage.createEmpty()
|
||||||
|
: image.resize({ width: traySize, height: traySize, quality: 'best' })
|
||||||
|
tray = new Tray(trayImage)
|
||||||
tray.setToolTip('WechatExplorer')
|
tray.setToolTip('WechatExplorer')
|
||||||
tray.setContextMenu(buildTrayMenu())
|
tray.setContextMenu(buildTrayMenu())
|
||||||
tray.on('click', () => showMainWindow())
|
tray.on('click', () => showMainWindow())
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Electron</title>
|
<title>WechatExplorer</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/src/assets/brand-icon.svg" />
|
||||||
<!-- 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"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="256" height="256" rx="48" fill="#022C22" />
|
||||||
|
<rect x="0.5" y="0.5" width="255" height="255" rx="47.5" stroke="#064E3B" />
|
||||||
|
<rect x="128" y="16.2742" width="158" height="158" rx="15" transform="rotate(45 128 16.2742)" stroke="#14B8A6" stroke-opacity="0.3" stroke-width="2" />
|
||||||
|
<rect x="65" y="65" width="126" height="126" rx="11" stroke="#14B8A6" stroke-opacity="0.5" stroke-width="2" />
|
||||||
|
<rect x="104" y="104" width="48" height="48" rx="24" fill="#14B8A6" />
|
||||||
|
<rect x="192" y="48" width="16" height="16" rx="8" fill="#2DD4BF" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 656 B |
@@ -59,27 +59,16 @@ body {
|
|||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: var(--wxex-radius-md);
|
border-radius: 12px;
|
||||||
background: var(--wxex-brand);
|
background: transparent;
|
||||||
color: #ffffff;
|
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-brand svg {
|
.app-brand img {
|
||||||
width: 34px;
|
display: block;
|
||||||
height: 34px;
|
width: 42px;
|
||||||
}
|
height: 42px;
|
||||||
|
border-radius: 12px;
|
||||||
.app-brand path {
|
|
||||||
fill: none;
|
|
||||||
stroke: currentColor;
|
|
||||||
stroke-width: 1.8;
|
|
||||||
stroke-linecap: round;
|
|
||||||
stroke-linejoin: round;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-brand circle {
|
|
||||||
fill: currentColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-navigation {
|
.primary-navigation {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import { AccountSummary } from '../account/AccountSummary'
|
import { AccountSummary } from '../account/AccountSummary'
|
||||||
import { PrimaryNavigation } from './PrimaryNavigation'
|
import { PrimaryNavigation } from './PrimaryNavigation'
|
||||||
import { AppPage, PRIMARY_NAV_ITEMS } from './navigation'
|
import { AppPage, PRIMARY_NAV_ITEMS } from './navigation'
|
||||||
|
import brandIcon from '../../assets/brand-icon.svg'
|
||||||
|
|
||||||
interface SelfInfo {
|
interface SelfInfo {
|
||||||
wxid: string
|
wxid: string
|
||||||
@@ -22,18 +23,7 @@ interface AppShellProps {
|
|||||||
function BrandLogo(): React.ReactElement {
|
function BrandLogo(): React.ReactElement {
|
||||||
return (
|
return (
|
||||||
<div className="app-brand" title="WechatExplorer" aria-label="WechatExplorer">
|
<div className="app-brand" title="WechatExplorer" aria-label="WechatExplorer">
|
||||||
<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false">
|
<img src={brandIcon} alt="" aria-hidden="true" />
|
||||||
<path d="M13 15.5 20 10l7 5.5" />
|
|
||||||
<path d="M13 24.5 20 30l7-5.5" />
|
|
||||||
<path d="M13 15.5v9" />
|
|
||||||
<path d="M27 15.5v9" />
|
|
||||||
<circle cx="20" cy="10" r="2.6" />
|
|
||||||
<circle cx="13" cy="15.5" r="2.6" />
|
|
||||||
<circle cx="27" cy="15.5" r="2.6" />
|
|
||||||
<circle cx="13" cy="24.5" r="2.6" />
|
|
||||||
<circle cx="27" cy="24.5" r="2.6" />
|
|
||||||
<circle cx="20" cy="30" r="2.6" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||