feat: add electron app.
39
.github/workflows/ci.yml
vendored
@@ -68,6 +68,12 @@ jobs:
|
|||||||
- name: Build Awesome Mac image
|
- name: Build Awesome Mac image
|
||||||
run: docker image build -t wxmp .
|
run: docker image build -t wxmp .
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: webiste
|
||||||
|
path: |
|
||||||
|
website/build/**
|
||||||
|
|
||||||
- name: Tags & Push image (latest)
|
- name: Tags & Push image (latest)
|
||||||
run: |
|
run: |
|
||||||
echo "outputs.tag - ${{ steps.changelog.outputs.version }}"
|
echo "outputs.tag - ${{ steps.changelog.outputs.version }}"
|
||||||
@@ -96,4 +102,35 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "version: v${{ steps.changelog.outputs.version }}"
|
echo "version: v${{ steps.changelog.outputs.version }}"
|
||||||
docker tag ghcr.io/jaywcjlove/wxmp:latest ghcr.io/jaywcjlove/wxmp:${{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}}
|
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
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
- [ ] 支持色盘取色,快速替换文章整体色调
|
- [ ] 支持色盘取色,快速替换文章整体色调
|
||||||
- [x] 支持 URL 参数加载 Markdown 内容。
|
- [x] 支持 URL 参数加载 Markdown 内容。
|
||||||
- [x] 支持 URL 参数选择预览主题。
|
- [x] 支持 URL 参数选择预览主题。
|
||||||
|
- [ ] 使用 electron 生成桌面应用。
|
||||||
|
|
||||||
### 支持代码块样式
|
### 支持代码块样式
|
||||||
|
|
||||||
|
|||||||
2
electron/app/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
dist
|
||||||
|
website
|
||||||
8
electron/app/assets/entitlements.mac.plist
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
35
electron/app/config.json
Normal file
@@ -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"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
electron/app/icon.icns
Normal file
BIN
electron/app/icons.iconset/icon_128x128.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
electron/app/icons.iconset/icon_128x128@2x.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
electron/app/icons.iconset/icon_16x16.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
electron/app/icons.iconset/icon_16x16@2x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
electron/app/icons.iconset/icon_256x256.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
electron/app/icons.iconset/icon_256x256@2x.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
electron/app/icons.iconset/icon_32x32.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
electron/app/icons.iconset/icon_32x32@2x.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
electron/app/icons.iconset/icon_512x512.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
electron/app/icons.iconset/icon_512x512@2x.png
Normal file
|
After Width: | Height: | Size: 275 KiB |
BIN
electron/app/logo.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
15
electron/app/main.js
Normal file
@@ -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);
|
||||||
|
})();
|
||||||
30
electron/app/package.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
electron/main/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
lib
|
||||||
16
electron/main/package.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
56
electron/main/src/Menu.ts
Normal file
@@ -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<MenuItem | MenuItemConstructorOptions>);
|
||||||
|
Menu.setApplicationMenu(menu);
|
||||||
60
electron/main/src/app.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { app, shell, BrowserWindow } from 'electron';
|
||||||
|
import './Menu';
|
||||||
|
|
||||||
|
export interface Options extends Electron.BrowserWindowConstructorOptions {
|
||||||
|
preload?: string;
|
||||||
|
webpath?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class App {
|
||||||
|
app = app;
|
||||||
|
win?: BrowserWindow;
|
||||||
|
isLogin: boolean = false;
|
||||||
|
/** 创建主进程窗口 */
|
||||||
|
async createWindow(options: Options = {}, loadURL?: string) {
|
||||||
|
await app.whenReady();
|
||||||
|
const opts: Options = {
|
||||||
|
titleBarStyle: 'hidden', // 无标题栏
|
||||||
|
frame: false, // 创建无边窗口
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
minWidth: 850,
|
||||||
|
center: true,
|
||||||
|
maximizable: true,
|
||||||
|
minimizable: true,
|
||||||
|
resizable: true,
|
||||||
|
webPreferences: {
|
||||||
|
// 多线程
|
||||||
|
nodeIntegrationInWorker: true,
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
},
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
if (options.preload) {
|
||||||
|
opts.webPreferences.preload = options.preload;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.win = new BrowserWindow(opts);
|
||||||
|
if (process.env.NODE_ENV === 'development') {
|
||||||
|
this.win.loadURL(loadURL || 'http://localhost:3000/');
|
||||||
|
// 打开开发者工具,默认不打开
|
||||||
|
this.win.webContents.openDevTools();
|
||||||
|
} else {
|
||||||
|
this.win.loadFile(options.webpath);
|
||||||
|
}
|
||||||
|
this.win.webContents.setWindowOpenHandler(({ url }) => {
|
||||||
|
if (/^https?:\/\//.test(url)) {
|
||||||
|
shell.openExternal(url);
|
||||||
|
return { action: 'deny' };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
action: 'allow',
|
||||||
|
overrideBrowserWindowOptions: {
|
||||||
|
modal: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return this.win;
|
||||||
|
}
|
||||||
|
}
|
||||||
1
electron/main/src/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './app';
|
||||||
19
electron/main/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"declaration": true,
|
||||||
|
"target": "es2017",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"sourceMap": false,
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"baseUrl": "."
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
1
electron/preload/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
lib
|
||||||
16
electron/preload/package.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "@wcj/wxmp-preload",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
electron/preload/src/index.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const styleStr = `.siderbar {
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
}
|
||||||
|
.siderbar header h1 a, github-corners {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
article.content:before {
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
position: absolute;
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 41px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const head = document.querySelector('head');
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.textContent = styleStr;
|
||||||
|
if (head) {
|
||||||
|
head.append(style);
|
||||||
|
}
|
||||||
|
});
|
||||||
27
electron/preload/tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"declaration": true,
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": false,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": true,
|
||||||
|
"outDir": "lib",
|
||||||
|
"baseUrl": "."
|
||||||
|
// "esModuleInterop": true,
|
||||||
|
// "allowSyntheticDefaultImports": true,
|
||||||
|
// "forceConsistentCasingInFileNames": true,
|
||||||
|
// "noFallthroughCasesInSwitch": true,
|
||||||
|
// "isolatedModules": false,
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
4
lerna.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"version": "2.1.0",
|
||||||
|
"packages": ["website", "electron/*"]
|
||||||
|
}
|
||||||
86
package.json
@@ -1,82 +1,34 @@
|
|||||||
{
|
{
|
||||||
"name": "website",
|
|
||||||
"version": "2.1.0",
|
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "kkt start",
|
"build": "lerna exec --scope @wcj/* --ignore wxmp -- npm run build",
|
||||||
"build": "kkt build",
|
"doc": "npm run-script build --workspace website",
|
||||||
|
"start": "npm run-script start --workspace website",
|
||||||
|
"build:app": "npm run-script build --workspace wxmp",
|
||||||
|
"⬆️⬆️⬆️⬆️⬆️ package ⬆️⬆️⬆️⬆️⬆️": "▲▲▲▲▲ package ▲▲▲▲▲",
|
||||||
|
"version": "lerna version --exact --force-publish --no-push --no-git-tag-version",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||||
"pretty-quick": "pretty-quick --staged"
|
"pretty-quick": "pretty-quick --staged",
|
||||||
|
"hoist": "lerna bootstrap --hoist",
|
||||||
|
"clean": "lerna clean --yes"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.18.9",
|
|
||||||
"@tanstack/react-query": "^4.2.3",
|
|
||||||
"@uiw/codemirror-theme-abcdef": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-androidstudio": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-atomone": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-bbedit": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-bespin": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-darcula": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-dracula": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-duotone": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-eclipse": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-github": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-okaidia": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-sublime": "^4.11.6",
|
|
||||||
"@uiw/codemirror-theme-xcode": "^4.11.6",
|
|
||||||
"@uiw/react-back-to-top": "^1.2.0",
|
|
||||||
"@uiw/react-github-corners": "^1.5.15",
|
|
||||||
"@uiw/react-markdown-editor": "^5.6.0",
|
|
||||||
"@wcj/dark-mode": "^1.0.15",
|
|
||||||
"css-tree": "^2.2.1",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-code-preview-layout": "^2.0.4",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"react-hot-toast": "^2.3.0",
|
|
||||||
"react-router-dom": "^6.3.0",
|
|
||||||
"rehype-attr": "^2.0.8",
|
|
||||||
"rehype-ignore": "^1.0.1",
|
|
||||||
"rehype-prism-plus": "^1.5.0",
|
|
||||||
"rehype-raw": "^6.1.1",
|
|
||||||
"rehype-stringify": "^9.0.3",
|
|
||||||
"remark-gfm": "^3.0.1",
|
|
||||||
"remark-parse": "^10.0.1",
|
|
||||||
"remark-rehype": "^10.1.0",
|
|
||||||
"styled-components": "^5.3.5",
|
|
||||||
"unified": "^10.1.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kkt/less-modules": "^7.2.0",
|
"cross-env": "^7.0.3",
|
||||||
"@kkt/raw-modules": "^7.2.0",
|
|
||||||
"@kkt/scope-plugin-options": "^7.2.0",
|
|
||||||
"@types/css-tree": "^1.0.7",
|
|
||||||
"@types/react": "^18.0.17",
|
|
||||||
"@types/react-dom": "^18.0.6",
|
|
||||||
"@types/styled-components": "^5.1.25",
|
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"kkt": "^7.2.0",
|
"lerna": "5.3.0",
|
||||||
"markdown-react-code-preview-loader": "^2.1.2",
|
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"pretty-quick": "~3.1.3"
|
"pretty-quick": "~3.1.3",
|
||||||
|
"tsbb": "^3.7.5"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"workspaces": {
|
||||||
"extends": [
|
"packages": [
|
||||||
"react-app",
|
"electron/**",
|
||||||
"react-app/jest"
|
"website"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"engines": {
|
||||||
"production": [
|
"node": ">=16.0.0"
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not op_mini all"
|
|
||||||
],
|
|
||||||
"development": [
|
|
||||||
"last 1 chrome version",
|
|
||||||
"last 1 firefox version",
|
|
||||||
"last 1 safari version"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import path from 'path';
|
|
||||||
import webpack, { Configuration } from 'webpack';
|
import webpack, { Configuration } from 'webpack';
|
||||||
import lessModules from '@kkt/less-modules';
|
import lessModules from '@kkt/less-modules';
|
||||||
import { mdCodeModulesLoader } from 'markdown-react-code-preview-loader';
|
import { mdCodeModulesLoader } from 'markdown-react-code-preview-loader';
|
||||||
import scopePluginOptions from '@kkt/scope-plugin-options';
|
import { disableScopePlugin } from '@kkt/scope-plugin-options';
|
||||||
import { LoaderConfOptions } from 'kkt';
|
import { LoaderConfOptions } from 'kkt';
|
||||||
import raw from '@kkt/raw-modules';
|
import raw from '@kkt/raw-modules';
|
||||||
import pkg from './package.json';
|
import pkg from './package.json';
|
||||||
@@ -14,10 +13,7 @@ export default (conf: Configuration, env: 'development' | 'production', options:
|
|||||||
...options,
|
...options,
|
||||||
test: /\.(md.css)$/i,
|
test: /\.(md.css)$/i,
|
||||||
});
|
});
|
||||||
conf = scopePluginOptions(conf, env, {
|
conf = disableScopePlugin(conf);
|
||||||
...options,
|
|
||||||
allowedFiles: [path.resolve(process.cwd(), 'README.md'), path.resolve(process.cwd(), 'src')],
|
|
||||||
});
|
|
||||||
conf.plugins!.push(
|
conf.plugins!.push(
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
VERSION: JSON.stringify(pkg.version),
|
VERSION: JSON.stringify(pkg.version),
|
||||||
76
website/package.json
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"name": "website",
|
||||||
|
"version": "2.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "kkt start",
|
||||||
|
"build": "kkt build"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.18.9",
|
||||||
|
"@tanstack/react-query": "^4.2.3",
|
||||||
|
"@uiw/codemirror-theme-abcdef": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-androidstudio": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-atomone": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-bbedit": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-bespin": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-darcula": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-dracula": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-duotone": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-eclipse": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-github": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-okaidia": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-sublime": "^4.11.6",
|
||||||
|
"@uiw/codemirror-theme-xcode": "^4.11.6",
|
||||||
|
"@uiw/react-back-to-top": "^1.2.0",
|
||||||
|
"@uiw/react-github-corners": "^1.5.15",
|
||||||
|
"@uiw/react-markdown-editor": "^5.6.2",
|
||||||
|
"@wcj/dark-mode": "^1.0.15",
|
||||||
|
"css-tree": "^2.2.1",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-code-preview-layout": "^2.0.4",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-hot-toast": "^2.3.0",
|
||||||
|
"react-router-dom": "^6.3.0",
|
||||||
|
"rehype-attr": "^2.0.8",
|
||||||
|
"rehype-ignore": "^1.0.1",
|
||||||
|
"rehype-prism-plus": "^1.5.0",
|
||||||
|
"rehype-raw": "^6.1.1",
|
||||||
|
"rehype-stringify": "^9.0.3",
|
||||||
|
"remark-gfm": "^3.0.1",
|
||||||
|
"remark-parse": "^10.0.1",
|
||||||
|
"remark-rehype": "^10.1.0",
|
||||||
|
"styled-components": "^5.3.5",
|
||||||
|
"unified": "^10.1.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@kkt/less-modules": "^7.2.0",
|
||||||
|
"@kkt/raw-modules": "^7.2.0",
|
||||||
|
"@kkt/scope-plugin-options": "^7.2.0",
|
||||||
|
"@types/css-tree": "^1.0.7",
|
||||||
|
"@types/react": "^18.0.17",
|
||||||
|
"@types/react-dom": "^18.0.6",
|
||||||
|
"@types/styled-components": "^5.1.25",
|
||||||
|
"kkt": "^7.2.0",
|
||||||
|
"markdown-react-code-preview-loader": "^2.1.2"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": [
|
||||||
|
"react-app",
|
||||||
|
"react-app/jest"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 576 B After Width: | Height: | Size: 576 B |
|
Before Width: | Height: | Size: 784 B After Width: | Height: | Size: 784 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -12,7 +12,7 @@ const Select = styled.select`
|
|||||||
padding: 0 0.2rem 0 0.2rem;
|
padding: 0 0.2rem 0 0.2rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 0.3rem;
|
font-size: 0.8rem;
|
||||||
outline: none;
|
outline: none;
|
||||||
height: 1.15rem;
|
height: 1.15rem;
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
@@ -10,6 +10,7 @@ import { Context } from '../store/context';
|
|||||||
const Warpper = styled.div``;
|
const Warpper = styled.div``;
|
||||||
|
|
||||||
const Header = styled.header`
|
const Header = styled.header`
|
||||||
|
-webkit-app-region: drag;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -39,9 +40,9 @@ const Title = styled.h1`
|
|||||||
margin-left: 0.4rem;
|
margin-left: 0.4rem;
|
||||||
background-color: var(--color-border-muted);
|
background-color: var(--color-border-muted);
|
||||||
border-radius: 0.1rem;
|
border-radius: 0.1rem;
|
||||||
padding: 0 0.2rem;
|
padding: 0 0.2rem 0 0.1rem;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 0.1rem;
|
font-size: 0.7rem;
|
||||||
letter-spacing: -0.1rem;
|
letter-spacing: -0.1rem;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import MarkdownEditor from '@uiw/react-markdown-editor';
|
import MarkdownEditor from '@uiw/react-markdown-editor';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import data from '../../../README.md';
|
import { markdownString } from '../../store/context';
|
||||||
|
|
||||||
const Warpper = styled.div`
|
const Warpper = styled.div`
|
||||||
max-width: 59rem;
|
max-width: 59rem;
|
||||||
@@ -11,7 +11,7 @@ const Warpper = styled.div`
|
|||||||
export const DocsPage = () => {
|
export const DocsPage = () => {
|
||||||
return (
|
return (
|
||||||
<Warpper>
|
<Warpper>
|
||||||
<MarkdownEditor.Markdown source={data.source} />
|
<MarkdownEditor.Markdown source={markdownString} />
|
||||||
</Warpper>
|
</Warpper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -17,7 +17,6 @@ export const HomePage = () => {
|
|||||||
const { theme, markdown, isLoading, setMarkdown } = useContext(Context);
|
const { theme, markdown, isLoading, setMarkdown } = useContext(Context);
|
||||||
const themeValue = themes[theme].value;
|
const themeValue = themes[theme].value;
|
||||||
const handleChange = (value: string) => setMarkdown(value);
|
const handleChange = (value: string) => setMarkdown(value);
|
||||||
console.log(isLoading);
|
|
||||||
return (
|
return (
|
||||||
<Warpper>
|
<Warpper>
|
||||||
<MarkdownEditor
|
<MarkdownEditor
|
||||||
@@ -30,7 +29,7 @@ export const HomePage = () => {
|
|||||||
renderPreview={Preview}
|
renderPreview={Preview}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
visible={true}
|
visible={true}
|
||||||
height="calc(100vh - 4.92rem)"
|
height="calc(100vh - 4.70rem)"
|
||||||
/>
|
/>
|
||||||
</Warpper>
|
</Warpper>
|
||||||
);
|
);
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { PreviewThemeValue, previewThemes, ThemeValue, Context } from './context';
|
import { PreviewThemeValue, previewThemes, ThemeValue, Context, markdownString } from './context';
|
||||||
import { useMdSource } from './getMdSource';
|
import { useMdSource } from './getMdSource';
|
||||||
|
|
||||||
import data from '../../README.md';
|
|
||||||
|
|
||||||
export const Provider: React.FC<React.PropsWithChildren> = ({ children }) => {
|
export const Provider: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const paramPreviewTheme = searchParams.get('theme') as PreviewThemeValue;
|
const paramPreviewTheme = searchParams.get('theme') as PreviewThemeValue;
|
||||||
const initPreviewTheme = paramPreviewTheme || 'underscore';
|
const initPreviewTheme = paramPreviewTheme || 'underscore';
|
||||||
const mdurl = searchParams.get('md');
|
const mdurl = searchParams.get('md');
|
||||||
const [markdown, setMarkdown] = React.useState<string>(mdurl ? '' : data.source);
|
const [markdown, setMarkdown] = React.useState<string>(mdurl ? '' : markdownString);
|
||||||
const [css, setCss] = React.useState<string>(previewThemes[initPreviewTheme].value);
|
const [css, setCss] = React.useState<string>(previewThemes[initPreviewTheme].value);
|
||||||
const [previewTheme, setPreviewTheme] = React.useState<PreviewThemeValue>(initPreviewTheme);
|
const [previewTheme, setPreviewTheme] = React.useState<PreviewThemeValue>(initPreviewTheme);
|
||||||
const [theme, setTheme] = React.useState<ThemeValue>('default');
|
const [theme, setTheme] = React.useState<ThemeValue>('default');
|
||||||
@@ -18,7 +18,9 @@ import simpleStyle from '../themes/simple.md.css';
|
|||||||
import underscoreStyle from '../themes/underscore.md.css';
|
import underscoreStyle from '../themes/underscore.md.css';
|
||||||
import baseStyle from '../themes/base.md.css';
|
import baseStyle from '../themes/base.md.css';
|
||||||
|
|
||||||
import data from '../../README.md';
|
import data from '../../../README.md';
|
||||||
|
|
||||||
|
export const markdownString = data.source;
|
||||||
|
|
||||||
export const themes = {
|
export const themes = {
|
||||||
default: {
|
default: {
|
||||||
@@ -105,10 +105,12 @@ th {
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
white-space: initial;
|
white-space: initial;
|
||||||
background: rgba(27, 31, 35, 0.05);
|
background: rgba(27, 31, 35, 0.05);
|
||||||
padding: 0.2em 0.6em;
|
padding: 0.1em 0.3em;
|
||||||
border-radius: 0.6em;
|
border-radius: 0.3em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.45em;
|
font-size: 1em;
|
||||||
|
top: -0.1em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footnotes-title {
|
.footnotes-title {
|
||||||
@@ -145,10 +145,12 @@ th {
|
|||||||
white-space: initial;
|
white-space: initial;
|
||||||
color: #009874;
|
color: #009874;
|
||||||
background: rgba(27, 31, 35, 0.05);
|
background: rgba(27, 31, 35, 0.05);
|
||||||
padding: 0.2em 0.6em;
|
padding: 0.1em 0.3em;
|
||||||
border-radius: 0.6em;
|
border-radius: 0.3em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.45em;
|
font-size: 1em;
|
||||||
|
top: -0.1em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footnotes-title {
|
.footnotes-title {
|
||||||
@@ -145,10 +145,12 @@ th {
|
|||||||
white-space: initial;
|
white-space: initial;
|
||||||
color: #0f4c81;
|
color: #0f4c81;
|
||||||
background: rgba(27, 31, 35, 0.05);
|
background: rgba(27, 31, 35, 0.05);
|
||||||
padding: 0.2em 0.6em;
|
padding: 0.1em 0.3em;
|
||||||
border-radius: 0.6em;
|
border-radius: 0.3em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.45em;
|
font-size: 1em;
|
||||||
|
top: -0.1em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footnotes-title {
|
.footnotes-title {
|
||||||
@@ -142,10 +142,12 @@ th {
|
|||||||
white-space: initial;
|
white-space: initial;
|
||||||
color: #ffb11b;
|
color: #ffb11b;
|
||||||
background: rgba(27, 31, 35, 0.05);
|
background: rgba(27, 31, 35, 0.05);
|
||||||
padding: 0.2em 0.6em;
|
padding: 0.1em 0.3em;
|
||||||
border-radius: 0.6em;
|
border-radius: 0.3em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.45em;
|
font-size: 1em;
|
||||||
|
top: -0.1em;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footnotes-title {
|
.footnotes-title {
|
||||||