diff --git a/manifest-beta.json b/manifest-beta.json index c74d94b..c65b2e7 100644 --- a/manifest-beta.json +++ b/manifest-beta.json @@ -1,8 +1,8 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.13.0", -"minAppVersion": "1.5.7", + "version": "2.13.1", + "minAppVersion": "1.5.7", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", "authorUrl": "https://excalidraw-obsidian.online", diff --git a/manifest.json b/manifest.json index 3807d3b..a9733b4 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.13.0", + "version": "2.13.1", "minAppVersion": "1.5.7", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/package-lock.json b/package-lock.json index f9bd735..aa42ca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3497,7 +3497,6 @@ "version": "0.18.0-25", "resolved": "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.18.0-25.tgz", "integrity": "sha512-aZKkzm1ENNUpwf9ANR+RA34fk2FYZNheHWNFj9CkNig/28bsS/MSVntWJNbk1qcqEQOdxhJkRhVN6NYlUtAZjA==", - "license": "MIT", "dependencies": { "@braintree/sanitize-url": "6.0.2", "@excalidraw/random-username": "1.1.0", diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 0bde7d7..7b118f4 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -921,8 +921,12 @@ FILENAME_HEAD: "Filename", //IFrameActionsMenu.tsx NARROW_TO_HEADING: "Narrow to heading...", + PIN_VIEW: "Pin view", + DO_NOT_PIN_VIEW: "Do not pin view", NARROW_TO_BLOCK: "Narrow to block...", SHOW_ENTIRE_FILE: "Show entire file", + SELECT_SECTION: "Select section from document", + SELECT_VIEW: "Select view from base", ZOOM_TO_FIT: "Zoom to fit", RELOAD: "Reload original link", OPEN_IN_BROWSER: "Open current link in browser", diff --git a/src/shared/Dialogs/Messages.ts b/src/shared/Dialogs/Messages.ts index 83981cd..21d0440 100644 --- a/src/shared/Dialogs/Messages.ts +++ b/src/shared/Dialogs/Messages.ts @@ -17,6 +17,15 @@ I build this plugin in my free time, as a labor of love. Curious about the philo
Buy Me a Coffee at ko-fi.com
`, +"2.13.1":` +## New +- Support for Obsidian bases as embeddables in Excalidraw. + - **Note:** The feature is only available to Insiders who have Obsidian 1.9.4 or later installed. + - If your base includes multiple views you can pin the desired view similar to filtering to a section (click top left # button; \`[[my.base|my view]]\`). + +## Fixed +- Cannot type in embedded web forms. In certain cases, typing within these embeds would trigger Excalidraw hotkeys instead of interacting with the embedded content. [#2403](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2403) +`, "2.13.0":`
diff --git a/src/view/ExcalidrawView.ts b/src/view/ExcalidrawView.ts index 15e9450..7aeec72 100644 --- a/src/view/ExcalidrawView.ts +++ b/src/view/ExcalidrawView.ts @@ -1708,7 +1708,9 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{ if(!this.excalidrawAPI || !this.excalidrawData.loaded || !this.isDirty()) { return; } - if((this.excalidrawAPI as ExcalidrawImperativeAPI).getAppState().activeTool.type !== "image") { + const api = this.excalidrawAPI as ExcalidrawImperativeAPI; + const st = api.getAppState(); + if(st.activeTool.type !== "image" && st.activeEmbeddable?.state !== "active") { this.forceSave(true); } }; diff --git a/src/view/components/CustomEmbeddable.tsx b/src/view/components/CustomEmbeddable.tsx index b901dfb..06efe59 100644 --- a/src/view/components/CustomEmbeddable.tsx +++ b/src/view/components/CustomEmbeddable.tsx @@ -9,6 +9,8 @@ import { ObsidianCanvasNode } from "src/view/managers/CanvasNodeFactory"; import { processLinkText, patchMobileView, setFileToLocalGraph } from "src/utils/customEmbeddableUtils"; import { EmbeddableMDCustomProps } from "src/shared/Dialogs/EmbeddableSettings"; +const CANVAS_VIEWTYPES = new Set(["markdown", "bases"]); + declare module "obsidian" { interface Workspace { floatingSplit: any; @@ -223,7 +225,7 @@ function RenderObsidianView( if(viewType === "canvas") { leafRef.current.leaf.view.canvas?.setReadonly(true); } - if ((viewType === "markdown") && view.canvasNodeFactory.isInitialized()) { + if (CANVAS_VIEWTYPES.has(viewType) && view.canvasNodeFactory.isInitialized()) { setKeepOnTop(); //I haven't found a better way of deciding if an .md file has its own view (e.g., kanban) or not //This runs only when the file is added, thus should not be a major performance issue @@ -295,6 +297,22 @@ function RenderObsidianView( canvasNode?.style.setProperty("--background-primary", color); canvasNodeContainer?.style.setProperty("background-color", color); } + canvasNode?.style.setProperty("--bases-cards-container-background","var(--background-primary)"); + canvasNode?.style.setProperty("--bases-embed-border-color","var(--background-modifier-border)"); + canvasNode?.style.setProperty("--bases-table-header-color","var(--text-muted)"); + canvasNode?.style.setProperty("--bases-table-header-background","var(--background-primary)"); + canvasNode?.style.setProperty("--bases-table-header-background-hover","var(--background-modifier-hover)"); + canvasNode?.style.setProperty("--bases-table-header-sort-mask","linear-gradient(to left, transparent var(--size-4-6), black var(--size-4-6))"); + canvasNode?.style.setProperty("--bases-table-border-color","var(--table-border-color)"); + canvasNode?.style.setProperty("--bases-table-row-background-hover","var(--table-row-background-hover)"); + canvasNode?.style.setProperty("--bases-table-cell-shadow-active","0 0 0 2px var(--interactive-accent)"); + canvasNode?.style.setProperty("--bases-table-cell-background-active","var(--background-primary)"); + canvasNode?.style.setProperty("--bases-table-cell-background-disabled","var(--background-primary-alt)"); + canvasNode?.style.setProperty("--bases-cards-container-background","var(--background-primary)"); + canvasNode?.style.setProperty("--bases-cards-background","var(--background-primary)"); + canvasNode?.style.setProperty("--bases-cards-cover-background","var(--background-primary-alt)"); + canvasNode?.style.setProperty("--bases-cards-shadow","0 0 0 1px var(--background-modifier-border)"); + canvasNode?.style.setProperty("--bases-cards-shadow-hover","0 0 0 1px var(--background-modifier-border-hover)"); if(mdProps.borderMatchElement) { const opacity = (mdProps?.borderOpacity ?? 50)/100; diff --git a/src/view/components/menu/EmbeddableActionsMenu.tsx b/src/view/components/menu/EmbeddableActionsMenu.tsx index fa27bd4..f310c8e 100644 --- a/src/view/components/menu/EmbeddableActionsMenu.tsx +++ b/src/view/components/menu/EmbeddableActionsMenu.tsx @@ -70,6 +70,28 @@ export class EmbeddableMenu { }, 5000); }; + private async actionBaseViewSelection (file: TFile, subpath: string, element: ExcalidrawEmbeddableElement) { + this.view.updateScene({appState: {activeEmbeddable: null}, captureUpdate: CaptureUpdateAction.NEVER}); + const views = Array.from( + (await this.view.app.vault.read(file)).matchAll(/\s*name\: (.*)$/gm) + ).map(x=>x?.[1]); + let values, display; + values = [""].concat( + views.map((b: string) => `#${cleanSectionHeading(b)}`) + ); + display = [t("DO_NOT_PIN_VIEW")].concat( + views.map((b: string) => b) + ); + + const newSubpath = await ScriptEngine.suggester( + this.view.app, display, values, t("SELECT_VIEW") + ); + if(!newSubpath && newSubpath!=="") return; + if (newSubpath !== subpath) { + this.updateElement(newSubpath, element, file); + } + } + private async actionMarkdownSelection (file: TFile, isExcalidrawFile: boolean, subpath: string, element: ExcalidrawEmbeddableElement) { this.view.updateScene({appState: {activeEmbeddable: null}, captureUpdate: CaptureUpdateAction.NEVER}); const sections = (await this.view.app.metadataCache.blockCache @@ -89,7 +111,7 @@ export class EmbeddableMenu { ); } const newSubpath = await ScriptEngine.suggester( - this.view.app, display, values, "Select section from document" + this.view.app, display, values, t("SELECT_SECTION") ); if(!newSubpath && newSubpath!=="") return; if (newSubpath !== subpath) { @@ -110,7 +132,7 @@ export class EmbeddableMenu { paragraphs.map((b: any) => `${b.node?.id ? `#^${b.node.id}: ` : ``}${b.display.trim()}`)); const selectedBlock = await ScriptEngine.suggester( - this.view.app, display, values, "Select section from document" + this.view.app, display, values, t("SELECT_SECTION") ); if(!selectedBlock) return; @@ -212,6 +234,7 @@ export class EmbeddableMenu { const { subpath, file } = processLinkText(link, view); if(!file) return; const isMD = file.extension==="md"; + const isBase = file.extension==="base"; const isExcalidrawFile = view.plugin.isExcalidrawFile(file); const isPDF = file.extension==="pdf"; const { x, y } = sceneCoordsToViewportCoords( { sceneX: element.x, sceneY: element.y }, appState); @@ -238,6 +261,14 @@ export class EmbeddableMenu { display: "block", }} > + {isBase && ( + this.actionBaseViewSelection(file, subpath, element)} + icon={ICONS.ZoomToSection} + /> + )} {isMD && (