This commit is contained in:
zsviczian
2023-07-23 19:09:19 +02:00
parent 71582220ee
commit bb2d30f9e3
10 changed files with 79 additions and 22 deletions

View File

@@ -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",

View File

@@ -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 => {

View File

@@ -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,

View File

@@ -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,
);
}

View File

@@ -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";

View File

@@ -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);
})();
}

View File

@@ -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",

View File

@@ -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;
}
}

View File

@@ -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()

View File

@@ -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);