This commit is contained in:
Vanessa 2023-05-10 00:01:47 +08:00
parent f45d2bd37b
commit fb007a61c0
16 changed files with 131 additions and 63 deletions

View file

@ -85,7 +85,7 @@ const hasKeymap = (keymap: Record<string, IKeymapItem>, key1: "general" | "edito
return match; return match;
}; };
export const onGetConfig = (isStart: boolean, app:App) => { export const onGetConfig = (isStart: boolean, app: App) => {
const matchKeymap1 = matchKeymap(Constants.SIYUAN_KEYMAP.general, "general"); const matchKeymap1 = matchKeymap(Constants.SIYUAN_KEYMAP.general, "general");
const matchKeymap2 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.general, "editor", "general"); const matchKeymap2 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.general, "editor", "general");
const matchKeymap3 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.insert, "editor", "insert"); const matchKeymap3 = matchKeymap(Constants.SIYUAN_KEYMAP.editor.insert, "editor", "insert");
@ -135,7 +135,7 @@ export const onGetConfig = (isStart: boolean, app:App) => {
fetchPost("/api/system/getEmojiConf", {}, response => { fetchPost("/api/system/getEmojiConf", {}, response => {
window.siyuan.emojis = response.data as IEmoji[]; window.siyuan.emojis = response.data as IEmoji[];
try { try {
JSONToLayout(isStart); JSONToLayout(app, isStart);
openChangelog(); openChangelog();
} catch (e) { } catch (e) {
resetLayout(); resetLayout();

View file

@ -14,7 +14,7 @@ export const newCardModel = (options: {
}) => { }) => {
let editor: Protyle; let editor: Protyle;
const custom = new Custom({ const custom = new Custom({
type: "card", type: "siyuan-card",
tab: options.tab, tab: options.tab,
data: options.data, data: options.data,
init() { init() {

View file

@ -12,6 +12,7 @@ import {MenuItem} from "../menus/Menu";
import {escapeHtml} from "../util/escape"; import {escapeHtml} from "../util/escape";
/// #if !MOBILE /// #if !MOBILE
import {openFile} from "../editor/util"; import {openFile} from "../editor/util";
import {newCardModel} from "./newCardTab";
/// #endif /// #endif
import {getDisplayName, movePathTo} from "../util/pathName"; import {getDisplayName, movePathTo} from "../util/pathName";
@ -21,9 +22,9 @@ export const genCardHTML = (options: {
blocks: ICard[], blocks: ICard[],
isTab: boolean isTab: boolean
}) => { }) => {
let iconsHTML:string; let iconsHTML: string;
/// #if MOBILE /// #if MOBILE
iconsHTML=`<div class="toolbar toolbar--border"> iconsHTML = `<div class="toolbar toolbar--border">
<svg class="toolbar__icon"><use xlink:href="#iconRiffCard"></use></svg> <svg class="toolbar__icon"><use xlink:href="#iconRiffCard"></use></svg>
<span class="fn__flex-1 fn__flex-center toolbar__text">${window.siyuan.languages.riffCard}</span> <span class="fn__flex-1 fn__flex-center toolbar__text">${window.siyuan.languages.riffCard}</span>
<div data-type="count" class="${options.blocks.length === 0 ? "fn__none" : ""}">1/${options.blocks.length}</span></div> <div data-type="count" class="${options.blocks.length === 0 ? "fn__none" : ""}">1/${options.blocks.length}</span></div>
@ -31,7 +32,7 @@ export const genCardHTML = (options: {
<svg class="toolbar__icon" data-type="close"><use xlink:href="#iconCloseRound"></use></svg> <svg class="toolbar__icon" data-type="close"><use xlink:href="#iconCloseRound"></use></svg>
</div>`; </div>`;
/// #else /// #else
iconsHTML=`<div class="block__icons"> iconsHTML = `<div class="block__icons">
${options.isTab ? '<div class="fn__flex-1"></div>' : `<div class="block__icon block__icon--show"> ${options.isTab ? '<div class="fn__flex-1"></div>' : `<div class="block__icon block__icon--show">
<svg><use xlink:href="#iconRiffCard"></use></svg> <svg><use xlink:href="#iconRiffCard"></use></svg>
</div> </div>
@ -205,11 +206,16 @@ export const bindCardEvent = (options: {
if (sticktabElement) { if (sticktabElement) {
openFile({ openFile({
position: "right", position: "right",
customData:{ custom: {
cardType: filterElement.getAttribute("data-cardtype") as TCardType, icon: "iconRiffCard",
id: filterElement.getAttribute("data-id"), title: window.siyuan.languages.spaceRepetition,
title: options.title data: {
} cardType: filterElement.getAttribute("data-cardtype") as TCardType,
id: filterElement.getAttribute("data-id"),
title: options.title
},
fn: newCardModel
},
}); });
if (options.dialog) { if (options.dialog) {
options.dialog.destroy(); options.dialog.destroy();

View file

@ -26,7 +26,6 @@ import {countBlockWord, countSelectWord} from "../layout/status";
import {showMessage} from "../dialog/message"; import {showMessage} from "../dialog/message";
import {objEquals} from "../util/functions"; import {objEquals} from "../util/functions";
import {resize} from "../protyle/util/resize"; import {resize} from "../protyle/util/resize";
import {newCardModel} from "../card/newCardTab";
import {Search} from "../search"; import {Search} from "../search";
export const openFileById = async (options: { export const openFileById = async (options: {
@ -96,9 +95,9 @@ export const openFile = (options: IOpenFileOptions) => {
} }
return; return;
} }
} else if (options.customData) { } else if (options.custom) {
const custom = allModels.custom.find((item) => { const custom = allModels.custom.find((item) => {
if (objEquals(item.data, options.customData)) { if (objEquals(item.data, options.custom.data)) {
if (!pdfIsLoading(item.parent.parent.element)) { if (!pdfIsLoading(item.parent.parent.element)) {
item.parent.parent.switchTab(item.parent.headElement); item.parent.parent.switchTab(item.parent.headElement);
item.parent.parent.showHeading(); item.parent.parent.showHeading();
@ -384,14 +383,14 @@ const newTab = (options: IOpenFileOptions) => {
} }
}); });
} }
} else if (options.customData) { } else if (options.custom) {
tab = new Tab({ tab = new Tab({
icon: "iconRiffCard", icon: options.custom.icon,
title: window.siyuan.languages.spaceRepetition, title: options.custom.title,
callback(tab) { callback(tab) {
tab.addModel(newCardModel({ tab.addModel(options.custom.fn({
tab, tab,
data: options.customData data: options.custom.data
})); }));
setPanelFocus(tab.panelElement.parentElement.parentElement); setPanelFocus(tab.panelElement.parentElement.parentElement);
} }

View file

@ -166,7 +166,7 @@ export class App {
getLocalStorage(() => { getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => { fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
window.siyuan.languages = lauguages; window.siyuan.languages = lauguages;
window.siyuan.menus = new Menus(); window.siyuan.menus = new Menus(siyuanApp);
bootSync(); bootSync();
fetchPost("/api/setting/getCloudUser", {}, userResponse => { fetchPost("/api/setting/getCloudUser", {}, userResponse => {
window.siyuan.user = userResponse.data; window.siyuan.user = userResponse.data;

View file

@ -34,8 +34,10 @@ import {isWindow} from "../util/functions";
import {hideAllElements} from "../protyle/ui/hideElements"; import {hideAllElements} from "../protyle/ui/hideElements";
import {focusByOffset, getSelectionOffset} from "../protyle/util/selection"; import {focusByOffset, getSelectionOffset} from "../protyle/util/selection";
import {Custom} from "./dock/Custom"; import {Custom} from "./dock/Custom";
import {App} from "../index";
export class Wnd { export class Wnd {
private app: App;
public id: string; public id: string;
public parent?: Layout; public parent?: Layout;
public element: HTMLElement; public element: HTMLElement;
@ -43,8 +45,9 @@ export class Wnd {
public children: Tab[] = []; public children: Tab[] = [];
public resize?: TDirection; public resize?: TDirection;
constructor(resize?: TDirection, parentType?: TLayout) { constructor(app: App, resize?: TDirection, parentType?: TLayout) {
this.id = genUUID(); this.id = genUUID();
this.app = app;
this.resize = resize; this.resize = resize;
this.element = document.createElement("div"); this.element = document.createElement("div");
this.element.classList.add("fn__flex-1", "fn__flex"); this.element.classList.add("fn__flex-1", "fn__flex");
@ -223,7 +226,7 @@ export class Wnd {
/// #if !BROWSER /// #if !BROWSER
if (!oldTab) { // 从主窗口拖拽到页签新窗口 if (!oldTab) { // 从主窗口拖拽到页签新窗口
if (wnd instanceof Wnd) { if (wnd instanceof Wnd) {
JSONToCenter(tabData, wnd); JSONToCenter(app, tabData, wnd);
oldTab = wnd.children[wnd.children.length - 1]; oldTab = wnd.children[wnd.children.length - 1];
ipcRenderer.send(Constants.SIYUAN_SEND_WINDOWS, {cmd: "closetab", data: tabData.id}); ipcRenderer.send(Constants.SIYUAN_SEND_WINDOWS, {cmd: "closetab", data: tabData.id});
it.querySelector("li[data-clone='true']").remove(); it.querySelector("li[data-clone='true']").remove();
@ -332,7 +335,7 @@ export class Wnd {
let oldTab = getInstanceById(tabData.id) as Tab; let oldTab = getInstanceById(tabData.id) as Tab;
/// #if !BROWSER /// #if !BROWSER
if (!oldTab) { // 从主窗口拖拽到页签新窗口 if (!oldTab) { // 从主窗口拖拽到页签新窗口
JSONToCenter(tabData, this); JSONToCenter(app, tabData, this);
oldTab = this.children[this.children.length - 1]; oldTab = this.children[this.children.length - 1];
ipcRenderer.send(Constants.SIYUAN_SEND_WINDOWS, {cmd: "closetab", data: tabData.id}); ipcRenderer.send(Constants.SIYUAN_SEND_WINDOWS, {cmd: "closetab", data: tabData.id});
getCurrentWindow().focus(); getCurrentWindow().focus();
@ -596,7 +599,7 @@ export class Wnd {
}).element); }).element);
}); });
window.siyuan.menus.menu.element.setAttribute("data-name", "tabList"); window.siyuan.menus.menu.element.setAttribute("data-name", "tabList");
const rect = target.getBoundingClientRect(); const rect = target.getBoundingClientRect();
window.siyuan.menus.menu.popup({ window.siyuan.menus.menu.popup({
x: rect.left + rect.width, x: rect.left + rect.width,
y: rect.top + rect.height, y: rect.top + rect.height,
@ -738,7 +741,7 @@ export class Wnd {
return; return;
} }
/// #endif /// #endif
const wnd = new Wnd(); const wnd = new Wnd(this.app);
window.siyuan.layout.centerLayout.addWnd(wnd); window.siyuan.layout.centerLayout.addWnd(wnd);
wnd.addTab(newCenterEmptyTab()); wnd.addTab(newCenterEmptyTab());
} }
@ -844,7 +847,7 @@ export class Wnd {
// 场景:没有打开的文档,点击标签面板打开 // 场景:没有打开的文档,点击标签面板打开
return this; return this;
} }
const wnd = new Wnd(direction); const wnd = new Wnd(this.app, direction);
if (direction === this.parent.direction) { if (direction === this.parent.direction) {
this.parent.addWnd(wnd, this.id); this.parent.addWnd(wnd, this.id);
} else if (this.parent.children.length === 1) { } else if (this.parent.children.length === 1) {

View file

@ -5,21 +5,23 @@ import {Model} from "../Model";
export class Custom extends Model { export class Custom extends Model {
private element: Element; private element: Element;
public data: any; public data: any;
public type: string;
public init: () => void; public init: () => void;
public destroy: () => void; public destroy: () => void;
public resize: () => void; public resize: () => void;
public update: () => void; public update: () => void;
constructor(options: { constructor(options: {
type: string,
tab: Tab, tab: Tab,
data: any, data: any,
destroy?: () => void, destroy?: () => void,
resize?: () => void, resize?: () => void,
update?: () => void, update?: () => void,
type: string, // 同一类型的唯一标识
init: () => void init: () => void
}) { }) {
super({id: options.tab.id}); super({id: options.tab.id});
this.type = options.type;
if (window.siyuan.config.fileTree.openFilesUseCurrentTab) { if (window.siyuan.config.fileTree.openFilesUseCurrentTab) {
options.tab.headElement.classList.add("item--unupdate"); options.tab.headElement.classList.add("item--unupdate");
} }

View file

@ -36,6 +36,7 @@ import {openHistory} from "../history/history";
import {Custom} from "./dock/Custom"; import {Custom} from "./dock/Custom";
import {newCardModel} from "../card/newCardTab"; import {newCardModel} from "../card/newCardTab";
import {openRecentDocs} from "../business/openRecentDocs"; import {openRecentDocs} from "../business/openRecentDocs";
import {App} from "../index";
export const setPanelFocus = (element: Element) => { export const setPanelFocus = (element: Element) => {
if (element.classList.contains("layout__tab--active") || element.classList.contains("layout__wnd--active")) { if (element.classList.contains("layout__tab--active") || element.classList.contains("layout__wnd--active")) {
@ -237,7 +238,7 @@ const JSONToDock = (json: any) => {
window.siyuan.layout.bottomDock = new Dock({position: "Bottom", data: json.bottom}); window.siyuan.layout.bottomDock = new Dock({position: "Bottom", data: json.bottom});
}; };
export const JSONToCenter = (json: ILayoutJSON, layout?: Layout | Wnd | Tab | Model, isStart = false) => { export const JSONToCenter = (app: App, json: ILayoutJSON, layout?: Layout | Wnd | Tab | Model, isStart = false) => {
let child: Layout | Wnd | Tab | Model; let child: Layout | Wnd | Tab | Model;
if (json.instance === "Layout") { if (json.instance === "Layout") {
if (!layout) { if (!layout) {
@ -258,7 +259,7 @@ export const JSONToCenter = (json: ILayoutJSON, layout?: Layout | Wnd | Tab | Mo
(layout as Layout).addLayout(child); (layout as Layout).addLayout(child);
} }
} else if (json.instance === "Wnd") { } else if (json.instance === "Wnd") {
child = new Wnd(json.resize, (layout as Layout).type); child = new Wnd(app, json.resize, (layout as Layout).type);
(layout as Layout).addWnd(child); (layout as Layout).addWnd(child);
if (json.width) { if (json.width) {
child.element.classList.remove("fn__flex-1"); child.element.classList.remove("fn__flex-1");
@ -338,15 +339,27 @@ export const JSONToCenter = (json: ILayoutJSON, layout?: Layout | Wnd | Tab | Mo
config: json.config config: json.config
})); }));
} else if (json.instance === "Custom") { } else if (json.instance === "Custom") {
(layout as Tab).addModel(newCardModel({ if (json.customModelType === "siyuan-card") {
tab: (layout as Tab), (layout as Tab).addModel(newCardModel({
data: json.data tab: (layout as Tab),
})); data: json.customModelData
}));
} else {
app.plugins.find(item => {
if (item.models[json.customModelType]) {
(layout as Tab).addModel(item.models[json.customModelType]({
tab: (layout as Tab),
data: json.customModelData
}));
return true;
}
});
}
} }
if (json.children) { if (json.children) {
if (Array.isArray(json.children)) { if (Array.isArray(json.children)) {
json.children.forEach((item: any, index: number) => { json.children.forEach((item: any, index: number) => {
JSONToCenter(item, layout ? child : window.siyuan.layout.layout, isStart); JSONToCenter(app, item, layout ? child : window.siyuan.layout.layout, isStart);
if (item.instance === "Tab" && index === (json.children as ILayoutJSON[]).length - 1) { if (item.instance === "Tab" && index === (json.children as ILayoutJSON[]).length - 1) {
const activeTabElement = (child as Wnd).headersElement.querySelector('[data-init-active="true"]') as HTMLElement; const activeTabElement = (child as Wnd).headersElement.querySelector('[data-init-active="true"]') as HTMLElement;
if (activeTabElement) { if (activeTabElement) {
@ -361,13 +374,13 @@ export const JSONToCenter = (json: ILayoutJSON, layout?: Layout | Wnd | Tab | Mo
} }
}); });
} else { } else {
JSONToCenter(json.children, child, isStart); JSONToCenter(app, json.children, child, isStart);
} }
} }
}; };
export const JSONToLayout = (isStart: boolean) => { export const JSONToLayout = (app: App, isStart: boolean) => {
JSONToCenter(window.siyuan.config.uiLayout.layout, undefined, isStart); JSONToCenter(app, window.siyuan.config.uiLayout.layout, undefined, isStart);
JSONToDock(window.siyuan.config.uiLayout); JSONToDock(window.siyuan.config.uiLayout);
// 启动时不打开页签,需要移除没有钉住的页签 // 启动时不打开页签,需要移除没有钉住的页签
if (window.siyuan.config.fileTree.closeTabsOnStart && isStart) { if (window.siyuan.config.fileTree.closeTabsOnStart && isStart) {
@ -472,7 +485,8 @@ export const layoutToJSON = (layout: Layout | Wnd | Tab | Model, json: any) => {
json.config = layout.config; json.config = layout.config;
} else if (layout instanceof Custom) { } else if (layout instanceof Custom) {
json.instance = "Custom"; json.instance = "Custom";
json.data = layout.data; json.customModelType = layout.type;
json.customModelData = layout.data;
} }
if (layout instanceof Layout || layout instanceof Wnd) { if (layout instanceof Layout || layout instanceof Wnd) {
@ -568,7 +582,7 @@ export const resizeTabs = () => {
}, 200); }, 200);
}; };
export const copyTab = (tab: Tab) => { export const copyTab = (app: App, tab: Tab) => {
return new Tab({ return new Tab({
icon: tab.icon, icon: tab.icon,
docIcon: tab.docIcon, docIcon: tab.docIcon,
@ -620,10 +634,23 @@ export const copyTab = (tab: Tab) => {
config: tab.model.config config: tab.model.config
}); });
} else if (tab.model instanceof Custom) { } else if (tab.model instanceof Custom) {
model = newCardModel({ const custom = tab.model as Custom;
tab, if (custom.type === "siyuan-card") {
data: tab.model.data model = newCardModel({
}); tab,
data: custom.data
});
} else {
app.plugins.find(item => {
if (item.models[custom.type]) {
model = item.models[custom.type]({
tab,
data: custom.data
});
return true;
}
});
}
} else if (!tab.model && tab.headElement) { } else if (!tab.model && tab.headElement) {
const initData = JSON.parse(tab.headElement.getAttribute("data-initdata") || "{}"); const initData = JSON.parse(tab.headElement.getAttribute("data-initdata") || "{}");
model = new Editor({ model = new Editor({

View file

@ -8,12 +8,13 @@ import {initTabMenu} from "./tab";
/// #endif /// #endif
import {Menu} from "./Menu"; import {Menu} from "./Menu";
import {hasTopClosestByTag} from "../protyle/util/hasClosest"; import {hasTopClosestByTag} from "../protyle/util/hasClosest";
import {App} from "../index";
export class Menus { export class Menus {
public menu: Menu; public menu: Menu;
constructor() { constructor(app: App) {
this.menu = new Menu(); this.menu = new Menu();
/// #if !MOBILE /// #if !MOBILE
window.addEventListener("contextmenu", (event) => { window.addEventListener("contextmenu", (event) => {
@ -23,7 +24,7 @@ export class Menus {
const dataType = target.getAttribute("data-type"); const dataType = target.getAttribute("data-type");
if (dataType === "tab-header") { if (dataType === "tab-header") {
this.unselect(); this.unselect();
initTabMenu((getInstanceById(target.getAttribute("data-id")) as Tab)).popup({ initTabMenu(app, (getInstanceById(target.getAttribute("data-id")) as Tab)).popup({
x: event.clientX, x: event.clientX,
y: event.clientY y: event.clientY
}); });

View file

@ -6,6 +6,7 @@ import {copyTab, resizeTabs} from "../layout/util";
import {openNewWindow} from "../window/openNewWindow"; import {openNewWindow} from "../window/openNewWindow";
/// #endif /// #endif
import {copySubMenu} from "./commonMenuItem"; import {copySubMenu} from "./commonMenuItem";
import {App} from "../index";
const closeMenu = (tab: Tab) => { const closeMenu = (tab: Tab) => {
const allTabs: Tab[] = []; const allTabs: Tab[] = [];
@ -115,12 +116,12 @@ const closeMenu = (tab: Tab) => {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
}; };
const splitSubMenu = (tab: Tab) => { const splitSubMenu = (app: App, tab: Tab) => {
const subMenus: IMenu[] = [{ const subMenus: IMenu[] = [{
icon: "iconSplitLR", icon: "iconSplitLR",
label: window.siyuan.languages.splitLR, label: window.siyuan.languages.splitLR,
click: () => { click: () => {
tab.parent.split("lr").addTab(copyTab(tab)); tab.parent.split("lr").addTab(copyTab(app, tab));
} }
}]; }];
if (tab.parent.children.length > 1) { if (tab.parent.children.length > 1) {
@ -140,7 +141,7 @@ const splitSubMenu = (tab: Tab) => {
icon: "iconSplitTB", icon: "iconSplitTB",
label: window.siyuan.languages.splitTB, label: window.siyuan.languages.splitTB,
click: () => { click: () => {
tab.parent.split("tb").addTab(copyTab(tab)); tab.parent.split("tb").addTab(copyTab(app, tab));
} }
}); });
@ -160,12 +161,12 @@ const splitSubMenu = (tab: Tab) => {
return subMenus; return subMenus;
}; };
export const initTabMenu = (tab: Tab) => { export const initTabMenu = (app: App, tab: Tab) => {
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();
closeMenu(tab); closeMenu(tab);
window.siyuan.menus.menu.append(new MenuItem({ window.siyuan.menus.menu.append(new MenuItem({
label: window.siyuan.languages.split, label: window.siyuan.languages.split,
submenu: splitSubMenu(tab) submenu: splitSubMenu(app, tab)
}).element); }).element);
const model = tab.model; const model = tab.model;
let rootId: string; let rootId: string;

View file

@ -64,7 +64,7 @@ class App {
getLocalStorage(() => { getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => { fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
window.siyuan.languages = lauguages; window.siyuan.languages = lauguages;
window.siyuan.menus = new Menus(); window.siyuan.menus = new Menus(siyuanApp);
document.title = window.siyuan.languages.siyuanNote; document.title = window.siyuan.languages.siyuanNote;
bootSync(); bootSync();
loadAssets(confResponse.data.conf.appearance); loadAssets(confResponse.data.conf.appearance);

View file

@ -6,6 +6,8 @@ import {MenuItem} from "../menus/Menu";
import {Menu as SiyuanMenu} from "../menus/Menu"; import {Menu as SiyuanMenu} from "../menus/Menu";
import {fetchGet, fetchPost, fetchSyncPost} from "../util/fetch"; import {fetchGet, fetchPost, fetchSyncPost} from "../util/fetch";
import {isMobile} from "../util/functions"; import {isMobile} from "../util/functions";
import {Custom} from "../layout/dock/Custom";
import {openFile} from "../editor/util";
export class Menu { export class Menu {
private menu: SiyuanMenu; private menu: SiyuanMenu;
@ -73,8 +75,9 @@ export const API = {
fetchPost, fetchPost,
fetchSyncPost, fetchSyncPost,
fetchGet, fetchGet,
Plugin: Plugin, isMobile,
openTab: openFile,
Plugin,
Dialog, Dialog,
Menu, Menu,
isMobile
}; };

View file

@ -2,12 +2,15 @@ import {App} from "../index";
import {EventBus} from "./EventBus"; import {EventBus} from "./EventBus";
import {fetchPost} from "../util/fetch"; import {fetchPost} from "../util/fetch";
import {isMobile, isWindow} from "../util/functions"; import {isMobile, isWindow} from "../util/functions";
import {Custom} from "../layout/dock/Custom";
import {Tab} from "../layout/Tab";
export class Plugin { export class Plugin {
public i18n: IObject; public i18n: IObject;
public eventBus: EventBus; public eventBus: EventBus;
public data: any; public data: any;
public name: string; public name: string;
public models: { [key: string]: (options: { tab: Tab, data: any }) => Custom } = {};
constructor(options: { constructor(options: {
app: App, app: App,
@ -89,4 +92,24 @@ export class Plugin {
}); });
}); });
} }
public createTab(options: {
type: string,
destroy?: () => void,
resize?: () => void,
update?: () => void,
init: () => void
}) {
const type2 = this.name + options.type;
this.models[type2] = (arg: { data: any, tab: Tab }) => new Custom({
tab: arg.tab,
type: type2,
data: arg.data,
init: options.init,
destroy: options.destroy,
resize: options.resize,
update: options.update,
});
return this.models[type2];
}
} }

View file

@ -291,11 +291,8 @@ declare interface ILayoutJSON extends ILayoutOptions {
rootId?: string rootId?: string
active?: boolean active?: boolean
pin?: boolean pin?: boolean
data?: { customModelData?: any
cardType: TCardType, customModelType?: string
id: string,
title?: string
}
config?: ISearchOption config?: ISearchOption
children?: ILayoutJSON[] | ILayoutJSON children?: ILayoutJSON[] | ILayoutJSON
} }
@ -310,7 +307,13 @@ declare interface IDockTab {
declare interface IOpenFileOptions { declare interface IOpenFileOptions {
searchData?: ISearchOption, // 搜索必填 searchData?: ISearchOption, // 搜索必填
customData?: any, // card 必填 // card 和自定义页签 必填
custom?: {
title: string,
icon: string,
data?: any
fn?: (options: { tab: import("../layout/Tab").Tab, data: any }) => import("../layout/Model").Model,
}
assetPath?: string, // asset 必填 assetPath?: string, // asset 必填
fileName?: string, // file 必填 fileName?: string, // file 必填
rootIcon?: string, // 文档图标 rootIcon?: string, // 文档图标

View file

@ -131,7 +131,7 @@ class App {
getLocalStorage(() => { getLocalStorage(() => {
fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => { fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages) => {
window.siyuan.languages = lauguages; window.siyuan.languages = lauguages;
window.siyuan.menus = new Menus(); window.siyuan.menus = new Menus(siyuanApp);
fetchPost("/api/setting/getCloudUser", {}, userResponse => { fetchPost("/api/setting/getCloudUser", {}, userResponse => {
window.siyuan.user = userResponse.data; window.siyuan.user = userResponse.data;
loadPlugins(siyuanApp); loadPlugins(siyuanApp);

View file

@ -11,7 +11,7 @@ import {getSearch} from "../util/functions";
import {initWindow} from "../boot/onGetConfig"; import {initWindow} from "../boot/onGetConfig";
import {App} from "../index"; import {App} from "../index";
export const init = (app:App) => { export const init = (app: App) => {
webFrame.setZoomFactor(window.siyuan.storage[Constants.LOCAL_ZOOM]); webFrame.setZoomFactor(window.siyuan.storage[Constants.LOCAL_ZOOM]);
globalShortcut(app); globalShortcut(app);
fetchPost("/api/system/getEmojiConf", {}, response => { fetchPost("/api/system/getEmojiConf", {}, response => {
@ -19,13 +19,13 @@ export const init = (app:App) => {
const layout = JSON.parse(sessionStorage.getItem("layout") || "{}"); const layout = JSON.parse(sessionStorage.getItem("layout") || "{}");
if (layout.layout) { if (layout.layout) {
JSONToCenter(layout.layout); JSONToCenter(app, layout.layout);
window.siyuan.layout.centerLayout = window.siyuan.layout.layout; window.siyuan.layout.centerLayout = window.siyuan.layout.layout;
return; return;
} }
const tabJSON = JSON.parse(getSearch("json")); const tabJSON = JSON.parse(getSearch("json"));
tabJSON.active = true; tabJSON.active = true;
JSONToCenter({ JSONToCenter(app, {
direction: "lr", direction: "lr",
resize: "lr", resize: "lr",
size: "auto", size: "auto",