feat: 统一应用品牌图标并修复 macOS 打包路径

This commit is contained in:
电摇小子
2026-07-14 11:07:35 +08:00
parent ce4b00bcd9
commit aebf56b3f7
10 changed files with 36 additions and 35 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 21 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 27 KiB

+3
View File
@@ -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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 27 KiB

+14 -4
View File
@@ -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 -1
View File
@@ -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"
+8
View File
@@ -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

+7 -18
View File
@@ -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>
) )
} }