diff --git a/app/src/assets/scss/base.scss b/app/src/assets/scss/base.scss index 2f3b26277..629885ef0 100644 --- a/app/src/assets/scss/base.scss +++ b/app/src/assets/scss/base.scss @@ -93,12 +93,14 @@ html { border-radius: 0; & > .protyle-breadcrumb, - & > .block__icons { // 关系图 + & > .block__icons { // 关系图、card padding-left: var(--b3-toolbar-left-mac); height: 32px; + min-height: 32px; } - .protyle-breadcrumb > .protyle-breadcrumb__space { + .protyle-breadcrumb > .protyle-breadcrumb__space, + & > .block__icons > .fn__flex-1{ -webkit-app-region: drag; min-width: 32px; diff --git a/app/src/assets/scss/business/_card.scss b/app/src/assets/scss/business/_card.scss index 7c9a65ed5..b1b170916 100644 --- a/app/src/assets/scss/business/_card.scss +++ b/app/src/assets/scss/business/_card.scss @@ -4,15 +4,6 @@ box-sizing: border-box; max-height: 100%; background-color: var(--b3-theme-surface); - - &.fullscreen > .card__header { - padding: 2px 8px 2px var(--b3-toolbar-left-mac); - } - } - - &__header { - display: flex; - padding: 8px 8px 8px 12px; } &__empty { diff --git a/app/src/assets/scss/util/_reset.scss b/app/src/assets/scss/util/_reset.scss index 6ab9aec4c..9d7532299 100644 --- a/app/src/assets/scss/util/_reset.scss +++ b/app/src/assets/scss/util/_reset.scss @@ -58,13 +58,6 @@ body { padding: 0 0 0 5px; } - .card__main.fullscreen > .card__header { - padding: 2px 108px 2px 12px; - & > .fn__flex-1 { - -webkit-app-region: drag; - } - } - .fullscreen { & > .protyle-breadcrumb, & > .block__icons { diff --git a/app/src/card/newCardTab.ts b/app/src/card/newCardTab.ts index 1c034c09f..e1fb95bac 100644 --- a/app/src/card/newCardTab.ts +++ b/app/src/card/newCardTab.ts @@ -2,7 +2,6 @@ import {Wnd} from "../layout/Wnd"; import {getInstanceById, getWndByLayout} from "../layout/util"; import {Tab} from "../layout/Tab"; import {Custom} from "../layout/dock/Custom"; -import {Dialog} from "../dialog"; import {bindCardEvent, genCardHTML} from "./openCard"; import {fetchPost} from "../util/fetch"; import {Protyle} from "../protyle"; @@ -10,7 +9,6 @@ import {Protyle} from "../protyle"; export const newCardTab = (options: { cardType: TCardType, id: string, - dialog: Dialog, title?: string }) => { let wnd: Wnd; @@ -21,53 +19,85 @@ export const newCardTab = (options: { if (!wnd) { wnd = getWndByLayout(window.siyuan.layout.centerLayout); } - let editor: Protyle + const tab = new Tab({ icon: "iconRiffCard", title: window.siyuan.languages.spaceRepetition, callback(tab) { - const custom = new Custom({ - type: "card", + tab.addModel(newCardModel({ tab, data: { - title: options.title, cardType: options.cardType, - id: options.id - }, - init(element) { - fetchPost(options.cardType === "all" ? "/api/riff/getRiffDueCards" : - (options.cardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), { - rootID: options.id, - deckID: options.id, - notebook: options.id, - }, (response) => { - element.innerHTML = genCardHTML({ - id: options.id, - cardType: options.cardType, - blocks: response.data.cards, - isTab: true, - }); - - editor = bindCardEvent({ - element, - id: options.id, - title: options.title, - cardType: options.cardType, - blocks: response.data.cards, - dialog: options.dialog, - }) - }); - }, - destroy() { - editor.destroy(); - }, - resize(){ - editor.resize(); + id: options.id, + title: options.title } - }); - tab.addModel(custom); + })); } }); wnd.split("lr").addTab(tab); - options.dialog.destroy(); +} + +export const newCardModel = (options: { + tab: Tab, + data: { + cardType: TCardType, + id: string, + title?: string + } +}) => { + let editor: Protyle; + const custom = new Custom({ + type: "card", + tab: options.tab, + data: options.data, + init() { + fetchPost(this.data.cardType === "all" ? "/api/riff/getRiffDueCards" : + (this.data.cardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), { + rootID: this.data.id, + deckID: this.data.id, + notebook: this.data.id, + }, (response) => { + this.element.innerHTML = genCardHTML({ + id: this.data.id, + cardType: this.data.cardType, + blocks: response.data.cards, + isTab: true, + }); + + editor = bindCardEvent({ + element: this.element, + id: this.data.id, + title: this.data.title, + cardType: this.data.cardType, + blocks: response.data.cards, + }); + }); + }, + destroy() { + if (editor) { + editor.destroy(); + } + }, + resize() { + if (editor) { + editor.resize(); + } + }, + update() { + fetchPost(this.data.cardType === "all" ? "/api/riff/getRiffDueCards" : + (this.data.cardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), { + rootID: this.data.id, + deckID: this.data.id, + notebook: this.data.id, + }, (response) => { + this.element.innerHTML = genCardHTML({ + id: this.data.id, + cardType: this.data.cardType, + blocks: response.data.cards, + isTab: true, + }); + }); + } + }); + return custom } diff --git a/app/src/card/openCard.ts b/app/src/card/openCard.ts index 94c32114c..22866c84b 100644 --- a/app/src/card/openCard.ts +++ b/app/src/card/openCard.ts @@ -20,8 +20,8 @@ export const genCardHTML = (options: { isTab: boolean }) => { return `
-
- ${window.siyuan.languages.riffCard} +
+ ${options.isTab ? '
' : `${window.siyuan.languages.riffCard}`}
1/${options.blocks.length}
@@ -97,7 +97,7 @@ export const bindCardEvent = (options: { blocks: ICard[], cardType: TCardType, id?: string, - dialog: Dialog, + dialog?: Dialog, }) => { let index = 0; const editor = new Protyle(options.element.querySelector("[data-type='render']") as HTMLElement, { @@ -188,16 +188,20 @@ export const bindCardEvent = (options: { newCardTab({ cardType: filterElement.getAttribute("data-cardtype") as TCardType, id: filterElement.getAttribute("data-id"), - dialog: options.dialog, title: options.title }); + if (options.dialog) { + options.dialog.destroy(); + } event.stopPropagation(); event.preventDefault(); return; } const closeElement = hasClosestByAttribute(target, "data-type", "close"); if (closeElement) { - options.dialog.destroy(); + if (options.dialog) { + options.dialog.destroy(); + } event.stopPropagation(); event.preventDefault(); return; diff --git a/app/src/dialog/processSystem.ts b/app/src/dialog/processSystem.ts index fee1691cb..b15a88d70 100644 --- a/app/src/dialog/processSystem.ts +++ b/app/src/dialog/processSystem.ts @@ -109,6 +109,11 @@ export const reloadSync = (data: { upsertRootIDs: string[], removeRootIDs: strin allModels.search.forEach(item => { item.parent.panelElement.querySelector("#searchInput").dispatchEvent(new CustomEvent("input")); }); + allModels.custom.forEach(item => { + if (item.update) { + item.update(); + } + }); /// #endif }; diff --git a/app/src/layout/Wnd.ts b/app/src/layout/Wnd.ts index 2b4be1209..3f63b280c 100644 --- a/app/src/layout/Wnd.ts +++ b/app/src/layout/Wnd.ts @@ -648,7 +648,9 @@ export class Wnd { } } if (model instanceof Custom) { - model.destroy(); + if (model.destroy) { + model.destroy(); + } } model.send("closews", {}); } diff --git a/app/src/layout/dock/Custom.ts b/app/src/layout/dock/Custom.ts index 0ac9425b4..a7e419420 100644 --- a/app/src/layout/dock/Custom.ts +++ b/app/src/layout/dock/Custom.ts @@ -4,42 +4,34 @@ import {Model} from "../Model"; export class Custom extends Model { private element: Element; + public data: any; + public init: () => void; + public destroy: () => void; + public resize: () => void; + public update: () => void; constructor(options: { tab: Tab, data: any, destroy?: () => void, resize?: () => void, + update?: () => void, type: string, // 同一类型的唯一标识 - init: (element: Element) => void + init: () => void }) { super({id: options.tab.id}); if (window.siyuan.config.fileTree.openFilesUseCurrentTab) { options.tab.headElement.classList.add("item--unupdate"); } this.element = options.tab.panelElement; - options.init(this.element); + this.data = options.data; this.element.addEventListener("click", () => { setPanelFocus(this.element.parentElement.parentElement); }); - this.data = options.data; + this.init = options.init; this.destroy = options.destroy; this.resize = options.resize; - } - - public destroy() { - if (this.destroy) { - this.destroy(); - } - } - - public resize() { - if (this.resize) { - this.resize(); - } - } - - private update() { - // TODO + this.update = options.update; + this.init(); } } diff --git a/app/src/layout/util.ts b/app/src/layout/util.ts index b1474a8f5..24d26d5e9 100644 --- a/app/src/layout/util.ts +++ b/app/src/layout/util.ts @@ -33,6 +33,8 @@ import {setTabPosition} from "../window/setHeader"; /// #endif import {showMessage} from "../dialog/message"; import {getIdZoomInByPath} from "../util/pathName"; +import {Custom} from "./dock/Custom"; +import {newCardModel} from "../card/newCardTab"; export const setPanelFocus = (element: Element) => { if (element.classList.contains("layout__tab--active") || element.classList.contains("layout__wnd--active")) { @@ -334,6 +336,11 @@ export const JSONToCenter = (json: any, layout?: Layout | Wnd | Tab | Model, isS tab: (layout as Tab), config: json.config })); + } else if (json.instance === "Custom") { + (layout as Tab).addModel(newCardModel({ + tab: (layout as Tab), + data: json.data + })); } if (json.children) { if (Array.isArray(json.children)) { @@ -462,6 +469,9 @@ export const layoutToJSON = (layout: Layout | Wnd | Tab | Model, json: any) => { } else if (layout instanceof Search) { json.instance = "Search"; json.config = layout.config; + } else if (layout instanceof Custom) { + json.instance = "Custom"; + json.data = layout.data; } if (layout instanceof Layout || layout instanceof Wnd) { @@ -548,8 +558,10 @@ export const resizeTabs = () => { }); }); models.custom.forEach(item => { - item.resize(); - }) + if (item.resize) { + item.resize(); + } + }); pdfResize(); hideAllElements(["gutter"]); }, 200); @@ -606,6 +618,11 @@ export const copyTab = (tab: Tab) => { tab: newTab, config: tab.model.config }); + } else if (tab.model instanceof Custom) { + model = newCardModel({ + tab, + data: tab.model.data + }); } else if (!tab.model && tab.headElement) { const initData = JSON.parse(tab.headElement.getAttribute("data-initdata") || "{}"); model = new Editor({