Compare commits

...

5 Commits

Author SHA1 Message Date
Zsolt Viczian 454c68b4b9 1.2.0-beta-1 2021-07-08 22:59:12 +02:00
Zsolt Viczian 09889d7ed3 1.2.0-alpha-4 2021-07-07 23:03:36 +02:00
Zsolt Viczian 096efc45d7 Added migration modal window to help with conversion 2021-07-06 22:16:51 +02:00
Zsolt Viczian 55291d8c27 two minor errors corrected 2021-07-05 21:30:40 +02:00
Zsolt Viczian e81787ee4b 1.2.0-alpha-3 2021-07-04 22:37:04 +02:00
8 changed files with 295 additions and 78 deletions
+1 -1
View File
@@ -175,7 +175,7 @@ export async function initExcalidrawAutomate(plugin: ExcalidrawPlugin) {
elements.push(this.elementsDict[this.elementIds[i]]);
}
plugin.createDrawing(
params?.filename ? params.filename + '.excalidraw' : this.plugin.getNextDefaultFilename(),
params?.filename ? params.filename + '.excalidraw.md' : this.plugin.getNextDefaultFilename(),
params?.onNewPane ? params.onNewPane : false,
params?.foldername ? params.foldername : this.plugin.settings.folder,
FRONTMATTER + exportSceneToMD(
+15 -7
View File
@@ -1,4 +1,4 @@
import { App, TFile } from "obsidian";
import { App, normalizePath, TFile } from "obsidian";
import {
nanoid,
FRONTMATTER_KEY_CUSTOM_PREFIX,
@@ -57,14 +57,22 @@ export class ExcalidrawData {
this.setShowLinkBrackets();
this.setLinkPrefix();
//Load scene: Read the JSON string after "# Drawing"
this.scene = null;
if (this.settings.syncExcalidraw) {
const excalfile = file.path.substring(0,file.path.lastIndexOf('.md')) + '.excalidraw';
const f = this.app.vault.getAbstractFileByPath(excalfile);
if(f && f instanceof TFile && f.stat.mtime>file.stat.mtime) { //the .excalidraw file is newer then the .md file
const d = await this.app.vault.read(f);
this.scene = JSON.parse(d);
}
}
//Load scene: Read the JSON string after "# Drawing"
let parts = data.matchAll(/\n# Drawing\n(.*)/gm).next();
if(!(parts.value && parts.value.length>1)) return false; //JSON not found or invalid
this.scene = JSON_parse(parts.value[1]);
if(!this.scene) { //scene was not loaded from .excalidraw
this.scene = JSON_parse(parts.value[1]);
}
//Trim data to remove the JSON string
data = data.substring(0,parts.value.index);
@@ -230,7 +238,7 @@ export class ExcalidrawData {
//1 2
const REG_FILE_BLOCKREF = /(.*)#\^(.*)/g;
const parts=text.matchAll(REG_FILE_BLOCKREF).next();
if(!parts.value[1] || !parts.value[2]) return text; //filename and/or blockref not found
if(parts.done || !parts.value[1] || !parts.value[2]) return text; //filename and/or blockref not found
const file = this.app.metadataCache.getFirstLinkpathDest(parts.value[1],this.file.path);
const contents = await this.app.vault.cachedRead(file);
//get transcluded line and take the part before ^blockref
+29 -9
View File
@@ -60,7 +60,7 @@ export default class ExcalidrawView extends TextFileView {
private justLoaded: boolean = false;
private plugin: ExcalidrawPlugin;
private dirty: boolean = false;
private autosaveTimer: any = null;
public autosaveTimer: any = null;
public isTextLocked:boolean = false;
private lockedElement:HTMLElement;
private unlockedElement:HTMLElement;
@@ -74,6 +74,17 @@ export default class ExcalidrawView extends TextFileView {
this.excalidrawData = new ExcalidrawData(plugin);
}
public saveExcalidraw(data?: string){
if(!data) {
if (!this.getScene) return false;
data = this.getScene();
}
const filepath = this.file.path.substring(0,this.file.path.lastIndexOf('.md')) + '.excalidraw';
const file = this.app.vault.getAbstractFileByPath(normalizePath(filepath));
if(file && file instanceof TFile) this.app.vault.modify(file,data.replaceAll("[","["));
else this.app.vault.create(filepath,data.replaceAll("[","["));
}
public async saveSVG(data?: string) {
if(!data) {
if (!this.getScene) return false;
@@ -131,15 +142,19 @@ export default class ExcalidrawView extends TextFileView {
getViewData () {
//console.log("ExcalidrawView.getViewData()");
if(this.getScene) {
const scene = this.getScene();
if(this.plugin.settings.autoexportSVG) this.saveSVG(scene);
if(this.plugin.settings.autoexportPNG) this.savePNG(scene);
if(this.excalidrawData.syncElements(scene)) {
if(this.excalidrawData.syncElements(this.getScene())) {
this.loadDrawing(false);
}
let trimLocation = this.data.search("# Text Elements\n");
if(trimLocation == -1) trimLocation = this.data.search("# Drawing\n");
if(trimLocation == -1) return this.data;
const scene = JSON_stringify(this.excalidrawData.scene);
if(this.plugin.settings.autoexportSVG) this.saveSVG(scene);
if(this.plugin.settings.autoexportPNG) this.savePNG(scene);
if(this.plugin.settings.autoexportExcalidraw) this.saveExcalidraw(scene);
const header = this.data.substring(0,trimLocation)
.replace(/excalidraw-plugin:\s.*\n/,FRONTMATTER_KEY+": " + (this.isTextLocked ? "locked\n" : "unlocked\n"));
return header + this.excalidrawData.generateMD();
@@ -240,16 +255,19 @@ export default class ExcalidrawView extends TextFileView {
}
}
private setupAutosaveTimer() {
public setupAutosaveTimer() {
const timer = async () => {
//console.log("ExcalidrawView.autosaveTimer(), dirty", this.dirty);
if(this.dirty) {
console.log("autosave",Date.now());
this.dirty = false;
if(this.excalidrawRef) await this.save();
this.plugin.triggerEmbedUpdates();
}
}
this.autosaveTimer = setInterval(timer,30000);
if(this.plugin.settings.autosave) {
this.autosaveTimer = setInterval(timer,30000);
}
}
//save current drawing when user closes workspace leaf
@@ -281,6 +299,8 @@ export default class ExcalidrawView extends TextFileView {
async setViewData (data: string, clear: boolean) {
this.app.workspace.onLayoutReady(async ()=>{
//console.log("ExcalidrawView.setViewData()");
this.plugin.settings.drawingOpenCount++;
this.plugin.saveSettings();
this.lock(data.search("excalidraw-plugin: locked\n")>-1,false);
if(!(await this.excalidrawData.loadData(data, this.file,this.isTextLocked))) return;
if(clear) this.clear();
@@ -543,13 +563,13 @@ export default class ExcalidrawView extends TextFileView {
if(this.isTextLocked && (e.target instanceof HTMLCanvasElement) && this.getSelectedText(true)) { //text element is selected
const now = (new Date()).getTime();
if(now-timestamp < 600) { //double click
var event = new MouseEvent('dblclick', {
let event = new MouseEvent('dblclick', {
'view': window,
'bubbles': true,
'cancelable': true,
});
e.target.dispatchEvent(event);
new Notice(t("UNLOCK_TO_EDIT"))
new Notice(t("UNLOCK_TO_EDIT"));
timestamp = now;
return;
}
+53
View File
@@ -0,0 +1,53 @@
import { App, Modal } from "obsidian";
import { t } from "./lang/helpers";
import ExcalidrawPlugin from "./main";
export class MigrationPrompt extends Modal {
private plugin: ExcalidrawPlugin;
constructor(app: App, plugin:ExcalidrawPlugin) {
super(app);
this.plugin = plugin;
}
onOpen(): void {
this.titleEl.setText("Welcome to Excalidraw 1.2");
this.createForm();
}
onClose(): void {
this.contentEl.empty();
}
createForm(): void {
const div = this.contentEl.createDiv();
div.addClass("excalidarw-prompt-div");
div.style.maxWidth = "600px";
div.createEl('p',{text: "This version comes with many new features and possibilities. Please read the description in Community Plugins to find out more."});
div.createEl('p',{text: ""} , (el) => {
el.innerHTML = "<b>⚠ ATTENTION</b>: Drawings you've created with version 1.1.x need to be converted, they WILL NOT WORK out of the box. "+
"During conversion your old *.excalidraw files will be replaced with new *.excalidraw.md files.";
});
div.createEl('p',{text: ""}, (el) => {//files manually follow one of two options:
el.innerHTML = "To convert your drawings you have the following options:<br><ul>" +
"<li>Click <code>CONVERT</code> to convert all of your *.excalidraw files now, or if you prefer to make a backup first, then click <code>CANCEL</code>.</li>" +
"<li>Using the Command Palette select <code>Excalidraw: Convert *.excalidraw files to *.excalidraw.md files</code></li>" +
"<li>Right click an *.excalidraw file in File Explorer and select one of the following to convert files individually: <ul>"+
"<li><code>*.excalidraw => *.excalidraw.md</code></li>"+
"<li><code>*.excalidraw => *.md (Logseq compatibility)</code>. This option will retain the original *.excalidraw file next to the new Obsidian format. " +
"Make sure you also enable <code>Compatibility features</code> in Settings for a full solution.</li></ul></li></ul>";
});
div.createEl('p',{text: "This message will only appear maximum 3 times in case you have *.excalidraw files in your Vault."});
const bConvert = div.createEl('button', {text: "CONVERT FILES"});
bConvert.onclick = (ev)=>{
this.plugin.convertExcalidrawToMD();
this.close();
};
const bCancel = div.createEl('button', {text: "CANCEL"});
bCancel.onclick = (ev)=>{
this.close();
};
}
}
+23 -9
View File
@@ -6,8 +6,10 @@ export default {
OPEN_AS_EXCALIDRAW: "Open as Excalidraw Drawing",
TOGGLE_MODE: "Toggle between Excalidraw and Markdown mode",
CONVERT_NOTE_TO_EXCALIDRAW: "Convert empty note to Excalidraw Drawing",
MIGRATE_TO_2: "MIGRATE to version 1.2: convert *.excalidraw to *.md files",
CONVERT_EXCALIDRAW: "Convert *.excalidraw to *.md files",
CREATE_NEW : "New Excalidraw drawing",
CONVERT_FILE_KEEP_EXT: "*.excalidraw => *.excalidraw.md",
CONVERT_FILE_REPLACE_EXT: "*.excalidraw => *.md (Logseq compatibility)",
OPEN_EXISTING_NEW_PANE: "Open an existing drawing - IN A NEW PANE",
OPEN_EXISTING_ACTIVE_PANE: "Open an existing drawing - IN THE CURRENT ACTIVE PANE",
TRANSCLUDE: "Transclude (embed) a drawing",
@@ -48,7 +50,12 @@ export default {
TEMPLATE_DESC: "Full filepath to the Excalidraw template. " +
"E.g.: If your template is in the default Excalidraw folder and it's name is " +
"Template.excalidraw, the setting would be: Excalidraw/Template.excalidraw",
FILENAME_HEAD: "Filenam for drawings",
AUTOSAVE_NAME: "Autosave",
AUTOSAVE_DESC: "Automatically save the active drawing every 30 seconds. Save normally happens when you close Excalidraw or Obsidian, or move "+
"focus to another pane. In rare cases autosave may slightly disrupt your drawing flow. I created this feature with mobile " +
"phones in mind (I only have experience with Android), where 'swiping out Obsidian to close it' led to some data loss, and because " +
"I wasn't able to force save on application termination on mobiles. If you use Excalidraw on a desktop this is likely not needed.",
FILENAME_HEAD: "Filename",
FILENAME_DESC: "<p>The auto-generated filename consists of a prefix and a date. " +
"e.g.'Drawing 2021-05-24 12.58.07'.</p>"+
"<p>Click this link for the <a href='https://momentjs.com/docs/#/displaying/format/'>"+
@@ -58,7 +65,7 @@ export default {
FILENAME_PREFIX_DESC: "The first part of the filename",
FILENAME_DATE_NAME: "Filename date",
FILENAME_DATE_DESC: "The second part of the filename",
LINKS_HEAD: "Links in drawings",
LINKS_HEAD: "Links",
LINKS_DESC: "CTRL/META + CLICK on Text Elements to open them as links. " +
"If the selected text has more than one [[valid Obsidian links]], only the first will be opened. " +
"If the text starts as a valid web link (i.e. https:// or http://), then " +
@@ -76,7 +83,7 @@ export default {
LINK_CTRL_CLICK_NAME: "CTRL + CLICK on text to open them as links",
LINK_CTRL_CLICK_DESC: "You can turn this feature off if it interferes with default Excalidraw features you want to use. If " +
"this is turned off, only the link button in the title bar of the drawing pane will open links.",
EMBED_HEAD: "Embedded/Export image settings",
EMBED_HEAD: "Embed & Export",
EMBED_WIDTH_NAME: "Default width of embedded (transcluded) image",
EMBED_WIDTH_DESC: "The default width of an embedded drawing. You can specify a custom " +
"width when embedding an image using the ![[drawing.excalidraw|100]] or " +
@@ -86,16 +93,23 @@ export default {
EXPORT_THEME_NAME: "Export image with theme",
EXPORT_THEME_DESC: "Export the image matching the dark/light theme of your drawing. If turned off, " +
"drawings created in drak mode will appear as they would in light mode.",
EXPORT_HEAD: "Export Settings",
EXPORT_SYNC_NAME:"Keep the .SVG and/or .PNG filenames in sync with the drawing file",
EXPORT_SYNC_DESC:"When turned on, the plugin will automaticaly update the filename of the .SVG and/or .PNG files when the drawing in the same folder (and same name) is renamed. " +
"The plugin will also automatically delete the .SVG and/or .PNG files when the drawing in the same folder (and same name) is deleted. ",
EXPORT_SVG_NAME: "Auto-export SVG",
EXPORT_SVG_DESC: "Automatically create an SVG export of your drawing matching the title of your file. " +
"The plugin will save the .SVG file in the same folder as the drawing. "+
"The plugin will save the *.SVG file in the same folder as the drawing. "+
"Embed the .svg file into your documents instead of excalidraw making you embeds platform independent. " +
"While the auto-export switch is on, this file will get updated every time you edit the excalidraw drawing with the matching name.",
EXPORT_PNG_NAME: "Auto-export PNG",
EXPORT_PNG_DESC: "Same as the auto-export SVG, but for PNG.",
EXPORT_SYNC_NAME:"Keep the .SVG and/or .PNG filenames in sync with the drawing file",
EXPORT_SYNC_DESC:"When turned on, the plugin will automaticaly update the filename of the .SVG and/or .PNG files when the drawing in the same folder (and same name) is renamed. " +
"The plugin will also automatically delete the .SVG and/or .PNG files when the drawing in the same folder (and same name) is deleted. ",
EXPORT_PNG_DESC: "Same as the auto-export SVG, but for *.PNG",
COMPATIBILITY_HEAD: "Compatibility features",
EXPORT_EXCALIDRAW_NAME: "Auto-export Excalidraw",
EXPORT_EXCALIDRAW_DESC: "Same as the auto-export SVG, but for *.Excalidraw",
SYNC_EXCALIDRAW_NAME: "Sync *.excalidraw with *.md version of the same drawing",
SYNC_EXCALIDRAW_DESC: "If the modified date of the *.excalidraw file is more recent than the modified date of the *.md file " +
"then update the drawing in the .md file based on the .excalidraw file",
//openDrawings.ts
SELECT_FILE: "Select a file then press enter.",
+103 -36
View File
@@ -15,6 +15,7 @@ import {
Tasks,
MarkdownRenderer,
ViewState,
Notice,
} from "obsidian";
import {
@@ -55,6 +56,7 @@ import {
import { Prompt } from "./Prompt";
import { around } from "monkey-around";
import { t } from "./lang/helpers";
import { MigrationPrompt } from "./MigrationPrompt";
export default class ExcalidrawPlugin extends Plugin {
public excalidrawFileModes: { [file: string]: string } = {};
@@ -94,8 +96,21 @@ export default class ExcalidrawPlugin extends Plugin {
//inspiration taken from kanban:
//https://github.com/mgmeyers/obsidian-kanban/blob/44118e25661bff9ebfe54f71ae33805dc88ffa53/src/main.ts#L267
this.registerMonkeyPatches();
if(this.settings.loadCount<3) this.migrationNotice();
}
private migrationNotice(){
const self = this;
this.app.workspace.onLayoutReady(async () => {
self.settings.loadCount++;
self.saveSettings();
const files = this.app.vault.getFiles().filter((f)=>f.extension=="excalidraw");
if(files.length>0) {
const prompt = new MigrationPrompt(self.app, self);
prompt.open();
}
});
}
/**
* Displays a transcluded .excalidraw image in markdown preview mode
*/
@@ -151,7 +166,7 @@ export default class ExcalidrawPlugin extends Plugin {
attr.fname = drawing.getAttribute("src");
file = this.app.metadataCache.getFirstLinkpathDest(attr.fname, ctx.sourcePath);
if(file && file instanceof TFile && this.isExcalidrawFile(file)) {
attr.fwidth = drawing.getAttribute("width");
attr.fwidth = drawing.getAttribute("width") ? drawing.getAttribute("width") : this.settings.width;
attr.fheight = drawing.getAttribute("height");
alt = drawing.getAttribute("alt");
if(alt == attr.fname) alt = ""; //when the filename starts with numbers followed by a space Obsidian recognizes the filename as alt-text
@@ -172,8 +187,8 @@ export default class ExcalidrawPlugin extends Plugin {
div = createDiv(attr.style, (el)=>{
el.append(img);
el.setAttribute("src",file.path);
el.setAttribute("w",attr.fwidth);
el.setAttribute("h",attr.fheight);
if(attr.fwidth) el.setAttribute("w",attr.fwidth);
if(attr.fheight) el.setAttribute("h",attr.fheight);
el.onClickEvent((ev)=>{
if(ev.target instanceof Element && ev.target.tagName.toLowerCase() != "img") return;
let src = el.getAttribute("src");
@@ -264,20 +279,52 @@ export default class ExcalidrawPlugin extends Plugin {
this.createDrawing(this.getNextDefaultFilename(), e.ctrlKey||e.metaKey);
});
const fileMenuHandler = (menu: Menu, file: TFile) => {
if (file instanceof TFolder) {
menu.addItem((item: MenuItem) => {
item.setTitle(t("CREATE_NEW"))
.setIcon(ICON_NAME)
.onClick(evt => {
this.createDrawing(this.getNextDefaultFilename(),false,file.path);
})
});
}
const fileMenuHandlerCreateNew = (menu: Menu, file: TFile) => {
menu.addItem((item: MenuItem) => {
item.setTitle(t("CREATE_NEW"))
.setIcon(ICON_NAME)
.onClick(evt => {
let folderpath = file.path;
if(file instanceof TFile) {
folderpath = normalizePath(file.path.substr(0,file.path.lastIndexOf(file.name)));
}
this.createDrawing(this.getNextDefaultFilename(),false,folderpath);
})
});
};
this.registerEvent(
this.app.workspace.on("file-menu", fileMenuHandler)
this.app.workspace.on("file-menu", fileMenuHandlerCreateNew)
);
const fileMenuHandlerConvertKeepExtension = (menu: Menu, file: TFile) => {
if(file instanceof TFile && file.extension == "excalidraw") {
menu.addItem((item: MenuItem) => {
item.setTitle(t("CONVERT_FILE_KEEP_EXT"))
.onClick(evt => {
this.convertSingleExcalidrawToMD(file,false,false);
})
});
}
};
this.registerEvent(
this.app.workspace.on("file-menu", fileMenuHandlerConvertKeepExtension)
);
const fileMenuHandlerConvertReplaceExtension = (menu: Menu, file: TFile) => {
if(file instanceof TFile && file.extension == "excalidraw") {
menu.addItem((item: MenuItem) => {
item.setTitle(t("CONVERT_FILE_REPLACE_EXT"))
.onClick(evt => {
this.convertSingleExcalidrawToMD(file,true,true);
})
});
}
};
this.registerEvent(
this.app.workspace.on("file-menu", fileMenuHandlerConvertReplaceExtension)
);
this.addCommand({
@@ -510,23 +557,37 @@ export default class ExcalidrawPlugin extends Plugin {
},
});
/*1.2 migration command */
this.addCommand({
id: "migrate-to-1.2.x",
name: t("MIGRATE_TO_2"),
callback: async () => {
const files = this.app.vault.getFiles().filter((f)=>f.extension=="excalidraw");
for (const file of files) {
const data = await this.app.vault.read(file);
const fname = this.getNewUniqueFilepath(file.name+'.md',normalizePath(file.path.substr(0,file.path.lastIndexOf(file.name))));
console.log(fname);
await this.app.vault.create(fname,FRONTMATTER + exportSceneToMD(data));
this.app.vault.delete(file);
id: "convert-excalidraw",
name: t("CONVERT_EXCALIDRAW"),
checkCallback: (checking) => {
if (checking) {
const files = this.app.vault.getFiles().filter((f)=>f.extension=="excalidraw");
return files.length>0;
}
this.convertExcalidrawToMD()
return true;
}
});
}
public async convertSingleExcalidrawToMD(file: TFile, replaceExtension:boolean = false, keepOriginal:boolean = false) {
const data = await this.app.vault.read(file);
const filename = file.name.substr(0,file.name.lastIndexOf(".excalidraw")) + (replaceExtension ? ".md" : ".excalidraw.md");
const fname = this.getNewUniqueFilepath(filename,normalizePath(file.path.substr(0,file.path.lastIndexOf(file.name))));
console.log(fname);
await this.app.vault.create(fname,FRONTMATTER + exportSceneToMD(data));
if (!keepOriginal) this.app.vault.delete(file);
}
public async convertExcalidrawToMD(replaceExtension:boolean = false, keepOriginal:boolean = false) {
const files = this.app.vault.getFiles().filter((f)=>f.extension=="excalidraw");
for (const file of files) {
this.convertSingleExcalidrawToMD(file,replaceExtension,keepOriginal);
}
new Notice("Converted " + files.length + " files.")
}
private registerMonkeyPatches() {
const self = this;
@@ -627,7 +688,7 @@ export default class ExcalidrawPlugin extends Plugin {
if(!(file instanceof TFile)) return;
if (!self.isExcalidrawFile(file)) return;
if (!self.settings.keepInSync) return;
['.svg','.png'].forEach(async (ext:string)=>{
['.svg','.png','.excalidraw'].forEach(async (ext:string)=>{
const oldIMGpath = oldPath.substring(0,oldPath.lastIndexOf('.md')) + ext;
const imgFile = self.app.vault.getAbstractFileByPath(normalizePath(oldIMGpath));
if(imgFile && imgFile instanceof TFile) {
@@ -644,8 +705,11 @@ export default class ExcalidrawPlugin extends Plugin {
const leaves = self.app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW);
leaves.forEach((leaf:WorkspaceLeaf)=> {
const excalidrawView = (leaf.view as ExcalidrawView);
if(excalidrawView.file && excalidrawView.file.path == file.path) {
excalidrawView.reload(true,file);
if(excalidrawView.file
&& (excalidrawView.file.path == file.path
|| (file.extension=="excalidraw"
&& file.path.substring(0,file.path.lastIndexOf('.excalidraw'))+'.md' == excalidrawView.file.path))) {
excalidrawView.reload(true,excalidrawView.file);
}
});
}
@@ -669,7 +733,7 @@ export default class ExcalidrawPlugin extends Plugin {
//delete PNG and SVG files as well
if (self.settings.keepInSync) {
['.svg','.png'].forEach(async (ext:string) => {
['.svg','.png','.excalidraw'].forEach(async (ext:string) => {
const imgPath = file.path.substring(0,file.path.lastIndexOf('.md')) + ext;
const imgFile = self.app.vault.getAbstractFileByPath(normalizePath(imgPath));
if(imgFile && imgFile instanceof TFile) {
@@ -695,14 +759,17 @@ export default class ExcalidrawPlugin extends Plugin {
//save Excalidraw leaf and update embeds when switching to another leaf
const activeLeafChangeEventHandler = async (leaf:WorkspaceLeaf) => {
const activeview:ExcalidrawView = (leaf.view instanceof ExcalidrawView) ? leaf.view as ExcalidrawView : null;
if(self.activeExcalidrawView && self.activeExcalidrawView != activeview) {
await self.activeExcalidrawView.save();
self.triggerEmbedUpdates(self.activeExcalidrawView.file?.path);
const activeExcalidrawView = self.activeExcalidrawView;
const newActiveview:ExcalidrawView = (leaf.view instanceof ExcalidrawView) ? leaf.view as ExcalidrawView : null;
if(activeExcalidrawView && activeExcalidrawView != newActiveview) {
await activeExcalidrawView.save(false);
if(activeExcalidrawView.file) {
self.triggerEmbedUpdates(activeExcalidrawView.file.path);
}
}
self.activeExcalidrawView = activeview;
if(self.activeExcalidrawView) {
self.lastActiveExcalidrawFilePath = self.activeExcalidrawView.file?.path;
self.activeExcalidrawView = newActiveview;
if(newActiveview) {
self.lastActiveExcalidrawFilePath = newActiveview.file?.path;
}
};
self.registerEvent(
+70 -16
View File
@@ -16,14 +16,18 @@ export interface ExcalidrawSettings {
width: string,
showLinkBrackets: boolean,
linkPrefix: string,
// validLinksOnly: boolean, //valid link as in [[valid Obsidian link]] - how to treat text elements in drawings
autosave: boolean;
allowCtrlClick: boolean, //if disabled only the link button in the view header will open links
exportWithTheme: boolean,
exportWithBackground: boolean,
keepInSync: boolean,
autoexportSVG: boolean,
autoexportPNG: boolean,
keepInSync: boolean,
autoexportExcalidraw: boolean,
syncExcalidraw: boolean,
library: string,
loadCount: number, //version 1.2 migration counter
drawingOpenCount: number,
}
export const DEFAULT_SETTINGS: ExcalidrawSettings = {
@@ -34,14 +38,18 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
width: '400',
linkPrefix: ">> ",
showLinkBrackets: true,
// validLinksOnly: false,
autosave: false,
allowCtrlClick: true,
exportWithTheme: true,
exportWithBackground: true,
keepInSync: false,
autoexportSVG: false,
autoexportPNG: false,
keepInSync: false,
autoexportExcalidraw: false,
syncExcalidraw: false,
library: `{"type":"excalidrawlib","version":1,"library":[]}`,
loadCount: 0,
drawingOpenCount: 0,
}
export class ExcalidrawSettingTab extends PluginSettingTab {
@@ -78,6 +86,28 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName(t("AUTOSAVE_NAME"))
.setDesc(t("AUTOSAVE_DESC"))
.addToggle(toggle => toggle
.setValue(this.plugin.settings.autosave)
.onChange(async (value) => {
this.plugin.settings.autosave = value;
await this.plugin.saveSettings();
const exs = this.plugin.app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW);
for(const v of exs) {
if(v.view instanceof ExcalidrawView) {
if(v.view.autosaveTimer) {
clearInterval(v.view.autosaveTimer)
v.view.autosaveTimer = null;
}
if(value) {
v.view.setupAutosaveTimer();
}
}
}
}));
this.containerEl.createEl('h1', {text: t("FILENAME_HEAD")});
containerEl.createDiv('',(el) => {
el.innerHTML = t("FILENAME_DESC");
@@ -202,7 +232,19 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
this.plugin.triggerEmbedUpdates();
}));
this.containerEl.createEl('h1', {text: t("EXPORT_HEAD")});
new Setting(containerEl)
.setName(t("EXPORT_SYNC_NAME"))
.setDesc(t("EXPORT_SYNC_DESC"))
.addToggle(toggle => toggle
.setValue(this.plugin.settings.keepInSync)
.onChange(async (value) => {
this.plugin.settings.keepInSync = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName(t("EXPORT_SVG_NAME"))
.setDesc(t("EXPORT_SVG_DESC"))
@@ -213,26 +255,38 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName(t("EXPORT_PNG_NAME"))
.setDesc(t("EXPORT_PNG_DESC"))
.addToggle(toggle => toggle
.setValue(this.plugin.settings.autoexportPNG)
.onChange(async (value) => {
this.plugin.settings.autoexportPNG = value;
await this.plugin.saveSettings();
}));
.addToggle(toggle => toggle
.setValue(this.plugin.settings.autoexportPNG)
.onChange(async (value) => {
this.plugin.settings.autoexportPNG = value;
await this.plugin.saveSettings();
}));
this.containerEl.createEl('h1', {text: t("COMPATIBILITY_HEAD")});
new Setting(containerEl)
.setName(t("EXPORT_SYNC_NAME"))
.setDesc(t("EXPORT_SYNC_DESC"))
.setName(t("EXPORT_EXCALIDRAW_NAME"))
.setDesc(t("EXPORT_EXCALIDRAW_DESC"))
.addToggle(toggle => toggle
.setValue(this.plugin.settings.keepInSync)
.setValue(this.plugin.settings.autoexportExcalidraw)
.onChange(async (value) => {
this.plugin.settings.keepInSync = value;
this.plugin.settings.autoexportExcalidraw = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName(t("SYNC_EXCALIDRAW_NAME"))
.setDesc(t("SYNC_EXCALIDRAW_DESC"))
.addToggle(toggle => toggle
.setValue(this.plugin.settings.syncExcalidraw)
.onChange(async (value) => {
this.plugin.settings.syncExcalidraw = value;
await this.plugin.saveSettings();
}));
}
}
+1
View File
@@ -51,6 +51,7 @@ button.ToolIcon_type_button[title="Export"] {
.excalidraw-prompt-div {
display: flex;
max-width: 600px;
}
.excalidraw-prompt-form {