diff --git a/plugins/publisher-main/.eslintrc.cjs b/plugins/publisher-main/.eslintrc.cjs index adaf0c2c..07816050 100644 --- a/plugins/publisher-main/.eslintrc.cjs +++ b/plugins/publisher-main/.eslintrc.cjs @@ -2,12 +2,24 @@ module.exports = { extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:svelte/recommended", "turbo", "prettier", ], parser: "@typescript-eslint/parser", + overrides: [ + { + files: ["*.svelte"], + parser: "svelte-eslint-parser", + // Parse the script in `.svelte` as TypeScript by adding the following configuration. + parserOptions: { + parser: "@typescript-eslint/parser", + }, + }, + ], + plugins: ["@typescript-eslint", "prettier"], rules: { @@ -23,4 +35,4 @@ module.exports = { "turbo/no-undeclared-env-vars": "off", "prettier/prettier": "error", }, -} \ No newline at end of file +} diff --git a/plugins/publisher-main/.prettierrc.cjs b/plugins/publisher-main/.prettierrc.cjs index eec8622f..e75550a8 100644 --- a/plugins/publisher-main/.prettierrc.cjs +++ b/plugins/publisher-main/.prettierrc.cjs @@ -24,7 +24,8 @@ */ module.exports = { - semi: false, - singleQuote: false, - printWidth: 120 + semi: false, + singleQuote: false, + printWidth: 120, + plugins: ["prettier-plugin-svelte"] } diff --git a/plugins/publisher-main/package.json b/plugins/publisher-main/package.json index 07d4f1f9..4abda388 100644 --- a/plugins/publisher-main/package.json +++ b/plugins/publisher-main/package.json @@ -2,7 +2,7 @@ "name": "publisher-main", "private": true, "version": "1.1.3", - "type": "commonjs", + "type": "module", "scripts": { "serve": "vite", "dev": "vite build --watch", @@ -12,8 +12,11 @@ "syncVersion": "echo 'syncVersion in main'" }, "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^2.0.3", "@terwer/eslint-config-custom": "^1.2.0", "@terwer/vite-config-custom": "^0.4.0", - "siyuan": "^0.7.1" + "@tsconfig/svelte": "^4.0.1", + "siyuan": "^0.7.1", + "svelte": "^3.57.0" } } diff --git a/plugins/publisher-main/public/i18n/en_US.json b/plugins/publisher-main/public/i18n/en_US.json new file mode 100644 index 00000000..a0273127 --- /dev/null +++ b/plugins/publisher-main/public/i18n/en_US.json @@ -0,0 +1,6 @@ +{ + "publishTool": "Publish Tool", + "setting": "Setting", + "cancel": "Cancel", + "save": "Save" +} \ No newline at end of file diff --git a/plugins/publisher-main/public/i18n/zh_CN.json b/plugins/publisher-main/public/i18n/zh_CN.json new file mode 100644 index 00000000..6774f1e0 --- /dev/null +++ b/plugins/publisher-main/public/i18n/zh_CN.json @@ -0,0 +1,6 @@ +{ + "publishTool": "发布工具", + "setting": "设置", + "cancel": "取消", + "save": "保存" +} \ No newline at end of file diff --git a/plugins/publisher-main/src/App.svelte b/plugins/publisher-main/src/App.svelte new file mode 100644 index 00000000..e16b7e63 --- /dev/null +++ b/plugins/publisher-main/src/App.svelte @@ -0,0 +1,23 @@ + + +
+
+ This is svelte {message} + + + +
+
diff --git a/plugins/publisher-main/src/index.ts b/plugins/publisher-main/src/index.ts index 68ba7337..83701851 100644 --- a/plugins/publisher-main/src/index.ts +++ b/plugins/publisher-main/src/index.ts @@ -1,11 +1,49 @@ -import { Plugin } from "siyuan" +import { Plugin, showMessage, confirm, Dialog, Menu, isMobile, openTab, adaptHotkey } from "siyuan" +import App from "./App.svelte" +const STORAGE_NAME = "menu-config" +const SETTING_CONTAINER = "publish-tool-setting" + +// https://github.com/sveltejs/svelte-preprocess/issues/91#issuecomment-548527600 export default class PublishTool extends Plugin { + // lifecycle onload() { - console.log("Publish Tool loaded") + console.log(`Publish Tool loaded ${new Date().getTime()}`) } onunload() { console.log("Publish Tool unloaded") } + + openSetting() { + this._show_setting_dialog() + } + + // private functions + _show_setting_dialog() { + new Dialog({ + title: `${this.i18n.setting} - ${this.i18n.publishTool}`, + content: `
`, + width: isMobile() ? "92vw" : "520px", + }) + + // setting + new App({ + target: document.getElementById(SETTING_CONTAINER) as HTMLElement, + }) + + // const inputElement = dialog.element.querySelector("textarea") as HTMLTextAreaElement + // const btnsElement = dialog.element.querySelectorAll(".b3-button") + // dialog.bindInput(inputElement, () => { + // ;(btnsElement[1] as HTMLButtonElement).click() + // }) + // inputElement.focus() + // btnsElement[0].addEventListener("click", () => { + // dialog.destroy() + // }) + // btnsElement[1].addEventListener("click", () => { + // this.saveData(STORAGE_NAME, inputElement.value) + // dialog.destroy() + // }) + } } diff --git a/plugins/publisher-main/src/lib/Counter.svelte b/plugins/publisher-main/src/lib/Counter.svelte new file mode 100644 index 00000000..cec46391 --- /dev/null +++ b/plugins/publisher-main/src/lib/Counter.svelte @@ -0,0 +1,10 @@ + + + diff --git a/plugins/publisher-main/src/siyuan.d.ts b/plugins/publisher-main/src/siyuan.d.ts new file mode 100644 index 00000000..8c7c0faf --- /dev/null +++ b/plugins/publisher-main/src/siyuan.d.ts @@ -0,0 +1,179 @@ +declare module "siyuan" { + type TEventBus = "ws-main" + + interface IObject { + [key: string]: string; + } + + interface IWebSocketData { + cmd: string; + callback?: string; + data: any; + msg: string; + code: number; + sid: string; + } + + declare interface IPluginDockTab { + position: "LeftTop" | "LeftBottom" | "RightTop" | "RightBottom" | "BottomLeft" | "BottomRight", + size: { width: number, height: number }, + icon: string, + hotkey?: string, + title: string, + } + + interface IMenuItemOption { + label?: string, + click?: (element: HTMLElement) => void, + type?: "separator" | "submenu" | "readonly", + accelerator?: string, + action?: string, + id?: string, + submenu?: IMenuItemOption[] + disabled?: boolean + icon?: string + iconHTML?: string + current?: boolean + bind?: (element: HTMLElement) => void + } + + export function fetchPost(url: string, data?: any, cb?: (response: IWebSocketData) => void, headers?: IObject): void; + + export function fetchSyncPost(url: string, data?: any): Promise; + + export function fetchGet(url: string, cb: (response: IWebSocketData) => void): void; + + export function openTab(options: { + custom?: { + title: string, + icon: string, + data?: any + fn?: () => any, + } // card 和自定义页签 必填 + position?: "right" | "bottom", + keepCursor?: boolean // 是否跳转到新 tab 上 + removeCurrentTab?: boolean // 在当前页签打开时需移除原有页签 + afterOpen?: () => void // 打开后回调 + }): void + + export function isMobile(): boolean; + + export function adaptHotkey(hotkey: string): string; + + export function confirm(title: string, text: string, confirmCB?: () => void, cancelCB?: () => void): void; + + /** + * @param timeout - ms. 0: manual close;-1: always show; 6000: default + * @param {string} [type=info] + */ + export function showMessage(text: string, timeout?: number, type?: "info" | "error", id?: string): void; + + export class App { + plugins: Plugin[]; + } + + export abstract class Plugin { + eventBus: EventBus; + i18n: IObject; + data: any; + name: string; + + constructor(options: { + app: App, + id: string, + name: string, + i18n: IObject + }) + + onload(): void; + + onunload(): void; + + /* + * @param {string} [options.position=right] + */ + addTopBar(options: { + icon: string, + title: string, + callback: (evt: MouseEvent) => void + position?: "right" | "left" + }): HTMLDivElement; + + openSetting(): void + + // registerCommand(command: IPluginCommand): void; + + // registerSettingRender(settingRender: SettingRender): void; + + loadData(storageName: string): Promise; + + saveData(storageName: string, content: any): Promise; + + addTab(options: { + type: string, + destroy?: () => void, + resize?: () => void, + update?: () => void, + init: () => void + }): () => any + + addDock(options: { + config: IPluginDockTab, + data: any, + type: string, + destroy?: () => void, + resize?: () => void, + update?: () => void, + init: () => void + }): any + } + + export class EventBus { + on(type: TEventBus, listener: (event: CustomEvent) => void): void; + + once(type: TEventBus, listener: (event: CustomEvent) => void): void; + + off(type: TEventBus, listener: (event: CustomEvent) => void): void; + + emit(type: TEventBus, detail?: any): boolean; + } + + export class Dialog { + + element: HTMLElement; + + constructor(options: { + title?: string, + transparent?: boolean, + content: string, + width?: string + height?: string, + destroyCallback?: (options?: IObject) => void + disableClose?: boolean + disableAnimation?: boolean + }); + + destroy(options?: IObject): void; + + bindInput(inputElement: HTMLInputElement | HTMLTextAreaElement, enterEvent?: () => void): void; + } + + export class Menu { + constructor(id?: string, closeCB?: () => void); + + showSubMenu(subMenuElement: HTMLElement): void; + + addItem(options: IMenuItemOption): HTMLElement; + + addSeparator(): void; + + open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }): void; + + /* + * @param {string} [position=all] + */ + fullscreen(position?: "bottom" | "all"): void; + + close(): void; + } +} \ No newline at end of file diff --git a/plugins/publisher-main/tsconfig.json b/plugins/publisher-main/tsconfig.json index 08cfe0c6..ab12f3b9 100644 --- a/plugins/publisher-main/tsconfig.json +++ b/plugins/publisher-main/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", "lib": [ @@ -22,9 +22,21 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, + + /* Svelte */ + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "types": [ "node", - "vite/client" + "vite/client", + "svelte" ] }, "include": [ diff --git a/plugins/publisher-main/vite.config.ts b/plugins/publisher-main/vite.config.ts index 61779b73..fd34e3f8 100644 --- a/plugins/publisher-main/vite.config.ts +++ b/plugins/publisher-main/vite.config.ts @@ -5,6 +5,7 @@ import { defineConfig } from "vite" import minimist from "minimist" import { viteStaticCopy } from "vite-plugin-static-copy" import livereload from "rollup-plugin-livereload" +import { svelte } from "@sveltejs/vite-plugin-svelte" const args = minimist(process.argv.slice(2)) const isWatch = args.watch || args.w @@ -16,6 +17,8 @@ console.log("distDir=>", distDir) export default defineConfig({ plugins: [ + svelte(), + viteStaticCopy({ targets: [ { @@ -85,22 +88,22 @@ export default defineConfig({ // entryFileNames: "static/js/[name]-[hash].js", entryFileNames: "[name].js", assetFileNames: "static/[ext]/[name]-[hash].[ext]", - manualChunks(id) { - if (id.includes("node_modules")) { - let arr = id.toString().split("node_modules/")[1].split("/") - // pnpm单独处理 - if (id.includes(".pnpm")) { - arr = id.toString().split(".pnpm/")[1].split("/") - } - const dep = arr[0].split("@")[0].replace(/\./g, "-") - // console.log("id=>", id) - // console.log("dep=>", dep) - if (dep !== "") { - return "vendor_" + dep - } - return "vendor" - } - }, + // manualChunks(id) { + // if (id.includes("node_modules")) { + // let arr = id.toString().split("node_modules/")[1].split("/") + // // pnpm单独处理 + // if (id.includes(".pnpm")) { + // arr = id.toString().split(".pnpm/")[1].split("/") + // } + // const dep = arr[0].split("@")[0].replace(/\./g, "-") + // // console.log("id=>", id) + // // console.log("dep=>", dep) + // if (dep !== "") { + // return "vendor_" + dep + // } + // return "vendor" + // } + // }, }, }, }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb81b7c2..8af0baa5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,15 +83,24 @@ importers: plugins/publisher-main: devDependencies: + '@sveltejs/vite-plugin-svelte': + specifier: ^2.0.3 + version: registry.npmjs.org/@sveltejs/vite-plugin-svelte@2.0.3(svelte@3.57.0)(vite@4.3.5) '@terwer/eslint-config-custom': specifier: ^1.2.0 version: registry.npmjs.org/@terwer/eslint-config-custom@1.2.0(@nuxt/eslint-config@0.1.1)(@typescript-eslint/eslint-plugin@5.59.5)(astro-eslint-parser@0.13.3)(eslint-config-prettier@8.8.0)(eslint-config-turbo@1.9.4)(eslint-plugin-prettier@4.2.1)(eslint-plugin-svelte@2.28.0)(eslint-plugin-vue@9.12.0)(eslint@8.40.0)(prettier-plugin-svelte@2.10.0)(prettier@2.8.8)(typescript@5.0.4) '@terwer/vite-config-custom': specifier: ^0.4.0 version: registry.npmjs.org/@terwer/vite-config-custom@0.4.0(jsdom@22.0.0)(rollup-plugin-livereload@2.0.5)(tslib@2.5.0)(typescript@5.0.4)(vite-plugin-css-injected-by-js@3.1.1)(vite-plugin-dts@2.3.0)(vite-plugin-no-bundle@2.0.2)(vite-plugin-static-copy@0.15.0)(vite-tsconfig-paths@4.2.0)(vite@4.3.5)(vitest@0.31.0) + '@tsconfig/svelte': + specifier: ^4.0.1 + version: registry.npmjs.org/@tsconfig/svelte@4.0.1 siyuan: specifier: ^0.7.1 version: registry.npmjs.org/siyuan@0.7.1 + svelte: + specifier: ^3.57.0 + version: registry.npmjs.org/svelte@3.57.0 packages: