From 1692d07b37f39845304f9593f24088255c19096c Mon Sep 17 00:00:00 2001 From: zsviczian Date: Sun, 2 Jul 2023 08:03:46 +0200 Subject: [PATCH] before adding backup store --- src/ExcalidrawAutomate.ts | 15 +++++++++++++-- src/ExcalidrawView.ts | 22 ++++++++++++++++++++++ src/MarkdownPostProcessor.ts | 2 +- src/dialogs/FolderSuggester.ts | 2 +- src/dialogs/SuggesterInfo.ts | 6 ++++++ src/lang/locale/en.ts | 6 +++--- src/utils/ImageCache.ts | 34 +++------------------------------- src/utils/ObsidianUtils.ts | 22 +++++++++++++--------- 8 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/ExcalidrawAutomate.ts b/src/ExcalidrawAutomate.ts index 2e75390..4f02108 100644 --- a/src/ExcalidrawAutomate.ts +++ b/src/ExcalidrawAutomate.ts @@ -24,7 +24,7 @@ import { fileid, GITHUB_RELEASES, } from "./Constants"; -import { getDrawingFilename, } from "./utils/FileUtils"; +import { getDrawingFilename, getNewUniqueFilepath, } from "./utils/FileUtils"; import { //debug, embedFontsInSVG, @@ -38,7 +38,7 @@ import { scaleLoadedImage, wrapTextAtCharLength, } from "./utils/Utils"; -import { getNewOrAdjacentLeaf, isObsidianThemeDark } from "./utils/ObsidianUtils"; +import { getAttachmentsFolderAndFilePath, getNewOrAdjacentLeaf, isObsidianThemeDark } from "./utils/ObsidianUtils"; import { AppState, BinaryFileData, DataURL, ExcalidrawImperativeAPI, Point } from "@zsviczian/excalidraw/types/types"; import { EmbeddedFile, EmbeddedFilesLoader, FileData } from "./EmbeddedFileLoader"; import { tex2dataURL } from "./LaTeX"; @@ -108,6 +108,16 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface { get obsidian() { return obsidian_module; }; + + async getAttachmentFilepath(filename: string): Promise { + if (!this.targetView || !this.targetView?.file) { + errorMessage("targetView not set", "getAttachmentFolderAndFilePath()"); + return null; + } + const folderAndPath = await getAttachmentsFolderAndFilePath(app,this.targetView.file.path, filename); + return getNewUniqueFilepath(app.vault, filename, folderAndPath.folder); + } + plugin: ExcalidrawPlugin; targetView: ExcalidrawView = null; //the view currently edited elementsDict: {[key:string]:any}; //contains the ExcalidrawElements currently edited in Automate indexed by el.id @@ -1049,6 +1059,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface { topY: number, imageFile: TFile | string, scale: boolean = true, //true will scale the image to MAX_IMAGE_SIZE, false will insert image at 100% of its size + ): Promise { const id = nanoid(); const loader = new EmbeddedFilesLoader( diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index 328a515..d514a7c 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -1024,6 +1024,28 @@ export default class ExcalidrawView extends TextFileView { keys.altKey = true; } const leaf = getLeaf(this.plugin,this.leaf,keys); + + try { + //@ts-ignore + const drawIO = app.plugins.plugins["drawio-obsidian"]; + if(drawIO && drawIO._loaded) { + if(file.extension === "svg") { + const svg = await this.app.vault.cachedRead(file); + if(/(<|\<)(mxfile|mxgraph)/i.test(svg)) { + leaf.setViewState({ + type: "diagram-edit", + state: { + file: file.path + } + }); + return; + } + } + } + } catch(e) { + console.error(e); + } + await leaf.openFile(file, subpath ? { active: !this.linksAlwaysOpenInANewPane, eState: { subpath } } : undefined); //if file exists open file and jump to reference //view.app.workspace.setActiveLeaf(leaf, true, true); //0.15.4 ExcaliBrain focus issue } catch (e) { diff --git a/src/MarkdownPostProcessor.ts b/src/MarkdownPostProcessor.ts index f941c4f..3de60b2 100644 --- a/src/MarkdownPostProcessor.ts +++ b/src/MarkdownPostProcessor.ts @@ -163,7 +163,7 @@ const getIMG = async ( return img; } - const cacheKey = {...filenameParts, isDark: theme==="dark", isSVG: false, scale:1}; + const cacheKey = {...filenameParts, isDark: theme==="dark", isSVG: true, scale:1}; if(cacheReady) { const src = await imageCache.get(cacheKey); if(src) { diff --git a/src/dialogs/FolderSuggester.ts b/src/dialogs/FolderSuggester.ts index caa5716..85a0886 100644 --- a/src/dialogs/FolderSuggester.ts +++ b/src/dialogs/FolderSuggester.ts @@ -196,7 +196,7 @@ export abstract class SuggestionModal extends FuzzySuggestModal { // TODO: Figure out a better way to do this. Idea from Periodic Notes plugin this.app.keymap.pushScope(this.scope); - document.body.appendChild(this.suggestEl); + this.inputEl.ownerDocument.body.appendChild(this.suggestEl); this.popper = createPopper(this.inputEl, this.suggestEl, { placement: "bottom-start", modifiers: [ diff --git a/src/dialogs/SuggesterInfo.ts b/src/dialogs/SuggesterInfo.ts index 11ada8d..5aab4b2 100644 --- a/src/dialogs/SuggesterInfo.ts +++ b/src/dialogs/SuggesterInfo.ts @@ -516,6 +516,12 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ desc: "Access functions and objects available on the Obsidian Module", after: "", }, + { + field: "getAttachmentFilepath", + code: "async getAttachmentFilepath(filename: string): Promise", + desc: "This asynchronous function should be awaited. It retrieves the filepath to a new file, taking into account the attachments preference settings in Obsidian. If the attachment folder doesn't exist, it creates it. The function returns the complete path to the file. If the provided filename already exists, the function will append '_[number]' before the extension to generate a unique filename.", + after: "", + }, { field: "setViewModeEnabled", code: "setViewModeEnabled(enabled: boolean): void;", diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index ea0acdd..41e4055 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -230,11 +230,11 @@ FILENAME_HEAD: "Filename", "the plugin will open it in a browser. " + "When Obsidian files change, the matching [[link]] in your drawings will also change. " + "If you don't want text accidentally changing in your drawings use [[links|with aliases]].", - ADJACENT_PANE_NAME: "Open in adjacent pane", + ADJACENT_PANE_NAME: "Reuse adjacent pane", ADJACENT_PANE_DESC: `When ${labelCTRL()}+${labelSHIFT()} clicking a link in Excalidraw, by default the plugin will open the link in a new pane. ` + - "Turning this setting on, Excalidraw will first look for an existing adjacent pane, and try to open the link there. " + - "Excalidraw will look for the adjacent pane based on your focus/navigation history, i.e. the workpane that was active before you " + + "Turning this setting on, Excalidraw will first look for an existing pane, and try to open the link there. " + + "Excalidraw will look for the other workspace pane based on your focus/navigation history, i.e. the workpane that was active before you " + "activated Excalidraw.", MAINWORKSPACE_PANE_NAME: "Open in main workspace", MAINWORKSPACE_PANE_DESC: diff --git a/src/utils/ImageCache.ts b/src/utils/ImageCache.ts index 13df3f5..90f5da2 100644 --- a/src/utils/ImageCache.ts +++ b/src/utils/ImageCache.ts @@ -3,7 +3,8 @@ import ExcalidrawPlugin from "src/main"; //@ts-ignore const DB_NAME = "Excalidraw " + app.appId; -const STORE_NAME = "imageCache"; +const CACHE_STORE_NAME = "imageCache"; +const BACKUP_STORE = "drawingBAK"; type FileCacheData = { mtime: number; imageBase64: string }; @@ -150,21 +151,6 @@ class ImageCache { return transaction.objectStore(this.storeName); } - public async openDB(): Promise { - return new Promise((resolve, reject) => { - const request = indexedDB.open(this.dbName); - - request.onerror = () => { - reject(new Error("Failed to open IndexedDB database.")); - }; - - request.onsuccess = () => { - const db = request.result as IDBDatabase; - resolve(db); - }; - }); - } - private async getCacheData(key: string): Promise { const store = await this.getObjectStore("readonly"); const request = store.get(key); @@ -181,20 +167,6 @@ class ImageCache { }); } - public async isCached(key_: ImageKey): Promise { - const key = getKey(key_); - return this.getCacheData(key).then((cachedData) => { - if (cachedData) { - const file = app.vault.getAbstractFileByPath(key_.filepath.split("#")[0]); - if (!file || !(file instanceof TFile)) return false; - if (cachedData.mtime === file.stat.mtime) { - return true; - } - } - return false; - }); - } - public isReady(): boolean { return !!this.db && !this.isInitializing && !!this.plugin && this.plugin.settings.allowImageCache; } @@ -253,4 +225,4 @@ class ImageCache { } } -export const imageCache = new ImageCache(DB_NAME, STORE_NAME); \ No newline at end of file +export const imageCache = new ImageCache(DB_NAME, CACHE_STORE_NAME); \ No newline at end of file diff --git a/src/utils/ObsidianUtils.ts b/src/utils/ObsidianUtils.ts index 8ed97f2..02b6fbb 100644 --- a/src/utils/ObsidianUtils.ts +++ b/src/utils/ObsidianUtils.ts @@ -83,43 +83,47 @@ const getLeafLoc = (leaf: WorkspaceLeaf): ["main" | "popout" | "left" | "right" export const getNewOrAdjacentLeaf = ( plugin: ExcalidrawPlugin, leaf: WorkspaceLeaf -): WorkspaceLeaf => { +): WorkspaceLeaf | null => { const [leafLoc, mainLeavesIds] = getLeafLoc(leaf); - const getMainLeaf = ():WorkspaceLeaf => { + const getMostRecentOrAvailableLeafInMainWorkspace = (inDifferentTabGroup?: boolean):WorkspaceLeaf => { let mainLeaf = app.workspace.getMostRecentLeaf(); if(mainLeaf && mainLeaf !== leaf && mainLeaf.view?.containerEl.ownerDocument === document) { + //Found a leaf in the main workspace that is not the originating leaf return mainLeaf; } + //Iterate all leaves in the main workspace and find the first one that is not the originating leaf mainLeaf = null; mainLeavesIds .forEach((id:any)=> { const l = app.workspace.getLeafById(id); if(mainLeaf || !l.view?.navigation || - leaf === l + leaf === l || + //@ts-ignore + (inDifferentTabGroup && (l?.parent === leaf?.parent)) ) return; mainLeaf = l; }) return mainLeaf; } - //1 + //1 - In Main Workspace if(plugin.settings.openInMainWorkspace || ["main","left","right"].contains(leafLoc)) { - //1.1 + //1.1 - Create new leaf in main workspace if(!plugin.settings.openInAdjacentPane) { if(leafLoc === "main") { return app.workspace.createLeafBySplit(leaf); } - const ml = getMainLeaf(); + const ml = getMostRecentOrAvailableLeafInMainWorkspace(); return ml ? (ml.view.getViewType() === "empty" ? ml : app.workspace.createLeafBySplit(ml)) : app.workspace.getLeaf(true); } - //1.2 - const ml = getMainLeaf(); - return ml ?? app.workspace.getLeaf(true); + //1.2 - Reuse leaf if it is adjacent + const ml = getMostRecentOrAvailableLeafInMainWorkspace(true); + return ml ?? app.workspace.createLeafBySplit(leaf); //app.workspace.getLeaf(true); } //2