Vanessa 2023-05-08 21:00:41 +08:00
parent 875f00398e
commit 99725ea21d
14 changed files with 122 additions and 40 deletions

View file

@ -53,6 +53,7 @@ import {reloadProtyle} from "../protyle/util/reload";
import {fullscreen} from "../protyle/breadcrumb/action";
import {setPadding} from "../protyle/ui/initUI";
import {openRecentDocs} from "../business/openRecentDocs";
import {App} from "../index";
const getRightBlock = (element: HTMLElement, x: number, y: number) => {
let index = 1;
@ -95,7 +96,7 @@ const switchDialogEvent = (event: MouseEvent, switchDialog: Dialog) => {
}
};
export const globalShortcut = () => {
export const globalShortcut = (app: App) => {
document.body.addEventListener("mouseleave", () => {
if (window.siyuan.layout.leftDock) {
window.siyuan.layout.leftDock.hideDock();
@ -630,7 +631,7 @@ export const globalShortcut = () => {
return;
}
if (!isTabWindow && !window.siyuan.config.readonly && matchHotKey(window.siyuan.config.keymap.general.config.custom, event)) {
openSetting();
openSetting(app);
event.preventDefault();
return;
}

View file

@ -26,6 +26,7 @@ import {initBar} from "../layout/topBar";
import {setProxy} from "../config/util/setProxy";
import {openChangelog} from "./openChangelog";
import {getIdFromSYProtocol, isSYProtocol} from "../util/pathName";
import {App} from "../index";
const matchKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
if (key1 === "general") {
@ -84,7 +85,7 @@ const hasKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "edito
return match;
};
export const onGetConfig = (isStart: boolean) => {
export const onGetConfig = (isStart: boolean, app:App) => {
const matchKeymap1 = matchKeymap(Constants.SIYUAN_KEYMAP.general, "general");
const matchKeymap2 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.general, "editor", "general");
const matchKeymap3 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.insert, "editor", "insert");
@ -130,7 +131,7 @@ export const onGetConfig = (isStart: boolean) => {
if (!window.siyuan.config.uiLayout || (window.siyuan.config.uiLayout && !window.siyuan.config.uiLayout.left)) {
window.siyuan.config.uiLayout = Constants.SIYUAN_EMPTY_LAYOUT;
}
globalShortcut();
globalShortcut(app);
fetchPost("/api/system/getEmojiConf", {}, response => {
window.siyuan.emojis = response.data as IEmoji[];
try {
@ -140,7 +141,7 @@ export const onGetConfig = (isStart: boolean) => {
resetLayout();
}
});
initBar();
initBar(app);
setProxy();
initStatus();
initWindow();

View file

@ -12,6 +12,8 @@ import * as path from "path";
import {isBrowser} from "../util/functions";
import {setStorageVal} from "../protyle/util/compatibility";
import {hasClosestByAttribute, hasClosestByClassName} from "../protyle/util/hasClosest";
import {Plugin} from "../plugin";
import {App} from "../index";
export const bazaar = {
element: undefined as Element,
@ -209,7 +211,7 @@ export const bazaar = {
</div>
</div>`;
},
_genMyHTML(bazaarType: TBazaarType) {
_genMyHTML(bazaarType: TBazaarType, app: App) {
let url = "/api/bazaar/getInstalledTheme";
if (bazaarType === "icons") {
url = "/api/bazaar/getInstalledIcon";
@ -236,6 +238,16 @@ export const bazaar = {
repoHash: item.repoHash,
downloaded: true
};
let hasSetting = false;
if (bazaarType === "plugins") {
app.plugins.find((item: Plugin) => {
if (item.name === dataObj.name) {
// @ts-ignore
hasSetting = item.__proto__.hasOwnProperty("openSetting");
return true;
}
})
}
html += `<div data-obj='${JSON.stringify(dataObj)}' class="b3-card${item.current ? " b3-card--current" : ""}">
<div class="b3-card__img"><img src="${item.iconURL}" onerror="this.src='${item.previewURLThumb}'"/></div>
<div class="fn__flex-1 fn__flex-column">
@ -247,6 +259,10 @@ export const bazaar = {
<div class="b3-card__actions">
${item.preferredFunding ? `<a target="_blank" href="${item.preferredFunding}" class="b3-tooltips b3-tooltips__ne block__icon block__icon--show" aria-label="${window.siyuan.languages.sponsor} ${item.preferredFunding}"><svg class="ft__pink"><use xlink:href="#iconHeart"></use></svg></a>` : ""}
<div class="fn__flex-1"></div>
<span class="b3-tooltips b3-tooltips__nw block__icon block__icon--show${hasSetting ? "" : " fn__none"}" data-type="setting" aria-label="${window.siyuan.languages.config}">
<svg><use xlink:href="#iconSettings"></use></svg>
</span>
<span class="fn__space"></span>
<span class="b3-tooltips b3-tooltips__nw block__icon block__icon--show" data-type="uninstall" aria-label="${window.siyuan.languages.uninstall}">
<svg><use xlink:href="#iconTrashcan"></use></svg>
</span>
@ -396,8 +412,8 @@ export const bazaar = {
}
readmeElement.classList.add("config-bazaar__readme--show");
},
bindEvent() {
this._genMyHTML("themes");
bindEvent(app: App) {
this._genMyHTML("themes", app);
bazaar.element.firstElementChild.addEventListener("click", (event) => {
let target = event.target as HTMLElement;
const dataElement = hasClosestByAttribute(target, "data-obj", null);
@ -429,7 +445,7 @@ export const bazaar = {
}
});
target.classList.remove("b3-button--outline");
this._genMyHTML(type.replace("my", "").toLowerCase() + "s" as TBazaarType);
this._genMyHTML(type.replace("my", "").toLowerCase() + "s" as TBazaarType, app);
}
event.preventDefault();
event.stopPropagation();
@ -462,7 +478,7 @@ export const bazaar = {
exportLayout(true);
return;
}
bazaar._genMyHTML(bazaarType);
bazaar._genMyHTML(bazaarType, app);
bazaar._onBazaar(response, bazaarType, ["themes", "icons"].includes(bazaarType));
});
}
@ -494,7 +510,7 @@ export const bazaar = {
update: true,
}, response => {
// 更新主题后不需要对该主题进行切换 https://github.com/siyuan-note/siyuan/issues/4966
this._genMyHTML(bazaarType);
this._genMyHTML(bazaarType, app);
bazaar._onBazaar(response, bazaarType, ["icons"].includes(bazaarType));
// https://github.com/siyuan-note/siyuan/issues/5411
if (bazaarType === "themes" && (
@ -536,7 +552,7 @@ export const bazaar = {
fetchPost(url, {
packageName
}, response => {
this._genMyHTML(bazaarType);
this._genMyHTML(bazaarType, app);
bazaar._onBazaar(response, bazaarType, ["themes", "icons"].includes(bazaarType));
// TODO destroy plugin
if (bazaarType === "plugins") {
@ -555,7 +571,7 @@ export const bazaar = {
fetchPost("/api/setting/setAppearance", Object.assign({}, window.siyuan.config.appearance, {
icon: packageName,
}), (appearanceResponse) => {
this._genMyHTML(bazaarType);
this._genMyHTML(bazaarType, app);
fetchPost("/api/bazaar/getBazaarIcon", {}, response => {
response.data.appearance = appearanceResponse.data;
bazaar._onBazaar(response, "icons", true);
@ -575,7 +591,7 @@ export const bazaar = {
window.siyuan.config.appearance.themeJS) {
exportLayout(true);
} else {
this._genMyHTML("themes");
this._genMyHTML("themes", app);
fetchPost("/api/bazaar/getBazaarTheme", {}, response => {
response.data.appearance = appearanceResponse.data;
bazaar._onBazaar(response, "themes", true);
@ -587,6 +603,16 @@ export const bazaar = {
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "setting") {
app.plugins.find((item: Plugin) => {
if (item.name === dataObj.name) {
item.openSetting()
return true
}
})
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "plugin-enable") {
const itemElement = hasClosestByClassName(target, "b3-card");
if (itemElement) {

View file

@ -13,8 +13,9 @@ import {query} from "./query";
import {Dialog} from "../dialog";
import {ai} from "./ai";
import {flashcard} from "./flashcard";
import {App} from "../index";
export const genItemPanel = (type: string, containerElement:Element) => {
export const genItemPanel = (type: string, containerElement:Element, app: App) => {
switch (type) {
case "filetree":
containerElement.innerHTML = fileTree.genHTML();
@ -54,7 +55,7 @@ export const genItemPanel = (type: string, containerElement:Element) => {
case "bazaar":
bazaar.element = containerElement;
containerElement.innerHTML = bazaar.genHTML();
bazaar.bindEvent();
bazaar.bindEvent(app);
break;
case "account":
containerElement.innerHTML = account.genHTML();
@ -81,7 +82,7 @@ export const genItemPanel = (type: string, containerElement:Element) => {
}
};
export const openSetting = () => {
export const openSetting = (app:App) => {
const exitDialog = window.siyuan.dialogs.find((item) => {
if (item.element.querySelector(".config__tab-container")) {
item.destroy();
@ -126,7 +127,7 @@ export const openSetting = () => {
width: "90vw",
});
initConfigSearch(dialog.element);
initConfigSearch(dialog.element, app);
(dialog.element.querySelector(".b3-dialog__container") as HTMLElement).style.maxWidth = "1280px";
dialog.element.querySelectorAll(".b3-tab-bar .b3-list-item").forEach(item => {
item.addEventListener("click", () => {
@ -139,7 +140,7 @@ export const openSetting = () => {
item.classList.add("b3-list-item--focus");
containerElement.classList.remove("fn__none");
if (containerElement.innerHTML === "" || type === "repos" || type === "bazaar") {
genItemPanel(type, containerElement);
genItemPanel(type, containerElement, app);
}
});
});

View file

@ -1,6 +1,7 @@
import {Constants} from "../constants";
import {genItemPanel} from "./index";
import {keymap} from "./keymap";
import {App} from "../index";
const getLang = (keys: string[]) => {
const langArray: string[] = [];
@ -10,7 +11,7 @@ const getLang = (keys: string[]) => {
return langArray;
};
export const initConfigSearch = (element: HTMLElement) => {
export const initConfigSearch = (element: HTMLElement, app: App) => {
const configIndex = [
// 编辑器
getLang(["config", "fullWidth",
@ -115,7 +116,7 @@ export const initConfigSearch = (element: HTMLElement) => {
// 右侧面板过滤
const panelElement = element.querySelector(`.config__tab-container[data-name="${type}"]`);
if (panelElement.innerHTML === "") {
genItemPanel(type, panelElement);
genItemPanel(type, panelElement, app);
}
if (type === "keymap") {
const searchElement = keymap.element.querySelector("#keymapInput") as HTMLInputElement;

View file

@ -171,7 +171,7 @@ export class App {
fetchPost("/api/setting/getCloudUser", {}, userResponse => {
window.siyuan.user = userResponse.data;
loadPlugins(siyuanApp);
onGetConfig(response.data.start);
onGetConfig(response.data.start, siyuanApp);
account.onSetaccount();
resizeDrag();
setTitle(window.siyuan.languages.siyuanNote);

View file

@ -9,6 +9,7 @@ import {MenuItem} from "../menus/Menu";
import {setMode} from "../util/assets";
import {openSetting} from "../config";
import {openSearch} from "../search/spread";
import {App} from "../index";
export const updateEditModeElement = () => {
const target = document.querySelector("#barReadonly");
@ -23,7 +24,7 @@ export const updateEditModeElement = () => {
}
};
export const initBar = () => {
export const initBar = (app: App) => {
const toolbarElement = document.getElementById("toolbar");
toolbarElement.innerHTML = `
<div id="barWorkspace" class="toolbar__item">
@ -68,7 +69,7 @@ export const initBar = () => {
event.stopPropagation();
break;
} else if (target.id === "barWorkspace") {
workspaceMenu(target.getBoundingClientRect());
workspaceMenu(app, target.getBoundingClientRect());
event.stopPropagation();
break;
} else if (target.id === "barReadonly") {
@ -113,7 +114,7 @@ export const initBar = () => {
break;
} else if (target.id === "toolbarVIP") {
if (!window.siyuan.config.readonly) {
const dialogSetting = openSetting();
const dialogSetting = openSetting(app);
dialogSetting.element.querySelector('.b3-tab-bar [data-name="account"]').dispatchEvent(new CustomEvent("click"));
}
event.stopPropagation();

View file

@ -22,6 +22,7 @@ import {viewCards} from "../card/viewCards";
import {Dialog} from "../dialog";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {confirmDialog} from "../dialog/confirmDialog";
import {App} from "../index";
const togglePinDock = (dock: Dock, icon: string) => {
return {
@ -34,7 +35,7 @@ const togglePinDock = (dock: Dock, icon: string) => {
};
};
export const workspaceMenu = (rect: DOMRect) => {
export const workspaceMenu = (app:App, rect: DOMRect) => {
if (!window.siyuan.menus.menu.element.classList.contains("fn__none") &&
window.siyuan.menus.menu.element.getAttribute("data-name") === "barWorkspace") {
window.siyuan.menus.menu.remove();
@ -49,7 +50,7 @@ export const workspaceMenu = (rect: DOMRect) => {
icon: "iconSettings",
accelerator: window.siyuan.config.keymap.general.config.custom,
click: () => {
openSetting();
openSetting(app);
}
}).element);
}

View file

@ -1,20 +1,26 @@
import {App} from "../index";
import {EventBus} from "./EventBus";
import {fetchPost} from "../util/fetch";
export class Plugin {
public i18n: IObject;
public eventBus: EventBus;
public data: any = {};
public name: string;
constructor(options: {
app: App,
id: string,
name: string,
i18n: IObject
}) {
this.i18n = options.i18n;
this.name = options.name;
this.eventBus = new EventBus(options.name);
}
public onload() {
}
public addTopBar(options: {
icon: string,
title: string,
@ -31,7 +37,36 @@ export class Plugin {
return iconElement;
}
public onload() {
console.log("Hello, world!");
public openSetting() {
}
public loadData(storageName: string) {
if (typeof this.data[storageName] === "undefined") {
this.data[storageName] = "";
}
return new Promise((resolve) => {
fetchPost("/api/file/getFile", {path: `/data/storage/petal/${this.name}/${storageName}`}, (response) => {
if (response.code === 404) {
this.data[storageName] = "";
} else {
this.data[storageName] = response;
}
resolve(this.data[storageName]);
});
});
}
public saveData(storageName: string, data: any) {
return new Promise((resolve) => {
const pathString = `/data/storage/petal/${this.name}/${storageName}`;
const file = new File([new Blob([data])], pathString.split('/').pop());
const formData = new FormData();
formData.append('path', pathString);
formData.append('file', file);
formData.append('isDir', "false");
fetchPost("/api/file/putFile", formData, (response) => {
resolve(response);
});
});
}
}

View file

@ -18,7 +18,7 @@ const runCode = (code: string, sourceURL: string) => {
export const loadPlugins = (app: App) => {
fetchPost("/api/petal/loadPetals", {}, response => {
let css = "";
response.data.forEach((item: { id: string, name: string, js: string, css: string, i18n: IObject }) => {
response.data.forEach((item: { name: string, js: string, css: string, i18n: IObject }) => {
const exportsObj: { [key: string]: any } = {};
const moduleObj = {exports: exportsObj};
try {
@ -39,7 +39,6 @@ export const loadPlugins = (app: App) => {
const plugin = new pluginClass({
app,
name: item.name,
id: item.id,
i18n: item.i18n
});
app.plugins.push(plugin);

View file

@ -388,12 +388,12 @@ declare interface IEditor {
}
declare interface IWebSocketData {
cmd: string
cmd?: string
callback?: string
data: any
data?: any
msg: string
code: number
sid: string
sid?: string
}
declare interface IAppearance {

View file

@ -28,8 +28,23 @@ export const fetchPost = (url: string, data?: any, cb?: (response: IWebSocketDat
init.headers = headers;
}
fetch(url, init).then((response) => {
if (response.status === 404) {
cb({
data: null,
msg: response.statusText,
code: response.status,
});
} else {
if (response.headers.get("content-type").indexOf("application/json") > -1) {
return response.json();
} else {
return response.text();
}
}
}).then((response: IWebSocketData) => {
if (!response) {
return;
}
if (["/api/search/searchRefBlock", "/api/graph/getGraph", "/api/graph/getLocalGraph"].includes(url)) {
if (response.data.reqId && window.siyuan.reqIds[url] && window.siyuan.reqIds[url] > response.data.reqId) {
return;

View file

@ -135,7 +135,7 @@ class App {
fetchPost("/api/setting/getCloudUser", {}, userResponse => {
window.siyuan.user = userResponse.data;
loadPlugins(siyuanApp);
init();
init(siyuanApp);
setTitle(window.siyuan.languages.siyuanNote);
initMessage();
});

View file

@ -9,10 +9,11 @@ import {initAssets, setInlineStyle} from "../util/assets";
import {renderSnippet} from "../config/util/snippets";
import {getSearch} from "../util/functions";
import {initWindow} from "../boot/onGetConfig";
import {App} from "../index";
export const init = () => {
export const init = (app:App) => {
webFrame.setZoomFactor(window.siyuan.storage[Constants.LOCAL_ZOOM]);
globalShortcut();
globalShortcut(app);
fetchPost("/api/system/getEmojiConf", {}, response => {
window.siyuan.emojis = response.data as IEmoji[];