From 2b3037402af6e61e29c4f3665c3a53dfb67afa31 Mon Sep 17 00:00:00 2001 From: zsviczian Date: Thu, 21 Dec 2023 20:51:21 +0100 Subject: [PATCH] 2.0.11 --- docs/API/ExcalidrawAutomate.d.ts | 6 +- manifest.json | 2 +- package.json | 7 +- src/EmbeddedFileLoader.ts | 4 +- src/ExcalidrawAutomate.ts | 51 ++++++- src/ExcalidrawData.ts | 27 +++- src/ExcalidrawLib.d.ts | 17 ++- src/ExcalidrawView.ts | 24 +-- src/LaTeX.ts | 4 +- src/Scripts.ts | 2 +- src/customEmbeddable.tsx | 4 +- src/dialogs/EmbeddableSettings.ts | 6 +- src/dialogs/ExportDialog.ts | 2 +- src/dialogs/InsertPDFModal.ts | 2 +- src/dialogs/Messages.ts | 22 +++ src/dialogs/PenSettingsModal.ts | 2 +- src/dialogs/SuggesterInfo.ts | 110 +++++++++++--- src/dialogs/UniversalInsertFileModal.ts | 2 +- src/index.ts | 4 +- src/lang/locale/en.ts | 21 ++- src/main.ts | 93 +++++++++++- src/menu/EmbeddableActionsMenu.tsx | 4 +- src/menu/ObsidianMenu.tsx | 2 +- src/menu/ToolsPanel.tsx | 2 +- src/ocr/Taskbone.ts | 2 +- src/settings.ts | 46 +++++- .../elements/ExcalidrawElement.ts | 2 +- src/svgToExcalidraw/types.ts | 2 +- src/utils/AIUtils.ts | 137 +++++++++++++++--- src/utils/CustomEmbeddableUtils.ts | 2 +- src/utils/DynamicStyling.ts | 4 +- src/utils/FileUtils.ts | 6 +- src/utils/GetElementAtPointer.ts | 2 +- src/utils/MermaidUtils.ts | 2 +- src/utils/Utils.ts | 6 +- 35 files changed, 504 insertions(+), 127 deletions(-) diff --git a/docs/API/ExcalidrawAutomate.d.ts b/docs/API/ExcalidrawAutomate.d.ts index 6df7364..dd7afa0 100644 --- a/docs/API/ExcalidrawAutomate.d.ts +++ b/docs/API/ExcalidrawAutomate.d.ts @@ -1,15 +1,15 @@ /// import ExcalidrawPlugin from "src/main"; -import { FillStyle, StrokeStyle, ExcalidrawElement, ExcalidrawBindableElement, FileId, NonDeletedExcalidrawElement, ExcalidrawImageElement, StrokeRoundness, RoundnessType } from "@zsviczian/excalidraw/types/element/types"; +import { FillStyle, StrokeStyle, ExcalidrawElement, ExcalidrawBindableElement, FileId, NonDeletedExcalidrawElement, ExcalidrawImageElement, StrokeRoundness, RoundnessType } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { Editor, OpenViewState, TFile, WorkspaceLeaf } from "obsidian"; import * as obsidian_module from "obsidian"; import ExcalidrawView, { ExportSettings } from "src/ExcalidrawView"; -import { AppState, BinaryFileData, DataURL, ExcalidrawImperativeAPI, Point } from "@zsviczian/excalidraw/types/types"; +import { AppState, BinaryFileData, DataURL, ExcalidrawImperativeAPI, Point } from "@zsviczian/excalidraw/types/excalidraw/types"; import { EmbeddedFilesLoader } from "src/EmbeddedFileLoader"; import { ConnectionPoint, DeviceType } from "src/types"; import { ColorMaster } from "colormaster"; import { TInput } from "colormaster/types"; -import { ClipboardData } from "@zsviczian/excalidraw/types/clipboard"; +import { ClipboardData } from "@zsviczian/excalidraw/types/excalidraw/clipboard"; import { PaneTarget } from "src/utils/ModifierkeyHelper"; export declare class ExcalidrawAutomate { /** diff --git a/manifest.json b/manifest.json index 115d5ba..675fcad 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.0.10", + "version": "2.0.11", "minAppVersion": "1.1.6", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/package.json b/package.json index df867f7..34820af 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "author": "", "license": "MIT", "dependencies": { - "@zsviczian/excalidraw": "0.17.1-obsidian-3", + "@zsviczian/excalidraw": "0.17.1-obsidian-6", "chroma-js": "^2.4.2", "clsx": "^2.0.0", "colormaster": "^1.2.1", @@ -47,8 +47,9 @@ "@rollup/plugin-typescript": "^11.1.2", "@types/chroma-js": "^2.4.0", "@types/js-beautify": "^1.14.0", - "@types/node": "^20.5.6", - "@types/react-dom": "^18.2.7", + "@types/node": "^20.10.5", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", "@zerollup/ts-transform-paths": "^1.7.18", "cross-env": "^7.0.3", "eslint-config-prettier": "^9.0.0", diff --git a/src/EmbeddedFileLoader.ts b/src/EmbeddedFileLoader.ts index c7dec9f..2c4eafc 100644 --- a/src/EmbeddedFileLoader.ts +++ b/src/EmbeddedFileLoader.ts @@ -1,8 +1,8 @@ //https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api //https://img.youtube.com/vi/uZz5MgzWXiM/maxresdefault.jpg -import { ExcalidrawElement, ExcalidrawImageElement, FileId } from "@zsviczian/excalidraw/types/element/types"; -import { BinaryFileData, DataURL } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawElement, ExcalidrawImageElement, FileId } from "@zsviczian/excalidraw/types/excalidraw/element/types"; +import { BinaryFileData, DataURL } from "@zsviczian/excalidraw/types/excalidraw/types"; import { App, MarkdownRenderer, Notice, TFile } from "obsidian"; import { ASSISTANT_FONT, diff --git a/src/ExcalidrawAutomate.ts b/src/ExcalidrawAutomate.ts index b466dab..b33a7d5 100644 --- a/src/ExcalidrawAutomate.ts +++ b/src/ExcalidrawAutomate.ts @@ -10,7 +10,7 @@ import { ExcalidrawTextElement, StrokeRoundness, RoundnessType, -} from "@zsviczian/excalidraw/types/element/types"; +} from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { Editor, normalizePath, Notice, OpenViewState, RequestUrlResponse, TFile, TFolder, WorkspaceLeaf } from "obsidian"; import * as obsidian_module from "obsidian"; import ExcalidrawView, { ExportSettings, TextMode } from "src/ExcalidrawView"; @@ -51,7 +51,7 @@ import { wrapTextAtCharLength, } from "src/utils/Utils"; import { getAttachmentsFolderAndFilePath, getLeaf, getNewOrAdjacentLeaf, isObsidianThemeDark } from "src/utils/ObsidianUtils"; -import { AppState, BinaryFileData, DataURL, ExcalidrawImperativeAPI, Point } from "@zsviczian/excalidraw/types/types"; +import { AppState, BinaryFileData, DataURL, ExcalidrawImperativeAPI, Point } from "@zsviczian/excalidraw/types/excalidraw/types"; import { EmbeddedFile, EmbeddedFilesLoader, FileData } from "src/EmbeddedFileLoader"; import { tex2dataURL } from "src/LaTeX"; import { GenericInputPrompt, NewFileActions, Prompt } from "src/dialogs/Prompt"; @@ -75,9 +75,9 @@ import CMYKPlugin from "colormaster/plugins/cmyk"; import { TInput } from "colormaster/types"; import {ConversionResult, svgToExcalidraw} from "src/svgToExcalidraw/parser" import { ROUNDNESS } from "src/constants/constants"; -import { ClipboardData } from "@zsviczian/excalidraw/types/clipboard"; +import { ClipboardData } from "@zsviczian/excalidraw/types/excalidraw/clipboard"; import { emulateKeysForLinkClick, KeyEvent, PaneTarget } from "src/utils/ModifierkeyHelper"; -import { Mutable } from "@zsviczian/excalidraw/types/utility-types"; +import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import PolyBool from "polybooljs"; import { EmbeddableMDCustomProps } from "./dialogs/EmbeddableSettings"; import { @@ -85,6 +85,7 @@ import { postOpenAI as _postOpenAI, extractCodeBlocks as _extractCodeBlocks, } from "./utils/AIUtils"; +import { EXCALIDRAW_AUTOMATE_INFO } from "./dialogs/SuggesterInfo"; extendPlugins([ HarmonyPlugin, @@ -123,6 +124,41 @@ export class ExcalidrawAutomate { return DEVICE; } + public help(target: Function | string) { + if (!target) { + console.log("Usage: ea.help(ea.functionName) or ea.help('propertyName')"); + return; + } + + let funcInfo; + + if (typeof target === 'function') { + funcInfo = EXCALIDRAW_AUTOMATE_INFO.find((info) => info.field === target.name); + } else if (typeof target === 'string') { + funcInfo = EXCALIDRAW_AUTOMATE_INFO.find((info) => info.field === target); + } + + if(!funcInfo) { + console.log("Usage: ea.help(ea.functionName) or\nea.help('propertyName') - notice property name is in quotes"); + return; + } + + if (funcInfo.desc) { + const formattedDesc = funcInfo.desc + .replaceAll("
", "\n") + .replace(/(.*?)<\/code>/g, '%c\u200b$1%c') // Zero-width space + .replace(/(.*?)<\/b>/g, '%c\u200b$1%c') // Zero-width space + .replace(/(.*?)<\/a>/g, (_, href, text) => `%c\u200b${text}%c\u200b (link: ${href})`); // Zero-width non-joiner + + const styles = Array.from({ length: (formattedDesc.match(/%c/g) || []).length }, (_, i) => i % 2 === 0 ? 'color: #007bff;' : ''); + + console.log(`Declaration: ${funcInfo.code}`); + console.log(`Description: ${formattedDesc}`, ...styles); + } else { + console.log("Description not available for this function."); + } + } + /** * Post's an AI request to the OpenAI API and returns the response. * @param request @@ -1264,15 +1300,16 @@ export class ExcalidrawAutomate { * Adds a mermaid diagram to ExcalidrawAutomate elements * @param diagram string containing the mermaid diagram * @param groupElements default is trud. If true, the elements will be grouped - * @returns the ids of the elements that were created + * @returns the ids of the elements that were created or null if there was an error */ async addMermaid( diagram: string, groupElements: boolean = true, - ): Promise { + ): Promise { const result = await mermaidToExcalidraw(diagram, {fontSize: this.style.fontSize}); const ids:string[] = []; - if(!result) return ids; + if(!result) return null; + if(result?.error) return result.error; if(result?.elements) { result.elements.forEach(el=>{ diff --git a/src/ExcalidrawData.ts b/src/ExcalidrawData.ts index 8454824..99af39d 100644 --- a/src/ExcalidrawData.ts +++ b/src/ExcalidrawData.ts @@ -42,6 +42,7 @@ import { hasExportTheme, isVersionNewerThanOther, LinkParts, + updateFrontmatterInString, wrapTextAtCharLength, } from "./utils/Utils"; import { cleanBlockRef, cleanSectionHeading, getAttachmentsFolderAndFilePath, isObsidianThemeDark } from "./utils/ObsidianUtils"; @@ -49,8 +50,8 @@ import { ExcalidrawElement, ExcalidrawImageElement, FileId, -} from "@zsviczian/excalidraw/types/element/types"; -import { BinaryFiles, DataURL, SceneData } from "@zsviczian/excalidraw/types/types"; +} from "@zsviczian/excalidraw/types/excalidraw/element/types"; +import { BinaryFiles, DataURL, SceneData } from "@zsviczian/excalidraw/types/excalidraw/types"; import { EmbeddedFile, MimeType } from "./EmbeddedFileLoader"; import { ConfirmationPrompt } from "./dialogs/Prompt"; import { getMermaidImageElements, getMermaidText, shouldRenderMermaid } from "./utils/MermaidUtils"; @@ -122,7 +123,7 @@ export const REGEX_LINK = { //added \n at and of DRAWING_REG: https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/357 const DRAWING_REG = /\n# Drawing\n[^`]*(```json\n)([\s\S]*?)```\n/gm; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/182 const DRAWING_REG_FALLBACK = /\n# Drawing\n(```json\n)?(.*)(```)?(%%)?/gm; -const DRAWING_COMPRESSED_REG = +export const DRAWING_COMPRESSED_REG = /(\n# Drawing\n[^`]*(?:```compressed\-json\n))([\s\S]*?)(```\n)/gm; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/182 const DRAWING_COMPRESSED_REG_FALLBACK = /(\n# Drawing\n(?:```compressed\-json\n)?)(.*)((```)?(%%)?)/gm; @@ -243,6 +244,26 @@ const estimateMaxLineLen = (text: string, originalText: string): number => { const wrap = (text: string, lineLen: number) => lineLen ? wrapTextAtCharLength(text, lineLen, false, 0) : text; +export const getExcalidrawMarkdownHeaderSection = (data:string, keys:[string,string][]):string => { + let trimLocation = data.search(/(^%%\n)?# Text Elements\n/m); + if (trimLocation == -1) { + trimLocation = data.search(/(%%\n)?# Drawing\n/); + } + if (trimLocation == -1) { + return data; + } + + let header = updateFrontmatterInString(data.substring(0, trimLocation),keys); + //this should be removed at a later time. Left it here to remediate 1.4.9 mistake + const REG_IMG = /(^---[\w\W]*?---\n)(!\[\[.*?]]\n(%%\n)?)/m; //(%%\n)? because of 1.4.8-beta... to be backward compatible with anyone who installed that version + if (header.match(REG_IMG)) { + header = header.replace(REG_IMG, "$1"); + } + //end of remove + return header; +} + + export class ExcalidrawData { public textElements: Map< string, diff --git a/src/ExcalidrawLib.d.ts b/src/ExcalidrawLib.d.ts index 1b4319b..479cf6f 100644 --- a/src/ExcalidrawLib.d.ts +++ b/src/ExcalidrawLib.d.ts @@ -1,9 +1,9 @@ -import { RestoredDataState } from "@zsviczian/excalidraw/types/data/restore"; -import { ImportedDataState } from "@zsviczian/excalidraw/types/data/types"; -import { BoundingBox } from "@zsviczian/excalidraw/types/element/bounds"; -import { ExcalidrawBindableElement, ExcalidrawElement, ExcalidrawFrameElement, ExcalidrawTextElement, FontFamilyValues, FontString, NonDeleted, NonDeletedExcalidrawElement, Theme } from "@zsviczian/excalidraw/types/element/types"; -import { AppState, BinaryFiles, ExportOpts, Point, Zoom } from "@zsviczian/excalidraw/types/types"; -import { Mutable } from "@zsviczian/excalidraw/types/utility-types"; +import { RestoredDataState } from "@zsviczian/excalidraw/types/excalidraw/data/restore"; +import { ImportedDataState } from "@zsviczian/excalidraw/types/excalidraw/data/types"; +import { BoundingBox } from "@zsviczian/excalidraw/types/excalidraw/element/bounds"; +import { ExcalidrawBindableElement, ExcalidrawElement, ExcalidrawFrameElement, ExcalidrawTextElement, FontFamilyValues, FontString, NonDeleted, NonDeletedExcalidrawElement, Theme } from "@zsviczian/excalidraw/types/excalidraw/element/types"; +import { AppState, BinaryFiles, ExportOpts, Point, Zoom } from "@zsviczian/excalidraw/types/excalidraw/types"; +import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; type EmbeddedLink = | ({ @@ -132,7 +132,8 @@ declare namespace ExcalidrawLib { opts: {fontSize: number}, forceSVG?: boolean, ): Promise<{ - elements: ExcalidrawElement[], - files:any + elements?: ExcalidrawElement[]; + files?: any; + error?: string; } | undefined>; } \ No newline at end of file diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index 6e8c290..9fa4850 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -20,7 +20,7 @@ import { ExcalidrawTextElement, FileId, NonDeletedExcalidrawElement, -} from "@zsviczian/excalidraw/types/element/types"; +} from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { AppState, BinaryFileData, @@ -28,7 +28,7 @@ import { Gesture, LibraryItems, UIAppState, -} from "@zsviczian/excalidraw/types/types"; +} from "@zsviczian/excalidraw/types/excalidraw/types"; import { VIEW_TYPE_EXCALIDRAW, ICON_NAME, @@ -67,6 +67,7 @@ import { REG_LINKINDEX_HYPERLINK, REGEX_LINK, AutoexportPreference, + getExcalidrawMarkdownHeaderSection, } from "./ExcalidrawData"; import { checkAndCreateFolder, @@ -104,7 +105,7 @@ import { import { getLeaf, getParentOfClass, obsidianPDFQuoteWithRef } from "./utils/ObsidianUtils"; import { splitFolderAndFilename } from "./utils/FileUtils"; import { ConfirmationPrompt, GenericInputPrompt, NewFileActions, Prompt } from "./dialogs/Prompt"; -import { ClipboardData } from "@zsviczian/excalidraw/types/clipboard"; +import { ClipboardData } from "@zsviczian/excalidraw/types/excalidraw/clipboard"; import { updateEquation } from "./LaTeX"; import { EmbeddedFile, @@ -724,14 +725,6 @@ export default class ExcalidrawView extends TextFileView { //deleted elements are only used if sync modifies files while Excalidraw is open //otherwise deleted elements are discarded when loading the scene if (!this.compatibilityMode) { - let trimLocation = this.data.search(/(^%%\n)?# Text Elements\n/m); - if (trimLocation == -1) { - trimLocation = this.data.search(/(%%\n)?# Drawing\n/); - } - if (trimLocation == -1) { - return this.data; - } - const keys:[string,string][] = this.exportDialog?.dirty && this.exportDialog?.saveSettings ? [ [FRONTMATTER_KEY_EXPORT_PADDING, this.exportDialog.padding.toString()], @@ -748,13 +741,8 @@ export default class ExcalidrawView extends TextFileView { this.exportDialog.dirty = false; } - let header = updateFrontmatterInString(this.data.substring(0, trimLocation),keys); - //this should be removed at a later time. Left it here to remediate 1.4.9 mistake - const REG_IMG = /(^---[\w\W]*?---\n)(!\[\[.*?]]\n(%%\n)?)/m; //(%%\n)? because of 1.4.8-beta... to be backward compatible with anyone who installed that version - if (header.match(REG_IMG)) { - header = header.replace(REG_IMG, "$1"); - } - //end of remove + const header = getExcalidrawMarkdownHeaderSection(this.data, keys); + if (!this.excalidrawData.disableCompression) { this.excalidrawData.disableCompression = this.isEditedAsMarkdownInOtherView(); diff --git a/src/LaTeX.ts b/src/LaTeX.ts index 10d0c2c..780fa40 100644 --- a/src/LaTeX.ts +++ b/src/LaTeX.ts @@ -1,4 +1,4 @@ -import { DataURL } from "@zsviczian/excalidraw/types/types"; +import { DataURL } from "@zsviczian/excalidraw/types/excalidraw/types"; import {mathjax} from "mathjax-full/js/mathjax"; import {TeX} from 'mathjax-full/js/input/tex.js'; import {SVG} from 'mathjax-full/js/output/svg.js'; @@ -9,7 +9,7 @@ import {AllPackages} from 'mathjax-full/js/input/tex/AllPackages.js'; import ExcalidrawView from "./ExcalidrawView"; import ExcalidrawPlugin from "./main"; import { FileData, MimeType } from "./EmbeddedFileLoader"; -import { FileId } from "@zsviczian/excalidraw/types/element/types"; +import { FileId } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { getImageSize, svgToBase64 } from "./utils/Utils"; import { fileid } from "./constants/constants"; import { TFile } from "obsidian"; diff --git a/src/Scripts.ts b/src/Scripts.ts index 644d0ba..177b63f 100644 --- a/src/Scripts.ts +++ b/src/Scripts.ts @@ -263,7 +263,7 @@ export class ScriptEngine { new Notice(t("SCRIPT_EXECUTION_ERROR"), 4000); errorlog({ script: this.plugin.ea.activeScript, error: e }); }*/ - ea.activeScript = null; + //ea.activeScript = null; return result; } diff --git a/src/customEmbeddable.tsx b/src/customEmbeddable.tsx index af5e800..136e983 100644 --- a/src/customEmbeddable.tsx +++ b/src/customEmbeddable.tsx @@ -1,10 +1,10 @@ -import { NonDeletedExcalidrawElement } from "@zsviczian/excalidraw/types/element/types"; +import { NonDeletedExcalidrawElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import ExcalidrawView from "./ExcalidrawView"; import { Notice, WorkspaceLeaf, WorkspaceSplit } from "obsidian"; import * as React from "react"; import { ConstructableWorkspaceSplit, getContainerForDocument, isObsidianThemeDark } from "./utils/ObsidianUtils"; import { DEVICE, EXTENDED_EVENT_TYPES, KEYBOARD_EVENT_TYPES } from "./constants/constants"; -import { ExcalidrawImperativeAPI, UIAppState } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI, UIAppState } from "@zsviczian/excalidraw/types/excalidraw/types"; import { ObsidianCanvasNode } from "./utils/CanvasNodeFactory"; import { processLinkText, patchMobileView } from "./utils/CustomEmbeddableUtils"; import { EmbeddableMDCustomProps } from "./dialogs/EmbeddableSettings"; diff --git a/src/dialogs/EmbeddableSettings.ts b/src/dialogs/EmbeddableSettings.ts index 96651ef..c16f108 100644 --- a/src/dialogs/EmbeddableSettings.ts +++ b/src/dialogs/EmbeddableSettings.ts @@ -1,5 +1,5 @@ -import { ExcalidrawEmbeddableElement } from "@zsviczian/excalidraw/types/element/types"; -import { Mutable } from "@zsviczian/excalidraw/types/utility-types"; +import { ExcalidrawEmbeddableElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; +import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import { Modal, Notice, Setting, TFile, ToggleComponent } from "obsidian"; import { getEA } from "src"; import { ExcalidrawAutomate } from "src/ExcalidrawAutomate"; @@ -11,7 +11,7 @@ import { addAppendUpdateCustomData, fragWithHTML } from "src/utils/Utils"; import { getYouTubeStartAt, isValidYouTubeStart, isYouTube, updateYouTubeStartTime } from "src/utils/YoutTubeUtils"; import { EmbeddalbeMDFileCustomDataSettingsComponent } from "./EmbeddableMDFileCustomDataSettingsComponent"; import { isWinCTRLorMacCMD } from "src/utils/ModifierkeyHelper"; -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; export type EmbeddableMDCustomProps = { useObsidianDefaults: boolean; diff --git a/src/dialogs/ExportDialog.ts b/src/dialogs/ExportDialog.ts index fb98137..8db1261 100644 --- a/src/dialogs/ExportDialog.ts +++ b/src/dialogs/ExportDialog.ts @@ -1,4 +1,4 @@ -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { Modal, Setting, TFile } from "obsidian"; import { getEA } from "src"; import { DEVICE } from "src/constants/constants"; diff --git a/src/dialogs/InsertPDFModal.ts b/src/dialogs/InsertPDFModal.ts index 146cb76..bfba1d0 100644 --- a/src/dialogs/InsertPDFModal.ts +++ b/src/dialogs/InsertPDFModal.ts @@ -6,7 +6,7 @@ import { Modal, Setting, TextComponent } from "obsidian"; import { FileSuggestionModal } from "./FolderSuggester"; import { getEA } from "src"; import { ExcalidrawAutomate } from "src/ExcalidrawAutomate"; -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; export class InsertPDFModal extends Modal { private borderBox: boolean = true; diff --git a/src/dialogs/Messages.ts b/src/dialogs/Messages.ts index 27e9308..b47091d 100644 --- a/src/dialogs/Messages.ts +++ b/src/dialogs/Messages.ts @@ -17,6 +17,28 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
`, +"2.0.11":` +## Fixed +- Resolved an Obsidian performance issue caused by simultaneous installations of Excalidraw and the Minimal theme. Optimized Excalidraw CSS loading into Obsidian since April 2021, resulting in noticeable performance improvements. ([#1456](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1456)) +- Removed default support for the [Sliding Panes Plugin](https://github.com/deathau/sliding-panes-obsidian) due to compatibility issues with Obsidian Workspaces. Obsidian's "Stack Tabs" feature now supersedes Sliding Panes. To re-enable sliding panes support, navigate to Compatibility Features in Plugin Settings. +- Sometimes images referenced with URLs did not show in exported scenes and when embedding Excalidraw into a markdown note. I hope all that is now resolved. +- ExcalidrawAutomate scripts sometimes were not able to save their settings. + +## New +- Introduced an "Easter Egg" feature in font-size properties: + - Hold SHIFT while selecting font size to use scaled sizes (S, M, L, XL) based on the current canvas zoom, ensuring consistent sizes within zoom ranges. + - Hold ALT/OPT while selecting font size to use values based on the golden mean (s:16, m:26, l:42, xl:68). ALT+SHIFT scales font sizes based on canvas zoom. + - Scaled sizes are sticky; new text elements adjust font sizes relative to the canvas zoom. Deselect SHIFT to disable this feature. + - For more on the Golden Scale, watch [The Golden Opportunity](https://youtu.be/2SHn_ruax-s). +- Added two new Command Palette Actions: + - "Decompress current Excalidraw File" in Markdown View mode helps repair corrupted, compressed Excalidraw files manually. + - "Save image from URL to local file" saves referenced URL images to your Vault, replacing images in the drawing. +- Updated the ExcaliAI script to generate images using ExcaliAI. + +## New in ExcalidrawAutomate +- Added additional documentation about functions to ea.suggester. +- Added ea.help(). You can use this function from Developer Console to print help information about functions. Usage: ${String.fromCharCode(96)}ea.help(ea.functionName)${String.fromCharCode(96)} or ${String.fromCharCode(96)}ea.help('propertyName')${String.fromCharCode(96)} - notice property name is in quotes. +`, "2.0.10":` One more minor tweak to support an updated ExcaliAI script - now available in the script store. `, diff --git a/src/dialogs/PenSettingsModal.ts b/src/dialogs/PenSettingsModal.ts index 69f6548..92ef463 100644 --- a/src/dialogs/PenSettingsModal.ts +++ b/src/dialogs/PenSettingsModal.ts @@ -1,4 +1,4 @@ -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { ColorComponent, Modal, Setting, SliderComponent, TextComponent, ToggleComponent } from "obsidian"; import { COLOR_NAMES, VIEW_TYPE_EXCALIDRAW } from "src/constants/constants"; import ExcalidrawView from "src/ExcalidrawView"; diff --git a/src/dialogs/SuggesterInfo.ts b/src/dialogs/SuggesterInfo.ts index 1bae066..c1dbd0c 100644 --- a/src/dialogs/SuggesterInfo.ts +++ b/src/dialogs/SuggesterInfo.ts @@ -5,7 +5,17 @@ type SuggesterInfo = { after: string; }; +const hyperlink = (url: string, text: string) => { + return `${text}`; +} + export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ + { + field: "help", + code: "help(target: Function | string)", + desc: "Utility function that provides help about ExcalidrawAutomate functions and properties. I recommend calling this function from Developer Console to print out help to the console.", + after: "", + }, { field: "plugin", code: null, @@ -27,13 +37,13 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ { field: "style.strokeColor", code: "[string]", - desc: "A valid css color. See W3 School Colors for more.", + desc: `A valid css color. See ${hyperlink("https://www.w3schools.com/colors/default.asp", "W3 School Colors")} for more.`, after: "", }, { field: "style.backgroundColor", code: "[string]", - desc: "A valid css color. See W3 School Colors for more.", + desc: `A valid css color. See ${hyperlink("https://www.w3schools.com/colors/default.asp","W3 School Colors")} for more.`, after: "", }, { @@ -123,7 +133,7 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ { field: "canvas.viewBackgroundColor", code: "[string]", - desc: "A valid css color.\nSee W3 School Colors for more.", + desc: `A valid css color.\nSee ${hyperlink("https://www.w3schools.com/colors/default.asp","W3 School Colors")} for more.`, after: "", }, { @@ -170,25 +180,25 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ }, { field: "create", - code: 'create(params?: {filename?: string, foldername?: string, templatePath?: string, onNewPane?: boolean, silent?: boolean, frontmatterKeys?: { "excalidraw-plugin"?: "raw" | "parsed", "excalidraw-link-prefix"?: string, "excalidraw-link-brackets"?: boolean, "excalidraw-url-prefix"?: string,},}): Promise;', + code: 'async create(params?: {filename?: string, foldername?: string, templatePath?: string, onNewPane?: boolean, silent?: boolean, frontmatterKeys?: { "excalidraw-plugin"?: "raw" | "parsed", "excalidraw-link-prefix"?: string, "excalidraw-link-brackets"?: boolean, "excalidraw-url-prefix"?: string,},}): Promise;', desc: "Create a drawing and save it to filename.\nIf filename is null: default filename as defined in Excalidraw settings.\nIf folder is null: default folder as defined in Excalidraw settings\nReturns the path to the created file", after: "", }, { field: "createSVG", - code: "createSVG(templatePath?: string, embedFont?: boolean, exportSettings?: ExportSettings, loader?: EmbeddedFilesLoader, theme?: string,): Promise;", + code: "async createSVG(templatePath?: string, embedFont?: boolean, exportSettings?: ExportSettings, loader?: EmbeddedFilesLoader, theme?: string,): Promise;", desc: "Use ExcalidrawAutomate.getExportSettings(boolean,boolean) to create an ExportSettings object.\nUse ExcalidrawAutomate.getEmbeddedFilesLoader(boolean?) to create an EmbeddedFilesLoader object.", after: "", }, { field: "createPNG", - code: "createPNG(templatePath?: string, scale?: number, exportSettings?: ExportSettings, loader?: EmbeddedFilesLoader, theme?: string,padding?: number): Promise;", + code: "async createPNG(templatePath?: string, scale?: number, exportSettings?: ExportSettings, loader?: EmbeddedFilesLoader, theme?: string,padding?: number): Promise;", desc: "Create an image based on the objects in ea.getElements(). The elements in ea will be merged with the elements from the provided template file - if any. Use ExcalidrawAutomate.getExportSettings(boolean,boolean) to create an ExportSettings object.\nUse ExcalidrawAutomate.getEmbeddedFilesLoader(boolean?) to create an EmbeddedFilesLoader object.", after: "", }, { field: "createPNGBase64", - code: "craetePNGBase64(templatePath?: string, scale?: number, exportSettings?: ExportSettings, loader?: EmbeddedFilesLoader, theme?: string,padding?: number): Promise;", + code: "async craetePNGBase64(templatePath?: string, scale?: number, exportSettings?: ExportSettings, loader?: EmbeddedFilesLoader, theme?: string,padding?: number): Promise;", desc: "The same as createPNG but returns a base64 encoded string instead of a file.", after: "", }, @@ -248,7 +258,7 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ }, { field: "addImage", - code: "addImage(topX: number, topY: number, imageFile: TFile, scale?: boolean, anchor?: boolean): Promise;", + code: "async addImage(topX: number, topY: number, imageFile: TFile, scale?: boolean, anchor?: boolean): Promise;", desc: "set scale to false if you want to embed the image at 100% of its original size. Default is true which will insert a scaled image. anchor will only be evaluated if scale is false. anchor true will add |100% to the end of the filename, resulting in an image that will always pop back to 100% when the source file is updated or when the Excalidraw file is reopened. ", after: "", }, @@ -260,8 +270,11 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ }, { field: "addMermaid", - code: "async addMermaid(diagram: string, groupElements: boolean = true,): Promise;", - desc: "Creates a mermaid diagram and returns the ids of the created elements as a string[]. The elements will be added to ea. To add them to the canvas you'll need to use addElementsToView. Depending on the diagram type the result will be either a single SVG image, or a number of excalidraw elements.", + code: "async addMermaid(diagram: string, groupElements: boolean = true,): Promise;", + desc: "Creates a mermaid diagram and returns the ids of the created elements as a string[]. " + + "The elements will be added to ea. To add them to the canvas you'll need to use addElementsToView. " + + "Depending on the diagram type the result will be either a single SVG image, or a number of excalidraw elements.
" + + "If there is an error, the function returns a string with the error message.", after: "", }, { @@ -315,7 +328,7 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ { field: "getExcalidrawAPI", code: "getExcalidrawAPI(): any;", - desc: "Excalidraw API", + desc: `${hyperlink("https://github.com/excalidraw/excalidraw/tree/master/src/packages/excalidraw#ref","Excalidraw API")}`, after: "", }, { @@ -368,7 +381,7 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ }, { field: "addElementsToView", - code: "addElementsToView(repositionToCursor?: boolean, save?: boolean, newElementsOnTop?: boolean,shouldRestoreElements?: boolean,): Promise;", + code: "async addElementsToView(repositionToCursor?: boolean, save?: boolean, newElementsOnTop?: boolean,shouldRestoreElements?: boolean,): Promise;", desc: "Adds elements from elementsDict to the current view\nrepositionToCursor: default is false\nsave: default is true\nnewElementsOnTop: default is false, i.e. the new elements get to the bottom of the stack\nnewElementsOnTop controls whether elements created with ExcalidrawAutomate are added at the bottom of the stack or the top of the stack of elements already in the view\nNote that elements copied to the view with copyViewElementsToEAforEditing retain their position in the stack of elements in the view even if modified using EA", after: "", }, @@ -435,19 +448,19 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ { field: "activeScript", code: "activeScript: string;", - desc: "Mandatory to set before calling the get and set ScriptSettings functions. Set automatically by the ScriptEngine\nSee for more details: Script Engine Help", + desc: `Mandatory to set before calling the get and set ScriptSettings functions. Set automatically by the ScriptEngine\nSee for more details: ${hyperlink("https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html","Script Engine Help")}`, after: "", }, { field: "getScriptSettings", code: "getScriptSettings(): {};", - desc: "Returns script settings. Saves settings in plugin settings, under the activeScript key. See for more details: Script Engine Help", + desc: `Returns script settings. Saves settings in plugin settings, under the activeScript key. See for more details: ${hyperlink("https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html","Script Engine Help")}`, after: "", }, { field: "setScriptSettings", - code: "setScriptSettings(settings: any): Promise;", - desc: "Sets script settings.\nSee for more details: Script Engine Help", + code: "async setScriptSettings(settings: any): Promise;", + desc: `Sets script settings.\nSee for more details: ${hyperlink("https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html","Script Engine Help")}`, after: "", }, { @@ -525,13 +538,68 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ { field: "obsidian", code: "obsidian", - desc: "Access functions and objects available on the Obsidian Module", + desc: `Access functions and objects available on the ${hyperlink("https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts","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.", + 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." + + "Prompts the user with a dialog to select new file action.
" + + " - create markdown file
" + + " - create excalidraw file
" + + " - cancel action
" + + "The new file will be relative to this.targetView.file.path, unless parentFile is provided. " + + "If shouldOpenNewFile is true, the new file will be opened in a workspace leaf. " + + "targetPane controls which leaf will be used for the new file.
" + + "Returns the TFile for the new file or null if the user cancelled the action.
" + + 'type PaneTarget = "active-pane"|"new-pane"|"popout-window"|"new-tab"|"md-properties";', + after: "", + }, + { + field: "getActiveEmbeddableViewOrEditor", + code: "getActiveEmbeddableViewOrEditor(view?: ExcalidrawView);", + desc: "Returns the editor or leaf.view of the currently active embedded obsidian file.
" + + "If view is not provided, ea.targetView is used.
" + + "If the embedded file is a markdown document the function will return
" + + "{file:TFile, editor:Editor} otherwise it will return {view:any}. You can check view type with view.getViewType();", + after: "", + }, + { + field: "getViewLastPointerPosition", + code: "getViewLastPointerPosition(): {x: number, y: number};", + desc: "@returns the last recorded pointer position on the Excalidraw canvas", + after: "", + }, + { + field: "getleaf", + code: "getLeaf(origo: WorkspaceLeaf, targetPane?: PaneTarget): WorkspaceLeaf;", + desc: "Generates a new Obsidian Leaf following Excalidraw plugin settings such as open in Main Workspace or not, open in adjacent pane if avaialble, etc.
" + + "@param origo: the currently active leaf, the origin of the new leaf
" + + '@param targetPane: type PaneTarget = "active-pane"|"new-pane"|"popout-window"|"new-tab"|"md-properties";', + after: "", + }, + { + field: "newFilePrompt", + code: "async newFilePrompt(newFileNameOrPath: string, shouldOpenNewFile: boolean, targetPane?: PaneTarget, parentFile?: TFile): Promise;", + desc: "", + after: "", + }, + { + field: "DEVICE", + code: "get DEVICE(): DeviceType;", + desc: "Returns the current device type. Possible values are:
" + + "type DeviceType = {
" + + " isDesktop: boolean,
" + + " isPhone: boolean,
" + + " isTablet: boolean,
" + + " isMobile: boolean,
" + + " isLinux: boolean,
" + + " isMacOS: boolean,
" + + " isWindows: boolean,
" + + " isIOS: boolean,
" + + " isAndroid: boolean
" + + "};", after: "", }, { @@ -557,12 +625,14 @@ export const EXCALIDRAW_AUTOMATE_INFO: SuggesterInfo[] = [ code: "async postOpenAI(requst: AIRequest): Promise", desc: "This asynchronous function should be awaited. It posts the supplied request to the OpenAI API and returns the response.
" + - "The response is a dictionary with the following keys:
{image, text, instruction, systemPrompt}
"+ + "The response is a dictionary with the following keys:
{image, text, instruction, systemPrompt, responseType}
"+ "image should be a dataURL - use ea.createPNGBase64()
"+ "systemPrompt: if undefined the message to OpenAI will not include a system prompt
"+ "text is the actual user prompt, a request must have either an image or a text
"+ "instruction is a user prompt sent as a separate element in the message - I use it to reinforce the type of response I am seeing (e.g. mermaid in a codeblock)
"+ - "RequestUrlResponse is defined in the Obsidian API", + `imageGenerationProperties if provided then the dall-e model will be used. imageGenerationProperties?: {size?: string, quality?: "standard" | "hd"; n?: number; mask?: string; }
` + + "Different openAI models accept different parameters fr size, quality, n and mask. Consult the API documenation for more information.
" + + `RequestUrlResponse is defined in the ${hyperlink("https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts","Obsidian API")}`, after: "", }, { diff --git a/src/dialogs/UniversalInsertFileModal.ts b/src/dialogs/UniversalInsertFileModal.ts index ccd4abc..b6af228 100644 --- a/src/dialogs/UniversalInsertFileModal.ts +++ b/src/dialogs/UniversalInsertFileModal.ts @@ -7,7 +7,7 @@ import { IMAGE_TYPES, sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, import { insertEmbeddableToView, insertImageToView } from "src/utils/ExcalidrawViewUtils"; import { getEA } from "src"; import { InsertPDFModal } from "./InsertPDFModal"; -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { ExcalidrawAutomate } from "src/ExcalidrawAutomate"; import { cleanSectionHeading } from "src/utils/ObsidianUtils"; diff --git a/src/index.ts b/src/index.ts index e541e09..acd3f56 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,8 +2,8 @@ import "obsidian"; //import { ExcalidrawAutomate } from "./ExcalidrawAutomate"; //export ExcalidrawAutomate from "./ExcalidrawAutomate"; //export {ExcalidrawAutomate} from "./ExcaildrawAutomate"; -export type { ExcalidrawBindableElement, ExcalidrawElement, FileId, FillStyle, StrokeRoundness, StrokeStyle } from "@zsviczian/excalidraw/types/element/types"; -export type { Point } from "@zsviczian/excalidraw/types/types"; +export type { ExcalidrawBindableElement, ExcalidrawElement, FileId, FillStyle, StrokeRoundness, StrokeStyle } from "@zsviczian/excalidraw/types/excalidraw/element/types"; +export type { Point } from "@zsviczian/excalidraw/types/excalidraw/types"; export const getEA = (view?:any): any => { try { return window.ExcalidrawAutomate.getAPI(view); diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index aaa0f29..f1e2a17 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -9,6 +9,8 @@ import { labelALT, labelCTRL, labelMETA, labelSHIFT } from "src/utils/Modifierke // English export default { // main.ts + CONVERT_URL_TO_FILE: "Save image from URL to local file", + UNZIP_CURRENT_FILE: "Decompress current Excalidraw file", PUBLISH_SVG_CHECK: "Obsidian Publish: Find SVG and PNG exports that are out of date", EMBEDDABLE_PROPERTIES: "Embeddable Properties", EMBEDDABLE_RELATIVE_ZOOM: "Scale selected embeddable elements to 100% relative to the current canvas zoom", @@ -153,7 +155,14 @@ export default { AI_OPENAI_DEFAULT_MODEL_DESC: "The default AI model to use when generating text. This is a freetext field, so you can enter any valid OpenAI model name. " + "Find out more about the available models on the OpenAI website.", - AI_OPENAI_DEFAULT_MODEL_PLACEHOLDER: "Enter your default AI model here", + AI_OPENAI_DEFAULT_MODEL_PLACEHOLDER: "Enter your default AI model here. e.g.: gpt-3.5-turbo-1106", + AI_OPENAI_DEFAULT_IMAGE_MODEL_NAME: "Default Image Generation AI model", + AI_OPENAI_DEFAULT_IMAGE_MODEL_DESC: + "The default AI model to use when generating images. Image editing and variations are only supported by dall-e-2 at this time by OpenAI, " + + "for this reason dall-e-2 will automatically be used in such cases regardless of this setting.
" + + "This is a freetext field, so you can enter any valid OpenAI model name. " + + "Find out more about the available models on the OpenAI website.", + AI_OPENAI_DEFAULT_IMAGE_MODEL_PLACEHOLDER: "Enter your default Image Generation AI model here e.g.: dall-e-3", AI_OPENAI_DEFAULT_VISION_MODEL_NAME: "Default AI vision model", AI_OPENAI_DEFAULT_VISION_MODEL_DESC: "The default AI vision model to use when generating text from images. This is a freetext field, so you can enter any valid OpenAI model name. " + @@ -162,7 +171,8 @@ export default { AI_OPENAI_DEFAULT_API_URL_DESC: "The default OpenAI API URL. This is a freetext field, so you can enter any valid OpenAI API compatible URL. " + "Excalidraw will use this URL when posting API requests to OpenAI. I am not doing any error handling on this field, so make sure you enter a valid URL and only change this if you know what you are doing. ", - AI_OPENAI_DEFAULT_VISION_MODEL_PLACEHOLDER: "Enter your default AI vision model here", + AI_OPENAI_DEFAULT_IMAGE_API_URL_NAME: "OpenAI Image Generation API URL", + AI_OPENAI_DEFAULT_VISION_MODEL_PLACEHOLDER: "Enter your default AI vision model here. e.g.: gpt-4-vision-preview", SAVING_HEAD: "Saving", SAVING_DESC: "In the 'Saving' section of Excalidraw Settings, you can configure how your drawings are saved. This includes options for compressing Excalidraw JSON in Markdown, setting autosave intervals for both desktop and mobile, defining filename formats, and choosing whether to use the .excalidraw.md or .md file extension. ", COMPRESS_NAME: "Compress Excalidraw JSON in Markdown", @@ -488,6 +498,13 @@ FILENAME_HEAD: "Filename", "Double files will be exported both if auto-export SVG or PNG (or both) are enabled, as well as when clicking export on a single image.", COMPATIBILITY_HEAD: "Compatibility features", COMPATIBILITY_DESC: "You should only enable these features if you have a strong reason for wanting to work with excalidraw.com files instead of markdown files. Many of the plugin features are not supported on legacy files. Typical usecase would be if you use set your vault up on top of a Visual Studio Code project folder and you have .excalidraw drawings you want to access from Visual Studio Code as well. Another usecase might be using Excalidraw in Logseq and Obsidian in parallel.", + SLIDING_PANES_NAME: "Sliding panes plugin support", + SLIDING_PANES_DESC: + "Need to restart Obsidian for this change to take effect.
" + + "If you use the Sliding Panes plugin " + + "you can enable this setting to make Excalidraw drawings work with the Sliding Panes plugin.
" + + "Note, that Excalidraw Sliding Panes support causes compatibility issues with Obsidian Workspaces.
" + + "Note also, that the 'Stack Tabs' feature is now available in Obsidian, providing native support for most of the Sliding Panes functionality.", EXPORT_EXCALIDRAW_NAME: "Auto-export Excalidraw", EXPORT_EXCALIDRAW_DESC: "Same as the auto-export SVG, but for *.Excalidraw", SYNC_EXCALIDRAW_NAME: diff --git a/src/main.ts b/src/main.ts index a1524f2..f2bda16 100644 --- a/src/main.ts +++ b/src/main.ts @@ -40,6 +40,7 @@ import { EXPORT_IMG_ICON_NAME, EXPORT_IMG_ICON, LOCALE, + fileid, } from "./constants/constants"; import { VIRGIL_FONT, @@ -53,7 +54,8 @@ import { changeThemeOfExcalidrawMD, getMarkdownDrawingSection, ExcalidrawData, - REGEX_LINK + REGEX_LINK, + getExcalidrawMarkdownHeaderSection } from "./ExcalidrawData"; import { ExcalidrawSettings, @@ -94,9 +96,10 @@ import { isVersionNewerThanOther, getExportTheme, isCallerFromTemplaterPlugin, + decompress, } from "./utils/Utils"; import { extractSVGPNGFileName, getAttachmentsFolderAndFilePath, getNewOrAdjacentLeaf, getParentOfClass, isObsidianThemeDark } from "./utils/ObsidianUtils"; -import { ExcalidrawElement, ExcalidrawEmbeddableElement, ExcalidrawImageElement, ExcalidrawTextElement, FileId } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawElement, ExcalidrawEmbeddableElement, ExcalidrawImageElement, ExcalidrawTextElement, FileId } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { ScriptEngine } from "./Scripts"; import { hoverEvent, @@ -121,10 +124,10 @@ import { PublishOutOfDateFilesDialog } from "./dialogs/PublishOutOfDateFiles"; import { EmbeddableSettings } from "./dialogs/EmbeddableSettings"; import { processLinkText } from "./utils/CustomEmbeddableUtils"; import { getEA } from "src"; -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; -import { Mutable } from "@zsviczian/excalidraw/types/utility-types"; +import { BinaryFileData, DataURL, ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; +import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import { CustomMutationObserver, durationTreshold, isDebugMode } from "./utils/DebugHelper"; -import { create } from "domain"; +import de from "./lang/locale/de"; declare const EXCALIDRAW_PACKAGES:string; declare const react:any; @@ -792,6 +795,86 @@ export default class ExcalidrawPlugin extends Plugin { ), ); + this.addCommand({ + id: "excalidraw-convert-image-from-url-to-local-file", + name: t("CONVERT_URL_TO_FILE"), + checkCallback: (checking: boolean) => { + const view = this.app.workspace.getActiveViewOfType(ExcalidrawView); + if(!view) return false; + if(!view.excalidrawAPI) return false; + const els = view.getViewSelectedElements().filter(el=>el.type==="image"); + if(els.length !== 1) { + if(checking) return false; + new Notice("Select a single image element and try again"); + return false; + } + const el = els[0] as ExcalidrawImageElement; + const imageFile = view.excalidrawData.getFile(el.fileId); + if(!imageFile.isHyperLink) return false; + if(checking) return true; + const imageDataURL = imageFile.getImage(false); + if(!imageDataURL) { + new Notice("Image not found"); + return false; + } + const ea = getEA(view) as ExcalidrawAutomate; + ea.copyViewElementsToEAforEditing([el]); + const eaEl = ea.getElement(el.id) as Mutable; + eaEl.fileId = fileid() as FileId; + if(!eaEl.link) {eaEl.link = imageFile.hyperlink}; + const files: BinaryFileData[] = []; + files.push({ + mimeType: imageFile.mimeType, + id: eaEl.fileId, + dataURL: imageFile.getImage(false) as DataURL, + created: imageFile.mtime, + }); + const api = view.excalidrawAPI as ExcalidrawImperativeAPI; + api.addFiles(files); + ea.addElementsToView(false,true); + }, + }); + + this.addCommand({ + id: "excalidraw-unzip-file", + name: t("UNZIP_CURRENT_FILE"), + checkCallback: (checking: boolean) => { + const activeFile = this.app.workspace.getActiveFile(); + if (!activeFile) { + return false; + } + const fileIsExcalidraw = this.isExcalidrawFile(activeFile); + if (!fileIsExcalidraw) { + return false; + } + + const excalidrawView = this.app.workspace.getActiveViewOfType(ExcalidrawView); + if (excalidrawView) { + return false; + } + + if (checking) { + return true; + } + + (async () => { + const data = await this.app.vault.read(activeFile); + const parts = data.split("%%\n# Drawing\n```compressed-json\n"); + if(parts.length!==2) return; + const header = parts[0] + "%%\n# Drawing\n```json\n"; + const compressed = parts[1].split("\n```\n%%"); + if(compressed.length!==2) return; + const decompressed = decompress(compressed[0]); + if(!decompressed) { + new Notice("The compressed string is corrupted. Unable to decompress data."); + return; + } + await this.app.vault.modify(activeFile,header + decompressed + "\n```\n%%"); + })(); + + } + }) + this.addCommand({ id: "excalidraw-publish-svg-check", name: t("PUBLISH_SVG_CHECK"), diff --git a/src/menu/EmbeddableActionsMenu.tsx b/src/menu/EmbeddableActionsMenu.tsx index c694884..8e00ae3 100644 --- a/src/menu/EmbeddableActionsMenu.tsx +++ b/src/menu/EmbeddableActionsMenu.tsx @@ -1,8 +1,8 @@ import { TFile } from "obsidian"; import * as React from "react"; import ExcalidrawView from "../ExcalidrawView"; -import { ExcalidrawElement, ExcalidrawEmbeddableElement } from "@zsviczian/excalidraw/types/element/types"; -import { AppState, ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawElement, ExcalidrawEmbeddableElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; +import { AppState, ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { ActionButton } from "./ActionButton"; import { ICONS } from "./ActionIcons"; import { t } from "src/lang/helpers"; diff --git a/src/menu/ObsidianMenu.tsx b/src/menu/ObsidianMenu.tsx index da013f2..d307e82 100644 --- a/src/menu/ObsidianMenu.tsx +++ b/src/menu/ObsidianMenu.tsx @@ -1,4 +1,4 @@ -import { AppState, ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { AppState, ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import clsx from "clsx"; import { TFile } from "obsidian"; import * as React from "react"; diff --git a/src/menu/ToolsPanel.tsx b/src/menu/ToolsPanel.tsx index a331382..f4ff38e 100644 --- a/src/menu/ToolsPanel.tsx +++ b/src/menu/ToolsPanel.tsx @@ -10,7 +10,7 @@ import { t } from "../lang/helpers"; import { ReleaseNotes } from "../dialogs/ReleaseNotes"; import { ScriptIconMap } from "../Scripts"; import { ScriptInstallPrompt } from "src/dialogs/ScriptInstallPrompt"; -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { isWinALTorMacOPT, isWinCTRLorMacCMD, isSHIFT } from "src/utils/ModifierkeyHelper"; import { InsertPDFModal } from "src/dialogs/InsertPDFModal"; import { ExportDialog } from "src/dialogs/ExportDialog"; diff --git a/src/ocr/Taskbone.ts b/src/ocr/Taskbone.ts index eb6db56..ccecac4 100644 --- a/src/ocr/Taskbone.ts +++ b/src/ocr/Taskbone.ts @@ -4,7 +4,7 @@ import ExcalidrawPlugin from "../main" import {log} from "../utils/Utils" import ExcalidrawView, { ExportSettings } from "../ExcalidrawView" import FrontmatterEditor from "src/utils/Frontmatter"; -import { ExcalidrawElement, ExcalidrawImageElement } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawElement, ExcalidrawImageElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { EmbeddedFilesLoader } from "src/EmbeddedFileLoader"; import { blobToBase64 } from "src/utils/FileUtils"; diff --git a/src/settings.ts b/src/settings.ts index 502b029..3a83fe7 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -160,7 +160,11 @@ export interface ExcalidrawSettings { openAIAPIToken: string, openAIDefaultTextModel: string, openAIDefaultVisionModel: string, + openAIDefaultImageGenerationModel: string, openAIURL: string, + openAIImageGenerationURL: string, + openAIImageEditsURL: string, + openAIImageVariationURL: string, modifierKeyConfig: { Mac: Record, Win: Record, @@ -312,7 +316,11 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = { openAIAPIToken: "", openAIDefaultTextModel: "gpt-3.5-turbo-1106", openAIDefaultVisionModel: "gpt-4-vision-preview", + openAIDefaultImageGenerationModel: "dall-e-3", openAIURL: "https://api.openai.com/v1/chat/completions", + openAIImageGenerationURL: "https://api.openai.com/v1/images/generations", + openAIImageEditsURL: "https://api.openai.com/v1/images/edits", + openAIImageVariationURL: "https://api.openai.com/v1/images/variations", modifierKeyConfig: { Mac: { LocalFileDragAction:{ @@ -522,7 +530,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab { .setDesc(fragWithHTML(t("FOLDER_DESC"))) .addText((text) => text - .setPlaceholder("Excalidraw") + .setPlaceholder("e.g.: Excalidraw") .setValue(this.plugin.settings.folder) .onChange(async (value) => { this.plugin.settings.folder = value; @@ -547,7 +555,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab { .setDesc(fragWithHTML(t("TEMPLATE_DESC"))) .addText((text) => text - .setPlaceholder("Excalidraw/Template") + .setPlaceholder("e.g.: Excalidraw/Template") .setValue(this.plugin.settings.templateFilePath) .onChange(async (value) => { this.plugin.settings.templateFilePath = value; @@ -561,7 +569,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab { .setDesc(fragWithHTML(t("SCRIPT_FOLDER_DESC"))) .addText((text) => text - .setPlaceholder("Excalidraw/Scripts") + .setPlaceholder("e.g.: Excalidraw/Scripts") .setValue(this.plugin.settings.scriptFolderPath) .onChange(async (value) => { this.plugin.settings.scriptFolderPath = value; @@ -663,7 +671,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab { .setDesc(fragWithHTML(t("FILENAME_PREFIX_DESC"))) .addText((text) => text - .setPlaceholder("Drawing ") + .setPlaceholder("e.g.: Drawing ") .setValue(this.plugin.settings.drawingFilenamePrefix) .onChange(async (value) => { this.plugin.settings.drawingFilenamePrefix = value.replaceAll( @@ -790,12 +798,25 @@ export class ExcalidrawSettingTab extends PluginSettingTab { }), ); + new Setting(detailsEl) + .setName(t("AI_OPENAI_DEFAULT_IMAGE_MODEL_NAME")) + .setDesc(fragWithHTML(t("AI_OPENAI_DEFAULT_IMAGE_MODEL_DESC"))) + .addText((text) => + text + .setPlaceholder(t("AI_OPENAI_DEFAULT_IMAGE_MODEL_PLACEHOLDER")) + .setValue(this.plugin.settings.openAIDefaultImageGenerationModel) + .onChange(async (value) => { + this.plugin.settings.openAIDefaultImageGenerationModel = value; + this.applySettingsUpdate(); + }), + ); + new Setting(detailsEl) .setName(t("AI_OPENAI_DEFAULT_API_URL_NAME")) .setDesc(fragWithHTML(t("AI_OPENAI_DEFAULT_API_URL_DESC"))) .addText((text) => text - .setPlaceholder("https://api.openai.com/v1/chat/completions") + .setPlaceholder("e.g.: https://api.openai.com/v1/chat/completions") .setValue(this.plugin.settings.openAIURL) .onChange(async (value) => { this.plugin.settings.openAIURL = value; @@ -1537,7 +1558,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab { .setDesc(fragWithHTML(t("EMBED_WIDTH_DESC"))) .addText((text) => text - .setPlaceholder("400") + .setPlaceholder("e.g.: 400") .setValue(this.plugin.settings.width) .onChange(async (value) => { this.plugin.settings.width = value; @@ -2166,6 +2187,19 @@ export class ExcalidrawSettingTab extends PluginSettingTab { cls: "excalidraw-setting-h1", }); + new Setting(detailsEl) + .setName(t("SLIDING_PANES_NAME")) + .setDesc(fragWithHTML(t("SLIDING_PANES_DESC"))) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.slidingPanesSupport) + .onChange((value) => { + this.plugin.settings.slidingPanesSupport = value; + this.applySettingsUpdate(); + }), + ); + + new Setting(detailsEl) .setName(t("COMPATIBILITY_MODE_NAME")) .setDesc(fragWithHTML(t("COMPATIBILITY_MODE_DESC"))) diff --git a/src/svgToExcalidraw/elements/ExcalidrawElement.ts b/src/svgToExcalidraw/elements/ExcalidrawElement.ts index 617610a..87af05a 100644 --- a/src/svgToExcalidraw/elements/ExcalidrawElement.ts +++ b/src/svgToExcalidraw/elements/ExcalidrawElement.ts @@ -1,6 +1,6 @@ import { randomId, randomInteger } from "../utils"; -import { ExcalidrawLinearElement, FillStyle, GroupId, RoundnessType, StrokeStyle } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawLinearElement, FillStyle, GroupId, RoundnessType, StrokeStyle } from "@zsviczian/excalidraw/types/excalidraw/element/types"; export type Point = [number, number]; diff --git a/src/svgToExcalidraw/types.ts b/src/svgToExcalidraw/types.ts index 8434215..9301473 100644 --- a/src/svgToExcalidraw/types.ts +++ b/src/svgToExcalidraw/types.ts @@ -1,4 +1,4 @@ -import { ExcalidrawElement, ExcalidrawLinearElement, ExcalidrawTextElement, FillStyle, GroupId, RoundnessType, StrokeStyle } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawElement, ExcalidrawLinearElement, ExcalidrawTextElement, FillStyle, GroupId, RoundnessType, StrokeStyle } from "@zsviczian/excalidraw/types/excalidraw/element/types"; export type PathCommand = { type: string; diff --git a/src/utils/AIUtils.ts b/src/utils/AIUtils.ts index 0c1f80c..b1fe5d2 100644 --- a/src/utils/AIUtils.ts +++ b/src/utils/AIUtils.ts @@ -1,3 +1,4 @@ +import { AnyARecord } from "dns"; import { Notice, RequestUrlResponse, requestUrl } from "obsidian"; import ExcalidrawPlugin from "src/main"; @@ -7,9 +8,9 @@ type MessageContent = export type GPTCompletionRequest = { model: string; - messages: { - role: "system" | "user" | "assistant" | "function"; - content: MessageContent; + messages?: { + role?: "system" | "user" | "assistant" | "function"; + content?: MessageContent; name?: string | undefined; }[]; functions?: any[] | undefined; @@ -28,6 +29,11 @@ export type GPTCompletionRequest = { } | undefined; stop?: (string[] | string) | undefined; + size?: string; + quality?: "standard" | "hd"; + prompt?: string; + image?: string; + mask?: string; }; export type AIRequest = { @@ -35,31 +41,100 @@ export type AIRequest = { text?: string; instruction?: string; systemPrompt?: string; + imageGenerationProperties?: { + size?: string; //depends on model + quality?: "standard" | "hd"; //depends on model + n?: number; //dall-e-3 only accepts 1 + mask?: string; //dall-e-2 only (image editing) + }; }; -export const postOpenAI = async (request: AIRequest) : Promise => { +const handleImageEditPrompt = async (request: AIRequest) : Promise => { const plugin: ExcalidrawPlugin = window.ExcalidrawAutomate.plugin; - const { openAIAPIToken, openAIDefaultTextModel, openAIDefaultVisionModel, openAIURL} = plugin.settings; - const { image, text, instruction, systemPrompt } = request; - const requestType = image ? "image" : "text"; + const { + openAIAPIToken, + openAIImageEditsURL, + } = plugin.settings; + const { image, text, imageGenerationProperties} = request; + + const body = new FormData(); + body.append("model", "dall-e-2"); + text.trim() !== "" && body.append("prompt", text); + + if (image) { + const imageFile = await fetch(image) + .then((res) => res.blob()) + .then((blob) => new File([blob], 'image.png', { type: 'image/png' })); + body.append('image', imageFile); + } + + if (imageGenerationProperties.mask) { + const maskFile = await fetch(imageGenerationProperties.mask) + .then((res) => res.blob()) + .then((blob) => new File([blob], 'mask.png', { type: 'image/png' })); + body.append('mask', maskFile); + } + + Boolean(image) && body.append("image", image); + + imageGenerationProperties.size && body.append("size", imageGenerationProperties.size); + imageGenerationProperties.n && body.append("n", String(imageGenerationProperties.n)); + + try { + //https://platform.openai.com/docs/api-reference/images + const resp = await fetch( + openAIImageEditsURL, + { + method: "post", + body, + headers: { + //"Content-Type": "multipart/form-data", + Authorization: `Bearer ${openAIAPIToken}`, + }, + //mode: 'no-cors' + } + ); + if(!resp) return null; + return { + status: resp.status, + headers: resp.headers as any, + text: null, + json: await resp.json(), + arrayBuffer: null, + }; + } catch (e) { + console.log(e); + } + return null; +} + +const handleGenericPrompt = async (request: AIRequest) : Promise => { + const plugin: ExcalidrawPlugin = window.ExcalidrawAutomate.plugin; + const { + openAIAPIToken, + openAIDefaultTextModel, + openAIDefaultVisionModel, + openAIURL, + openAIImageGenerationURL, + openAIDefaultImageGenerationModel, + } = plugin.settings; + const { image, text, instruction, systemPrompt, imageGenerationProperties} = request; + const isImageGeneration = Boolean(imageGenerationProperties); + const requestType = isImageGeneration ? "dall-e" : (image ? "image" : "text"); let body: GPTCompletionRequest; - if(openAIAPIToken === "") { - new Notice("OpenAI API Token is not set. Please set it in plugin settings."); - return null; - } switch (requestType) { case "text": body = { model: openAIDefaultTextModel, max_tokens: 4096, messages: [ - ...(systemPrompt ? [{role: "system" as const,content: systemPrompt}] : []), + ...(systemPrompt && systemPrompt.trim() !=="" ? [{role: "system" as const,content: systemPrompt}] : []), { role: "user", content: text, }, - ...(instruction ? [{role: "user" as const,content: instruction}] : []) + ...(instruction && instruction.trim() !=="" ? [{role: "user" as const,content: instruction}] : []), ], }; break; @@ -68,7 +143,7 @@ export const postOpenAI = async (request: AIRequest) : Promise => { + const plugin: ExcalidrawPlugin = window.ExcalidrawAutomate.plugin; + const { openAIAPIToken } = plugin.settings; + const { image, imageGenerationProperties} = request; + const isImageGeneration = Boolean(imageGenerationProperties); + const isImageVariationOrEditing = isImageGeneration && (Boolean(imageGenerationProperties.mask) || Boolean(image)); + + if(openAIAPIToken === "") { + new Notice("OpenAI API Token is not set. Please set it in plugin settings."); + return null; + } + + if(isImageVariationOrEditing) { + return await handleImageEditPrompt(request); + } + return await handleGenericPrompt(request); + +} + /** * Grabs the codeblock contents from the supplied markdown string. * @param markdown diff --git a/src/utils/CustomEmbeddableUtils.ts b/src/utils/CustomEmbeddableUtils.ts index 3dddf1a..2e670f5 100644 --- a/src/utils/CustomEmbeddableUtils.ts +++ b/src/utils/CustomEmbeddableUtils.ts @@ -1,4 +1,4 @@ -import { NonDeletedExcalidrawElement } from "@zsviczian/excalidraw/types/element/types"; +import { NonDeletedExcalidrawElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { DEVICE, REG_LINKINDEX_INVALIDCHARS } from "src/constants/constants"; import { getParentOfClass } from "./ObsidianUtils"; import { TFile, WorkspaceLeaf } from "obsidian"; diff --git a/src/utils/DynamicStyling.ts b/src/utils/DynamicStyling.ts index 28dd3b2..2f45be3 100644 --- a/src/utils/DynamicStyling.ts +++ b/src/utils/DynamicStyling.ts @@ -1,10 +1,10 @@ -import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types"; +import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/excalidraw/types"; import { ColorMaster } from "colormaster"; import { ExcalidrawAutomate } from "src/ExcalidrawAutomate"; import ExcalidrawView from "src/ExcalidrawView"; import { DynamicStyle } from "src/types"; import { cloneElement } from "src/ExcalidrawAutomate"; -import { ExcalidrawFrameElement } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawFrameElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { addAppendUpdateCustomData } from "./Utils"; import { mutateElement } from "src/constants/constants"; diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts index c351b78..95fe08e 100644 --- a/src/utils/FileUtils.ts +++ b/src/utils/FileUtils.ts @@ -1,4 +1,4 @@ -import { DataURL } from "@zsviczian/excalidraw/types/types"; +import { DataURL } from "@zsviczian/excalidraw/types/excalidraw/types"; import { loadPdfJs, normalizePath, Notice, requestUrl, RequestUrlResponse, TAbstractFile, TFile, TFolder, Vault } from "obsidian"; import { DEVICE, URLFETCHTIMEOUT } from "src/constants/constants"; import { IMAGE_MIME_TYPES, MimeType } from "src/EmbeddedFileLoader"; @@ -176,7 +176,7 @@ const getFileFromURL = async (url: string, mimeType: MimeType, timeout: number = ); const response = await Promise.race([ - fetch(url), + fetch(url, { mode: 'no-cors' }), timeoutPromise, ]); @@ -210,7 +210,7 @@ const getFileFromURLFallback = async (url: string, mimeType: MimeType, timeout: return await Promise.race([ timeoutPromise, - requestUrl({url: url, method: "get", contentType: mimeType, throw: false }) + requestUrl({url: url, method: "get", contentType: mimeType, throw: false }), ]) } catch (e) { errorlog({where: getFileFromURLFallback, message: `URL did not load within timeout period of ${timeout}ms`, url: url}); diff --git a/src/utils/GetElementAtPointer.ts b/src/utils/GetElementAtPointer.ts index af26260..2ad8b4a 100644 --- a/src/utils/GetElementAtPointer.ts +++ b/src/utils/GetElementAtPointer.ts @@ -1,4 +1,4 @@ -import { ExcalidrawElement, ExcalidrawImageElement, ExcalidrawTextElement } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawElement, ExcalidrawImageElement, ExcalidrawTextElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { REGEX_LINK, REG_LINKINDEX_HYPERLINK } from "src/ExcalidrawData"; import ExcalidrawView, { TextMode } from "src/ExcalidrawView"; import { rotatedDimensions } from "./Utils"; diff --git a/src/utils/MermaidUtils.ts b/src/utils/MermaidUtils.ts index e730649..8530dbc 100644 --- a/src/utils/MermaidUtils.ts +++ b/src/utils/MermaidUtils.ts @@ -1,4 +1,4 @@ -import { ExcalidrawElement, ExcalidrawImageElement } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawElement, ExcalidrawImageElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { requireApiVersion } from "obsidian"; export const getMermaidImageElements = (elements: ExcalidrawElement[]):ExcalidrawImageElement[] => diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 5ff7fb6..2397785 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -6,7 +6,7 @@ import { TFile, } from "obsidian"; import { Random } from "roughjs/bin/math"; -import { BinaryFileData, DataURL} from "@zsviczian/excalidraw/types/types"; +import { BinaryFileData, DataURL} from "@zsviczian/excalidraw/types/excalidraw/types"; import { ASSISTANT_FONT, CASCADIA_FONT, @@ -23,13 +23,13 @@ import { IMAGE_TYPES } from "../constants/constants"; import ExcalidrawPlugin from "../main"; -import { ExcalidrawElement } from "@zsviczian/excalidraw/types/element/types"; +import { ExcalidrawElement } from "@zsviczian/excalidraw/types/excalidraw/element/types"; import { ExportSettings } from "../ExcalidrawView"; import { getDataURLFromURL, getIMGFilename, getMimeType, getURLImageExtension } from "./FileUtils"; import { generateEmbeddableLink } from "./CustomEmbeddableUtils"; import ExcalidrawScene from "src/svgToExcalidraw/elements/ExcalidrawScene"; import { FILENAMEPARTS } from "./UtilTypes"; -import { Mutable } from "@zsviczian/excalidraw/types/utility-types"; +import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import { cleanBlockRef, cleanSectionHeading, getFileCSSClasses } from "./ObsidianUtils"; import { updateElementLinksToObsidianLinks } from "src/ExcalidrawAutomate";