Skip to content

Commit

Permalink
feat(publisher-main): 集成 svelte 到插件
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed May 13, 2023
1 parent 89c3be9 commit 22b7b67
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 26 deletions.
14 changes: 13 additions & 1 deletion plugins/publisher-main/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -23,4 +35,4 @@ module.exports = {
"turbo/no-undeclared-env-vars": "off",
"prettier/prettier": "error",
},
}
}
7 changes: 4 additions & 3 deletions plugins/publisher-main/.prettierrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
*/

module.exports = {
semi: false,
singleQuote: false,
printWidth: 120
semi: false,
singleQuote: false,
printWidth: 120,
plugins: ["prettier-plugin-svelte"]
}
7 changes: 5 additions & 2 deletions plugins/publisher-main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "publisher-main",
"private": true,
"version": "1.1.3",
"type": "commonjs",
"type": "module",
"scripts": {
"serve": "vite",
"dev": "vite build --watch",
Expand All @@ -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"
}
}
6 changes: 6 additions & 0 deletions plugins/publisher-main/public/i18n/en_US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"publishTool": "Publish Tool",
"setting": "Setting",
"cancel": "Cancel",
"save": "Save"
}
6 changes: 6 additions & 0 deletions plugins/publisher-main/public/i18n/zh_CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"publishTool": "发布工具",
"setting": "设置",
"cancel": "取消",
"save": "保存"
}
23 changes: 23 additions & 0 deletions plugins/publisher-main/src/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import Counter from "./lib/Counter.svelte"
const message = "Hello, World!"
</script>

<main>
<div>
This is svelte {message}
<Counter />

<!--
<div class="b3-dialog__content">
<textarea class="b3-text-field fn__block" placeholder="readonly text in the menu" />
</div>
<div class="b3-dialog__action">
<button class="b3-button b3-button--cancel">${this.i18n.cancel}</button>
<div class="fn__space" />
<button class="b3-button b3-button--text">${this.i18n.save}</button>
</div>
</div>
-->
</div>
</main>
42 changes: 40 additions & 2 deletions plugins/publisher-main/src/index.ts
Original file line number Diff line number Diff line change
@@ -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: `<div id="${SETTING_CONTAINER}"></div>`,
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()
// })
}
}
10 changes: 10 additions & 0 deletions plugins/publisher-main/src/lib/Counter.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script lang="ts">
let count = 0
const increment = () => {
count += 1
}
</script>

<button on:click={increment}>
count is {count}
</button>
179 changes: 179 additions & 0 deletions plugins/publisher-main/src/siyuan.d.ts
Original file line number Diff line number Diff line change
@@ -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<IWebSocketData>;

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<any>;

saveData(storageName: string, content: any): Promise<void>;

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<any>) => void): void;

once(type: TEventBus, listener: (event: CustomEvent<any>) => void): void;

off(type: TEventBus, listener: (event: CustomEvent<any>) => 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;
}
}
16 changes: 14 additions & 2 deletions plugins/publisher-main/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "ES2020",
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": [
Expand All @@ -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": [
Expand Down
Loading

0 comments on commit 22b7b67

Please sign in to comment.