diff --git a/src/OneOffs.ts b/src/OneOffs.ts index bbbd89f..863b279 100644 --- a/src/OneOffs.ts +++ b/src/OneOffs.ts @@ -12,6 +12,7 @@ export class OneOffs { this.plugin = plugin; } + /* public patchCommentBlock() { //This is a once off cleanup process to remediate incorrectly placed comment %% before # Text Elements if (!this.plugin.settings.patchCommentBlock) { @@ -368,4 +369,5 @@ class ImageElementNotice extends Modal { }; }); } + */ } diff --git a/src/ReleaseNotes.ts b/src/ReleaseNotes.ts new file mode 100644 index 0000000..46257f7 --- /dev/null +++ b/src/ReleaseNotes.ts @@ -0,0 +1,75 @@ +import { App, MarkdownRenderer, Modal } from "obsidian"; +import ExcalidrawPlugin from "./main"; + +const RELEASE_NOTES: { [k: string]: string } = { +Intro: `I want to make it easier for you to keep up with all the updates. +Going forward, after installing each release, you'll be prompted with a message summarizing the key new features and fixes. +You can disable this in plugin-settings. The release change log is also avalable on [GitHub](https://github.com/zsviczian/obsidian-excalidraw-plugin/releases). + +Since March 2021, I've spent most of my free time building this plugin. By now, this means well over 100 workdays worth of my time (assuming 8-hour days). +I am greatful to all of you who have already bought me a coffee. THANK YOU! This means a lot to me! + +I still have many-many ideas for making Obsidian Excalidraw better. +I will continue to keep all the features of the plugin free. If, however, you'd like to contribute to the on-going development of the plugin, I am introducing a simple membership scheme, with Insider, Supporter and VIP tiers. +If you find this plugin valuable, please consider clicking the button below. + +
+`, +"1.6.16":` +
+
+ +## Fixed +- CMD+Drag does not work on Mac. You can now use SHIFT+Drag to embed an image or markdown document from the file Obsidian File Explorer into a scene. + +## New Features +`}; + +export class ReleaseNotes extends Modal { + private plugin: ExcalidrawPlugin; + private version: string; + + constructor(app: App, plugin: ExcalidrawPlugin, version: string) { + super(app); + this.plugin = plugin; + //@ts-ignore + this.version = version; + } + + onOpen(): void { + this.contentEl.classList.add("excalidraw-release"); + this.containerEl.classList.add(".excalidraw-release"); + this.titleEl.setText(`Welcome to Excalidraw ${this.version}`); + this.createForm(); + } + + async onClose() { + this.contentEl.empty(); + await this.plugin.loadSettings(); + this.plugin.settings.previousRelease = this.version; + await this.plugin.saveSettings(); + } + + async createForm() { + const prevRelease = this.plugin.settings.previousRelease; + const message = Object + .keys(RELEASE_NOTES) + .filter(key=>key>prevRelease) + .map((key:string)=>`# ${key}\n${RELEASE_NOTES[key]}`) + .join("\n\n"); + await MarkdownRenderer.renderMarkdown( + message, + this.contentEl, + "", + this.plugin, + ); + + + this.contentEl.createEl("p", { text: "" }, (el) => { + //files manually follow one of two options: + el.style.textAlign = "right"; + const bOk = el.createEl("button", { text: "Thank you!" }); + bOk.onclick = () => this.close(); + }); + } +} \ No newline at end of file diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 59582f6..8ff268d 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -75,6 +75,9 @@ export default { CONVERT_FILE: "Convert to new format", //settings.ts + RELEASE_NOTES_NAME: "Display Release Notes after update", + RELEASE_NOTES_DESC: "Toggle ON: Display release notes each time you update Excalidraw to a newer version.
" + + "Toggle OFF: Silent mode. You can still read release notes on [GitHub](https://github.com/zsviczian/obsidian-excalidraw-plugin/releases).", FOLDER_NAME: "Excalidraw folder", FOLDER_DESC: "Default location for new drawings. If empty, drawings will be created in the Vault root.", diff --git a/src/main.ts b/src/main.ts index d97e4f6..5c511ff 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,1705 +1,1709 @@ -import { - TFile, - Plugin, - WorkspaceLeaf, - addIcon, - App, - PluginManifest, - MarkdownView, - normalizePath, - Menu, - MenuItem, - TAbstractFile, - ViewState, - Notice, - loadMathJax, - Scope, - request, - MetadataCache, - FrontMatterCache, -} from "obsidian"; -import { - BLANK_DRAWING, - VIEW_TYPE_EXCALIDRAW, - EXCALIDRAW_ICON, - ICON_NAME, - SCRIPTENGINE_ICON, - SCRIPTENGINE_ICON_NAME, - DISK_ICON, - DISK_ICON_NAME, - PNG_ICON, - PNG_ICON_NAME, - SVG_ICON, - SVG_ICON_NAME, - RERENDER_EVENT, - FRONTMATTER_KEY, - FRONTMATTER, - JSON_parse, - nanoid, - DARK_BLANK_DRAWING, - CTRL_OR_CMD, - SCRIPT_INSTALL_CODEBLOCK, - SCRIPT_INSTALL_FOLDER, - VIRGIL_FONT, - VIRGIL_DATAURL, -} from "./constants"; -import ExcalidrawView, { TextMode } from "./ExcalidrawView"; -import { changeThemeOfExcalidrawMD, getMarkdownDrawingSection } from "./ExcalidrawData"; -import { - ExcalidrawSettings, - DEFAULT_SETTINGS, - ExcalidrawSettingTab, -} from "./settings"; -import { openDialogAction, OpenFileDialog } from "./openDrawing"; -import { InsertLinkDialog } from "./InsertLinkDialog"; -import { InsertImageDialog } from "./InsertImageDialog"; -import { InsertMDDialog } from "./InsertMDDialog"; -import { - initExcalidrawAutomate, - destroyExcalidrawAutomate, - ExcalidrawAutomate, -} from "./ExcalidrawAutomate"; -import { Prompt } from "./Prompt"; -import { around } from "monkey-around"; -import { t } from "./lang/helpers"; -import { - checkAndCreateFolder, - download, - errorlog, - getAttachmentsFolderAndFilePath, - getFontDataURL, - getIMGPathFromExcalidrawFile, - getNewUniqueFilepath, - isObsidianThemeDark, - log, - sleep, -} from "./Utils"; -import { OneOffs } from "./OneOffs"; -import { FileId } from "@zsviczian/excalidraw/types/element/types"; -import { ScriptEngine } from "./Scripts"; -import { - hoverEvent, - initializeMarkdownPostProcessor, - markdownPostProcessor, - observer, -} from "./MarkdownPostProcessor"; -import { FieldSuggestor } from "./FieldSuggestor"; - -declare module "obsidian" { - interface App { - isMobile(): boolean; - } - interface Workspace { - on( - name: "hover-link", - callback: (e: MouseEvent) => any, - ctx?: any, - ): EventRef; - } -} - -export default class ExcalidrawPlugin extends Plugin { - private excalidrawFiles: Set = new Set(); - public excalidrawFileModes: { [file: string]: string } = {}; - private _loaded: boolean = false; - public settings: ExcalidrawSettings; - private openDialog: OpenFileDialog; - private insertLinkDialog: InsertLinkDialog; - private insertImageDialog: InsertImageDialog; - private insertMDDialog: InsertMDDialog; - private activeExcalidrawView: ExcalidrawView = null; - public lastActiveExcalidrawFilePath: string = null; - public hover: { linkText: string; sourcePath: string } = { - linkText: null, - sourcePath: null, - }; - private observer: MutationObserver; - private themeObserver: MutationObserver; - private fileExplorerObserver: MutationObserver; - public opencount: number = 0; - public ea: ExcalidrawAutomate; - //A master list of fileIds to facilitate copy / paste - public filesMaster: Map = - null; //fileId, path - public equationsMaster: Map = null; //fileId, formula - public mathjax: any = null; - private mathjaxDiv: HTMLDivElement = null; - public scriptEngine: ScriptEngine; - public fourthFontDef: string = VIRGIL_FONT; - constructor(app: App, manifest: PluginManifest) { - super(app, manifest); - this.filesMaster = new Map< - FileId, - { path: string; hasSVGwithBitmap: boolean } - >(); - this.equationsMaster = new Map(); - } - - async onload() { - addIcon(ICON_NAME, EXCALIDRAW_ICON); - addIcon(SCRIPTENGINE_ICON_NAME, SCRIPTENGINE_ICON); - addIcon(DISK_ICON_NAME, DISK_ICON); - addIcon(PNG_ICON_NAME, PNG_ICON); - addIcon(SVG_ICON_NAME, SVG_ICON); - - await this.loadSettings(); - this.addSettingTab(new ExcalidrawSettingTab(this.app, this)); - this.ea = await initExcalidrawAutomate(this); - - this.registerView( - VIEW_TYPE_EXCALIDRAW, - (leaf: WorkspaceLeaf) => new ExcalidrawView(leaf, this), - ); - - //Compatibility mode with .excalidraw files - this.registerExtensions(["excalidraw"], VIEW_TYPE_EXCALIDRAW); - - this.addMarkdownPostProcessor(); - this.registerInstallCodeblockProcessor(); - this.addThemeObserver(); - this.experimentalFileTypeDisplayToggle(this.settings.experimentalFileType); - this.registerCommands(); - this.registerEventListeners(); - this.initializeFourthFont(); - this.registerEditorSuggest(new FieldSuggestor(this)); - - //inspiration taken from kanban: - //https://github.com/mgmeyers/obsidian-kanban/blob/44118e25661bff9ebfe54f71ae33805dc88ffa53/src/main.ts#L267 - this.registerMonkeyPatches(); - - if (!this.app.isMobile) { - const electron: string = process?.versions?.electron; - if (electron && electron?.startsWith("8.")) { - new Notice( - `You are running an older version of the electron Browser (${electron}). If Excalidraw does not start up, please reinstall Obsidian with the latest installer and try again.`, - 10000, - ); - } - } - - const patches = new OneOffs(this); - patches.migrationNotice(); - patches.patchCommentBlock(); - patches.wysiwygPatch(); - patches.imageElementLaunchNotice(); - - this.switchToExcalidarwAfterLoad(); - - this.loadMathJax(); - - const self = this; - this.app.workspace.onLayoutReady(() => { - this.scriptEngine = new ScriptEngine(self); - }); - } - - public initializeFourthFont() { - this.app.workspace.onLayoutReady(async () => { - const font = await getFontDataURL( - this.app, - this.settings.experimantalFourthFont, - "", - "LocalFont", - ); - const fourthFontDataURL = - font.dataURL === "" ? VIRGIL_DATAURL : font.dataURL; - this.fourthFontDef = font.fontDef; - const newStylesheet = document.createElement("style"); - newStylesheet.id = "local-font-stylesheet"; - newStylesheet.textContent = ` - @font-face { - font-family: 'LocalFont'; - src: url("${fourthFontDataURL}"); - font-display: swap; - } - `; - // replace the old local font