mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
1.9.10
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "1.9.9",
|
||||
"version": "1.9.10",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -871,6 +871,7 @@ export class ExcalidrawAutomate {
|
||||
[this.getElement(id)],
|
||||
{ x: topX, y: topY },
|
||||
false,
|
||||
this.getExcalidrawAPI(),
|
||||
)[0];
|
||||
return id;
|
||||
};
|
||||
@@ -1688,7 +1689,7 @@ export class ExcalidrawAutomate {
|
||||
errorMessage("targetView not set", "addElementsToView()");
|
||||
return false;
|
||||
}
|
||||
const elements = this.getElements();
|
||||
const elements = this.getElements();
|
||||
return await this.targetView.addElements(
|
||||
elements,
|
||||
repositionToCursor,
|
||||
@@ -2587,6 +2588,7 @@ export function repositionElementsToCursor(
|
||||
elements: ExcalidrawElement[],
|
||||
newPosition: { x: number; y: number },
|
||||
center: boolean = false,
|
||||
api: ExcalidrawImperativeAPI,
|
||||
): ExcalidrawElement[] {
|
||||
const [x1, y1, x2, y2] = estimateBounds(elements);
|
||||
let [offsetX, offsetY] = [0, 0];
|
||||
@@ -2604,7 +2606,8 @@ export function repositionElementsToCursor(
|
||||
element.x = element.x + offsetX;
|
||||
element.y = element.y + offsetY;
|
||||
});
|
||||
return elements;
|
||||
|
||||
return api.restore({elements}).elements;
|
||||
}
|
||||
|
||||
function errorMessage(message: string, source: string) {
|
||||
@@ -2743,18 +2746,20 @@ export const getFrameElementsMatchingQuery = (
|
||||
}
|
||||
return m[1] === q.toLowerCase();
|
||||
}
|
||||
const text = el.name.toLowerCase().replaceAll("\n", " ").trim();
|
||||
const text = el.name
|
||||
? el.name.toLowerCase().replaceAll("\n", " ").trim()
|
||||
: "";
|
||||
|
||||
return text.match(q.toLowerCase()); //to distinguish between "# frame" and "# frame 1" https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/530
|
||||
}));
|
||||
}
|
||||
|
||||
export const cloneElement = (el: ExcalidrawElement):any => {
|
||||
return {
|
||||
...el,
|
||||
version: el.version + 1,
|
||||
updated: Date.now(),
|
||||
versionNonce: Math.floor(Math.random() * 1000000000),
|
||||
}
|
||||
const newEl = JSON.parse(JSON.stringify(el));
|
||||
newEl.version = el.version + 1;
|
||||
newEl.updated = Date.now();
|
||||
newEl.versionNonce = Math.floor(Math.random() * 1000000000);
|
||||
return newEl;
|
||||
}
|
||||
|
||||
export const verifyMinimumPluginVersion = (requiredVersion: string): boolean => {
|
||||
|
||||
@@ -1172,9 +1172,12 @@ export class ExcalidrawData {
|
||||
await getAttachmentsFolderAndFilePath(this.app, this.file.path, fname)
|
||||
).filepath;
|
||||
|
||||
const arrayBuffer = await getBinaryFileFromDataURL(dataURL);
|
||||
if(!arrayBuffer) return null;
|
||||
|
||||
const file = await this.app.vault.createBinary(
|
||||
filepath,
|
||||
getBinaryFileFromDataURL(dataURL),
|
||||
arrayBuffer,
|
||||
);
|
||||
|
||||
const embeddedFile = new EmbeddedFile(
|
||||
@@ -1182,7 +1185,7 @@ export class ExcalidrawData {
|
||||
this.file.path,
|
||||
filepath,
|
||||
);
|
||||
|
||||
|
||||
embeddedFile.setImage(
|
||||
dataURL,
|
||||
mimeType,
|
||||
|
||||
@@ -2194,6 +2194,10 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const dataURL = await getDataURLFromURL(link,mimeType,3000);
|
||||
const fileId = await generateIdFromFile((new TextEncoder()).encode(dataURL as string))
|
||||
const file = await this.excalidrawData.saveDataURLtoVault(dataURL,mimeType,fileId);
|
||||
if(!file) {
|
||||
new Notice(t("ERROR_SAVING_IMAGE"));
|
||||
return;
|
||||
}
|
||||
await ea.addImage(0,0,file);
|
||||
ea.addElementsToView(true,true,true);
|
||||
}
|
||||
@@ -2648,6 +2652,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
newElements,
|
||||
this.currentPosition,
|
||||
true,
|
||||
api,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export const ROUNDNESS = { //should at one point publish @zsviczian/excalidraw/t
|
||||
ADAPTIVE_RADIUS: 3,
|
||||
} as const;
|
||||
export const GITHUB_RELEASES = "https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/";
|
||||
export const URLFETCHTIMEOUT = 1000;
|
||||
export const URLFETCHTIMEOUT = 3000;
|
||||
export const PLUGIN_ID = "obsidian-excalidraw-plugin";
|
||||
export const SCRIPT_INSTALL_CODEBLOCK = "excalidraw-script-install";
|
||||
export const SCRIPT_INSTALL_FOLDER = "Downloaded";
|
||||
|
||||
@@ -61,7 +61,7 @@ export class InsertImageDialog extends FuzzySuggestModal<TFile> {
|
||||
const scaleToFullsize = scaleToFullsizeModifier(event);
|
||||
(async () => {
|
||||
await ea.addImage(0, 0, item, !scaleToFullsize);
|
||||
ea.addElementsToView(true, false, true);
|
||||
ea.addElementsToView(true, true, true);
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ export default {
|
||||
BACKUP_RESTORED: "Backup restored",
|
||||
CACHE_NOT_READY: "I apologize for the inconvenience, but an error occurred while loading your file.<br><br><mark>Having a little patience can save you a lot of time...</mark><br><br>The plugin has a backup cache, but it appears that you have just started Obsidian. Initializing the Backup Cache may take some time, usually up to a minute or more depending on your device's performance. You will receive a notification in the top right corner when the cache initialization is complete.<br><br>Please press OK to attempt loading the file again and check if the cache has finished initializing. If you see a completely empty file behind this message, I recommend waiting until the backup cache is ready before proceeding. Alternatively, you can choose Cancel to manually correct your file.<br>",
|
||||
OBSIDIAN_TOOLS_PANEL: "Obsidian Tools Panel",
|
||||
ERROR_SAVING_IMAGE: "Unknown error occured while fetching the image. It could be that for some reason the image is not available or rejected the fetch request from Obsidian",
|
||||
|
||||
//settings.ts
|
||||
RELEASE_NOTES_NAME: "Display Release Notes after update",
|
||||
|
||||
@@ -21,7 +21,7 @@ export const insertImageToView = async (
|
||||
file,
|
||||
scale,
|
||||
);
|
||||
await ea.addElementsToView(false, false, true);
|
||||
await ea.addElementsToView(false, true, true);
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export const insertEmbeddableToView = async (
|
||||
link,
|
||||
file,
|
||||
);
|
||||
await ea.addElementsToView(false, false, true);
|
||||
await ea.addElementsToView(false, true, true);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +169,38 @@ export const getMimeType = (extension: string):MimeType => {
|
||||
}
|
||||
}
|
||||
|
||||
const getFileFromURL = async (url: string, mimeType: MimeType, timeout: number = URLFETCHTIMEOUT):Promise<RequestUrlResponse> => {
|
||||
|
||||
// using fetch API
|
||||
const getFileFromURL = async (url: string, mimeType: MimeType, timeout: number = URLFETCHTIMEOUT): Promise<RequestUrlResponse> => {
|
||||
try {
|
||||
const response = await Promise.race([
|
||||
fetch(url),
|
||||
new Promise<Response>((resolve) => setTimeout(() => resolve(null), timeout))
|
||||
]);
|
||||
|
||||
if (!response) {
|
||||
new Notice(`URL did not load within the timeout period of ${timeout}ms.\n\nTry force-saving again in a few seconds.\n\n${url}`,8000);
|
||||
throw new Error(`URL did not load within the timeout period of ${timeout}ms`);
|
||||
}
|
||||
|
||||
const arrayBuffer = await response.arrayBuffer();
|
||||
|
||||
return {
|
||||
status: response.status,
|
||||
headers: Object.fromEntries(response.headers.entries()),
|
||||
arrayBuffer: arrayBuffer,
|
||||
json: null,
|
||||
text: null,
|
||||
};
|
||||
} catch (e) {
|
||||
errorlog({ where: getFileFromURL, message: e.message, url: url });
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
// using Obsidian requestUrl (this failed on a firebase link)
|
||||
// https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2FJSG%2FfTMP6WGQRC.png?alt=media&token=6d2993b4-e629-46b6-98d1-133af7448c49
|
||||
const getFileFromURLFallback = async (url: string, mimeType: MimeType, timeout: number = URLFETCHTIMEOUT):Promise<RequestUrlResponse> => {
|
||||
try {
|
||||
return await Promise.race([
|
||||
(async () => new Promise<RequestUrlResponse>((resolve) => setTimeout(()=>resolve(null), timeout)))(),
|
||||
@@ -181,12 +212,15 @@ const getFileFromURL = async (url: string, mimeType: MimeType, timeout: number =
|
||||
}
|
||||
}
|
||||
|
||||
export const getDataURLFromURL = async (url: string, mimeType: MimeType, timeout: number = URLFETCHTIMEOUT):Promise<DataURL> => {
|
||||
const response = await getFileFromURL(url, mimeType, timeout);
|
||||
export const getDataURLFromURL = async (url: string, mimeType: MimeType, timeout: number = URLFETCHTIMEOUT): Promise<DataURL> => {
|
||||
let response = await getFileFromURL(url, mimeType, timeout);
|
||||
if(response && response.status !== 200) {
|
||||
response = await getFileFromURLFallback(url, mimeType, timeout);
|
||||
}
|
||||
return response && response.status === 200
|
||||
? await getDataURL(response.arrayBuffer, mimeType)
|
||||
: url as DataURL;
|
||||
}
|
||||
};
|
||||
|
||||
export const blobToBase64 = async (blob: Blob): Promise<string> => {
|
||||
const arrayBuffer = await blob.arrayBuffer()
|
||||
|
||||
@@ -24,7 +24,7 @@ import ExcalidrawPlugin from "../main";
|
||||
import { ExcalidrawElement } from "@zsviczian/excalidraw/types/element/types";
|
||||
import { ExportSettings } from "../ExcalidrawView";
|
||||
import { compressToBase64, decompressFromBase64 } from "lz-string";
|
||||
import { getIMGFilename } from "./FileUtils";
|
||||
import { getDataURLFromURL, getIMGFilename, getMimeType, getURLImageExtension } from "./FileUtils";
|
||||
import ExcalidrawScene from "../svgToExcalidraw/elements/ExcalidrawScene";
|
||||
import { IMAGE_TYPES } from "../Constants";
|
||||
import { generateEmbeddableLink } from "./CustomEmbeddableUtils";
|
||||
@@ -229,11 +229,20 @@ export const svgToBase64 = (svg: string): string => {
|
||||
)}`;
|
||||
};
|
||||
|
||||
export const getBinaryFileFromDataURL = (dataURL: string): ArrayBuffer => {
|
||||
export const getBinaryFileFromDataURL = async (dataURL: string): Promise<ArrayBuffer> => {
|
||||
if (!dataURL) {
|
||||
return null;
|
||||
}
|
||||
if(dataURL.match(/^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i)) {
|
||||
const hyperlink = dataURL;
|
||||
const extension = getURLImageExtension(hyperlink)
|
||||
const mimeType = getMimeType(extension);
|
||||
dataURL = await getDataURLFromURL(hyperlink, mimeType)
|
||||
}
|
||||
const parts = dataURL.matchAll(/base64,(.*)/g).next();
|
||||
if (!parts.value) {
|
||||
return null;
|
||||
}
|
||||
const binary_string = window.atob(parts.value[1]);
|
||||
const len = binary_string.length;
|
||||
const bytes = new Uint8Array(len);
|
||||
|
||||
Reference in New Issue
Block a user