diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0e613f1..3ff05e6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -68,6 +68,12 @@ jobs:
- name: Build Awesome Mac image
run: docker image build -t wxmp .
+ - uses: actions/upload-artifact@v3
+ with:
+ name: webiste
+ path: |
+ website/build/**
+
- name: Tags & Push image (latest)
run: |
echo "outputs.tag - ${{ steps.changelog.outputs.version }}"
@@ -96,4 +102,35 @@ jobs:
run: |
echo "version: v${{ steps.changelog.outputs.version }}"
docker tag ghcr.io/jaywcjlove/wxmp:latest ghcr.io/jaywcjlove/wxmp:${{steps.changelog.outputs.version}}
- docker push ghcr.io/jaywcjlove/wxmp:${{steps.changelog.outputs.version}}
\ No newline at end of file
+ docker push ghcr.io/jaywcjlove/wxmp:${{steps.changelog.outputs.version}}
+
+ build_macos:
+ needs: [build-deploy]
+ runs-on: macos-latest
+ timeout-minutes: 30
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 16
+
+ - run: npm install
+ - run: npm run hoist
+ - run: npm run build
+
+ - uses: actions/download-artifact@v3
+ with:
+ name: webiste
+ path: website/build
+
+ - name: electron-builder install-app-deps
+ working-directory: electron/app
+ run: npm run deps
+
+ - run: npm run build:app
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: tools-macos-zip
+ path: |
+ electron/app/dist/*.zip
\ No newline at end of file
diff --git a/README.md b/README.md
index efa0168..4522e71 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@
- [ ] 支持色盘取色,快速替换文章整体色调
- [x] 支持 URL 参数加载 Markdown 内容。
- [x] 支持 URL 参数选择预览主题。
+- [ ] 使用 electron 生成桌面应用。
### 支持代码块样式
diff --git a/electron/app/.gitignore b/electron/app/.gitignore
new file mode 100644
index 0000000..f7a95c7
--- /dev/null
+++ b/electron/app/.gitignore
@@ -0,0 +1,2 @@
+dist
+website
\ No newline at end of file
diff --git a/electron/app/assets/entitlements.mac.plist b/electron/app/assets/entitlements.mac.plist
new file mode 100644
index 0000000..bb87459
--- /dev/null
+++ b/electron/app/assets/entitlements.mac.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+
+
\ No newline at end of file
diff --git a/electron/app/config.json b/electron/app/config.json
new file mode 100644
index 0000000..127e0e9
--- /dev/null
+++ b/electron/app/config.json
@@ -0,0 +1,35 @@
+{
+ "productName": "wxmp",
+ "appId": "com.wangchujiang.wxmp",
+ "asar": true,
+ "directories": {
+ "output": "dist"
+ },
+ "mac": {
+ "icon": "tools.icns",
+ "target": {
+ "target": "default",
+ "arch": ["arm64", "x64"]
+ },
+ "category": "public.app-category.developer-tools",
+ "type": "distribution",
+ "entitlements": "assets/entitlements.mac.plist",
+ "entitlementsInherit": "assets/entitlements.mac.plist"
+ },
+ "linux": {
+ "icon": "tools.icns",
+ "description": "微信公众号 Markdown 编辑器",
+ "category": "Development",
+ "target": ["deb", "rpm"],
+ "desktop": {
+ "Name": "Web Tools"
+ }
+ },
+ "win": {
+ "icon": "tools.ico",
+ "target": {
+ "target": "nsis",
+ "arch": ["x64", "ia32"]
+ }
+ }
+}
diff --git a/electron/app/icon.icns b/electron/app/icon.icns
new file mode 100644
index 0000000..dc203d6
Binary files /dev/null and b/electron/app/icon.icns differ
diff --git a/electron/app/icons.iconset/icon_128x128.png b/electron/app/icons.iconset/icon_128x128.png
new file mode 100644
index 0000000..84943b2
Binary files /dev/null and b/electron/app/icons.iconset/icon_128x128.png differ
diff --git a/electron/app/icons.iconset/icon_128x128@2x.png b/electron/app/icons.iconset/icon_128x128@2x.png
new file mode 100644
index 0000000..0e35702
Binary files /dev/null and b/electron/app/icons.iconset/icon_128x128@2x.png differ
diff --git a/electron/app/icons.iconset/icon_16x16.png b/electron/app/icons.iconset/icon_16x16.png
new file mode 100644
index 0000000..9dc5a2e
Binary files /dev/null and b/electron/app/icons.iconset/icon_16x16.png differ
diff --git a/electron/app/icons.iconset/icon_16x16@2x.png b/electron/app/icons.iconset/icon_16x16@2x.png
new file mode 100644
index 0000000..54d9889
Binary files /dev/null and b/electron/app/icons.iconset/icon_16x16@2x.png differ
diff --git a/electron/app/icons.iconset/icon_256x256.png b/electron/app/icons.iconset/icon_256x256.png
new file mode 100644
index 0000000..0e35702
Binary files /dev/null and b/electron/app/icons.iconset/icon_256x256.png differ
diff --git a/electron/app/icons.iconset/icon_256x256@2x.png b/electron/app/icons.iconset/icon_256x256@2x.png
new file mode 100644
index 0000000..fed7da8
Binary files /dev/null and b/electron/app/icons.iconset/icon_256x256@2x.png differ
diff --git a/electron/app/icons.iconset/icon_32x32.png b/electron/app/icons.iconset/icon_32x32.png
new file mode 100644
index 0000000..54d9889
Binary files /dev/null and b/electron/app/icons.iconset/icon_32x32.png differ
diff --git a/electron/app/icons.iconset/icon_32x32@2x.png b/electron/app/icons.iconset/icon_32x32@2x.png
new file mode 100644
index 0000000..bee588d
Binary files /dev/null and b/electron/app/icons.iconset/icon_32x32@2x.png differ
diff --git a/electron/app/icons.iconset/icon_512x512.png b/electron/app/icons.iconset/icon_512x512.png
new file mode 100644
index 0000000..fed7da8
Binary files /dev/null and b/electron/app/icons.iconset/icon_512x512.png differ
diff --git a/electron/app/icons.iconset/icon_512x512@2x.png b/electron/app/icons.iconset/icon_512x512@2x.png
new file mode 100644
index 0000000..8ac194c
Binary files /dev/null and b/electron/app/icons.iconset/icon_512x512@2x.png differ
diff --git a/electron/app/logo.png b/electron/app/logo.png
new file mode 100644
index 0000000..fed7da8
Binary files /dev/null and b/electron/app/logo.png differ
diff --git a/electron/app/main.js b/electron/app/main.js
new file mode 100644
index 0000000..721418a
--- /dev/null
+++ b/electron/app/main.js
@@ -0,0 +1,15 @@
+const path = require('path');
+const { App } = require('@wcj/wxmp-main');
+
+(async () => {
+ const options = {};
+ if (process.env.NODE_ENV === 'development') {
+ options.preload = require.resolve('@wcj/wxmp-preload');
+ options.webpath = require.resolve('website/build/index.html');
+ } else {
+ options.preload = path.resolve(__dirname, 'website/index.js');
+ options.webpath = 'website/index.html';
+ }
+ const app = new App();
+ await app.createWindow(options);
+})();
diff --git a/electron/app/package.json b/electron/app/package.json
new file mode 100644
index 0000000..9fc91ea
--- /dev/null
+++ b/electron/app/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "wxmp",
+ "description": "微信公众号 Markdown 编辑器",
+ "homepage": "https://github.com/jaywcjlove/wxmp.git",
+ "version": "2.1.0",
+ "main": "main.js",
+ "author": "Kenny Wong <398188662@qq.com>",
+ "private": true,
+ "scripts": {
+ "deps": "electron-builder install-app-deps",
+ "start": "cross-env NODE_ENV=development ELECTRON_DISABLE_SECURITY_WARNINGS=true electron .",
+ "start:production": "cross-env NODE_ENV=production ELECTRON_DISABLE_SECURITY_WARNINGS=true electron .",
+ "dist-win32": "electron-builder --win --ia32 --config config.json",
+ "dist-win64": "electron-builder --win --x64 --config config.json",
+ "dist-mac": "electron-builder --mac --universal --config config.json",
+ "dist-linux": "electron-builder --linux --config config.json",
+ "copy": "cpy './node_modules/@wcj/wxmp-preload/lib/*.js' './node_modules/website/build/**' website",
+ "build": "npm run copy && cross-env NODE_ENV=production electron-builder build --publish=never --config config.json"
+ },
+ "dependencies": {
+ "@wcj/wxmp-main": "2.1.0"
+ },
+ "devDependencies": {
+ "@wcj/wxmp-preload": "2.1.0",
+ "cpy-cli": "4.1.0",
+ "electron": "19.0.5",
+ "electron-builder": "23.1.0",
+ "website": "2.1.0"
+ }
+}
diff --git a/electron/main/.gitignore b/electron/main/.gitignore
new file mode 100644
index 0000000..7951405
--- /dev/null
+++ b/electron/main/.gitignore
@@ -0,0 +1 @@
+lib
\ No newline at end of file
diff --git a/electron/main/package.json b/electron/main/package.json
new file mode 100644
index 0000000..f8937f5
--- /dev/null
+++ b/electron/main/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@wcj/wxmp-main",
+ "version": "2.1.0",
+ "main": "./lib/index.js",
+ "private": true,
+ "scripts": {
+ "build": "tsbb build --disable-babel --file-names src/index.ts",
+ "watch": "tsbb watch --disable-babel --file-names src/index.ts"
+ },
+ "files": [
+ "lib"
+ ],
+ "devDependencies": {
+ "electron": "19.0.5"
+ }
+}
diff --git a/electron/main/src/Menu.ts b/electron/main/src/Menu.ts
new file mode 100644
index 0000000..cab5a9d
--- /dev/null
+++ b/electron/main/src/Menu.ts
@@ -0,0 +1,56 @@
+import { app, Menu, MenuItem, MenuItemConstructorOptions } from 'electron';
+const isMac = process.platform === 'darwin';
+const template = [
+ // { role: 'appMenu' }
+ ...(isMac
+ ? [
+ {
+ label: app.name,
+ submenu: [
+ { role: 'about' },
+ { type: 'separator' },
+ { role: 'services' },
+ { type: 'separator' },
+ { role: 'hide' },
+ { role: 'hideOthers' },
+ { role: 'unhide' },
+ { type: 'separator' },
+ { role: 'quit' },
+ ],
+ },
+ ]
+ : []),
+ { role: 'editMenu' },
+ {
+ label: 'Window',
+ submenu: [
+ { role: 'minimize' },
+ { role: 'zoom' },
+ ...(isMac
+ ? [{ type: 'separator' }, { role: 'front' }, { type: 'separator' }, { role: 'window' }]
+ : [{ role: 'close' }]),
+ ],
+ },
+ {
+ role: 'help',
+ submenu: [
+ {
+ label: 'Open Source for Github',
+ click: async () => {
+ const { shell } = require('electron');
+ await shell.openExternal('https://github.com/jaywcjlove/wxmp');
+ },
+ },
+ {
+ label: 'Online Website',
+ click: async () => {
+ const { shell } = require('electron');
+ await shell.openExternal('https://jaywcjlove.github.io/wxmp');
+ },
+ },
+ ],
+ },
+];
+
+const menu = Menu.buildFromTemplate(template as Array