mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
iframe beta 2
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -612,6 +612,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
y: number,
|
||||
w: number,
|
||||
h: number,
|
||||
link: string | null = null,
|
||||
) {
|
||||
return {
|
||||
id,
|
||||
@@ -640,11 +641,33 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
isDeleted: false,
|
||||
groupIds: [] as any,
|
||||
boundElements: [] as any,
|
||||
link: null as string,
|
||||
link,
|
||||
locked: false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param topX
|
||||
* @param topY
|
||||
* @param width
|
||||
* @param height
|
||||
* @returns
|
||||
*/
|
||||
addIFrame(topX: number, topY: number, width: number, height: number, url?: string, file?: TFile): string {
|
||||
const id = nanoid();
|
||||
this.elementsDict[id] = this.boxedElement(
|
||||
id,
|
||||
"iframe",
|
||||
topX,
|
||||
topY,
|
||||
width,
|
||||
height,
|
||||
url ? url : file ? `[[${file.path}]]` : "",
|
||||
);
|
||||
return id;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param topX
|
||||
|
||||
@@ -114,6 +114,7 @@ import { setDynamicStyle } from "./utils/DynamicStyling";
|
||||
import { MenuLinks } from "./menu/MenuLinks";
|
||||
import { InsertPDFModal } from "./dialogs/InsertPDFModal";
|
||||
import { CustomIFrame, renderWebView, useDefaultExcalidrawFrame } from "./customIFrame";
|
||||
import { insertIFrameToView, insertImageToView } from "./utils/ExcalidrawViewUtils";
|
||||
|
||||
declare const PLUGIN_VERSION:string;
|
||||
|
||||
@@ -2951,6 +2952,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
case "image": msg = "Embed image";break;
|
||||
case "image-fullsize": msg = "Embed image @100%"; break;
|
||||
case "link": msg = "Insert link"; break;
|
||||
case "iframe": msg = "Insert in interactive frame"; break;
|
||||
}
|
||||
} else if(e.dataTransfer.types.length === 1 && e.dataTransfer.types.includes("Files")) {
|
||||
//drag from OS file manager
|
||||
@@ -2961,6 +2963,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
case "image-import": msg = "Import image to Vault"; break;
|
||||
case "image-url": msg = "Insert image/thumbnail with URL"; break;
|
||||
case "insert-link": msg = "Insert link"; break;
|
||||
case "iframe": msg = "Insert in interactive frame"; break;
|
||||
}
|
||||
}
|
||||
if(this.draginfoDiv.innerText !== msg) this.draginfoDiv.innerText = msg;
|
||||
@@ -3173,6 +3176,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const internalDragAction = internalDragModifierType(event);
|
||||
const externalDragAction = externalDragModifierType(event);
|
||||
|
||||
//Call Excalidraw Automate onDropHook
|
||||
const onDropHook = (
|
||||
type: "file" | "text" | "unknown",
|
||||
files: TFile[],
|
||||
@@ -3204,39 +3208,47 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
};
|
||||
|
||||
//Obsidian internal drag event
|
||||
//---------------------------------------------------------------------------------
|
||||
// Obsidian internal drag event
|
||||
//---------------------------------------------------------------------------------
|
||||
switch (draggable?.type) {
|
||||
case "file":
|
||||
if (!onDropHook("file", [draggable.file], null)) {
|
||||
const file:TFile = draggable.file;
|
||||
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/422
|
||||
if (draggable.file.path.match(REG_LINKINDEX_INVALIDCHARS)) {
|
||||
if (file.path.match(REG_LINKINDEX_INVALIDCHARS)) {
|
||||
new Notice(t("FILENAME_INVALID_CHARS"), 4000);
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
["image", "image-fullsize"].contains(internalDragAction) &&
|
||||
(IMAGE_TYPES.contains(draggable.file.extension) ||
|
||||
draggable.file.extension === "md" ||
|
||||
draggable.file.extension.toLowerCase() === "pdf" )
|
||||
(IMAGE_TYPES.contains(file.extension) ||
|
||||
file.extension === "md" ||
|
||||
file.extension.toLowerCase() === "pdf" )
|
||||
) {
|
||||
const ea = getEA(this);
|
||||
if(draggable.file.extension.toLowerCase() === "pdf") {
|
||||
if(file.extension.toLowerCase() === "pdf") {
|
||||
const insertPDFModal = new InsertPDFModal(this.plugin, this);
|
||||
insertPDFModal.open(draggable.file);
|
||||
insertPDFModal.open(file);
|
||||
} else {
|
||||
(async () => {
|
||||
ea.canvas.theme = api.getAppState().theme;
|
||||
await ea.addImage(
|
||||
this.currentPosition.x,
|
||||
this.currentPosition.y,
|
||||
draggable.file,
|
||||
!(internalDragAction==="image-fullsize"),
|
||||
);
|
||||
ea.addElementsToView(false, false, true);
|
||||
})();
|
||||
insertImageToView(
|
||||
getEA(this),
|
||||
this.currentPosition,
|
||||
file,
|
||||
!(internalDragAction==="image-fullsize")
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (internalDragAction === "iframe") {
|
||||
insertIFrameToView(
|
||||
getEA(this),
|
||||
this.currentPosition,
|
||||
file,
|
||||
)
|
||||
return false;
|
||||
}
|
||||
|
||||
//internalDragAction === "link"
|
||||
this.addText(
|
||||
`[[${app.metadataCache.fileToLinktext(
|
||||
@@ -3272,6 +3284,28 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (internalDragAction === "iframe") {
|
||||
const ea = getEA(this) as ExcalidrawAutomate;
|
||||
let column:number = 0;
|
||||
let row:number = 0;
|
||||
for (const f of draggable.files) {
|
||||
await insertIFrameToView(
|
||||
ea,
|
||||
{
|
||||
x:this.currentPosition.x + column*500,
|
||||
y:this.currentPosition.y + row*550
|
||||
},
|
||||
f,
|
||||
)
|
||||
column = (column + 1) % 3;
|
||||
if(column === 0) {
|
||||
row++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//internalDragAction === "link"
|
||||
for (const f of draggable.files) {
|
||||
await this.addText(
|
||||
@@ -3289,7 +3323,9 @@ export default class ExcalidrawView extends TextFileView {
|
||||
return false;
|
||||
}
|
||||
|
||||
//externalDragAction
|
||||
//---------------------------------------------------------------------------------
|
||||
// externalDragAction
|
||||
//---------------------------------------------------------------------------------
|
||||
if (event.dataTransfer.types.includes("Files")) {
|
||||
if (event.dataTransfer.types.includes("text/plain")) {
|
||||
const text: string = event.dataTransfer.getData("text");
|
||||
@@ -3312,6 +3348,15 @@ export default class ExcalidrawView extends TextFileView {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(text && (externalDragAction === "iframe")) {
|
||||
insertIFrameToView(
|
||||
getEA(this),
|
||||
this.currentPosition,
|
||||
undefined,
|
||||
text,
|
||||
)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(event.dataTransfer.types.includes("text/html")) {
|
||||
@@ -3333,6 +3378,15 @@ export default class ExcalidrawView extends TextFileView {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(src && (externalDragAction === "iframe")) {
|
||||
insertIFrameToView(
|
||||
getEA(this),
|
||||
this.currentPosition,
|
||||
undefined,
|
||||
src[1],
|
||||
)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3353,6 +3407,9 @@ export default class ExcalidrawView extends TextFileView {
|
||||
return true;
|
||||
}
|
||||
if (!onDropHook("text", null, text)) {
|
||||
if(text && (externalDragAction==="iframe") && /^(http|https):\/\/[^\s/$.?#].[^\s]*$/.test(text)) {
|
||||
return true;
|
||||
}
|
||||
if(text && (externalDragAction==="image-url") && hyperlinkIsYouTubeLink(text)) {
|
||||
this.addYouTubeThumbnail(text);
|
||||
return false;
|
||||
|
||||
@@ -185,7 +185,7 @@ function RenderObsidianView(
|
||||
return;
|
||||
}
|
||||
|
||||
isActiveRef.current = appState.activeIFrameElement === element;
|
||||
isActiveRef.current = appState.activeIFrame?.element === element && appState.activeIFrame?.state === "active";
|
||||
|
||||
if(!isActiveRef.current) {
|
||||
//@ts-ignore
|
||||
@@ -194,7 +194,7 @@ function RenderObsidianView(
|
||||
app.workspace.setActiveLeaf(view.leaf);
|
||||
return;
|
||||
}
|
||||
}, [appState.activeIFrameElement, element]);
|
||||
}, [appState.activeIFrame, element]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -220,6 +220,19 @@ export const CustomIFrame: React.FC<{element: NonDeletedExcalidrawElement; radiu
|
||||
view={view}
|
||||
containerRef={containerRef}
|
||||
appState={appState}/>
|
||||
{(appState.activeIFrame?.element === element && appState.activeIFrame?.state === "hover") && (<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: `100%`,
|
||||
height: `100%`,
|
||||
background: `radial-gradient(
|
||||
ellipse at center,
|
||||
rgba(0, 0, 0, 0) 20%,
|
||||
rgba(0, 0, 0, 0.6) 80%
|
||||
)`,
|
||||
}}/>)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
189
src/dialogs/UniversalInsertFileModal.ts
Normal file
189
src/dialogs/UniversalInsertFileModal.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
import { ButtonComponent, DropdownComponent, TFile, ToggleComponent } from "obsidian";
|
||||
import ExcalidrawView from "../ExcalidrawView";
|
||||
import ExcalidrawPlugin from "../main";
|
||||
import { Modal, Setting, TextComponent } from "obsidian";
|
||||
import { FileSuggestionModal } from "./FolderSuggester";
|
||||
import { IMAGE_TYPES, REG_BLOCK_REF_CLEAN } from "src/Constants";
|
||||
import { insertIFrameToView, insertImageToView } from "src/utils/ExcalidrawViewUtils";
|
||||
import { getEA } from "src";
|
||||
import { InsertPDFModal } from "./InsertPDFModal";
|
||||
import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types";
|
||||
import { MAX_IMAGE_SIZE } from "src/Constants";
|
||||
|
||||
const {
|
||||
viewportCoordsToSceneCoords
|
||||
//@ts-ignore
|
||||
} = excalidrawLib;
|
||||
|
||||
export class UniversalInsertFileModal extends Modal {
|
||||
private center: { x: number, y: number } = { x: 0, y: 0 };
|
||||
constructor(
|
||||
private plugin: ExcalidrawPlugin,
|
||||
private view: ExcalidrawView,
|
||||
) {
|
||||
super(app);
|
||||
const appState = (view.excalidrawAPI as ExcalidrawImperativeAPI).getAppState();
|
||||
const containerRect = view.containerEl.getBoundingClientRect();
|
||||
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
|
||||
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||
|
||||
const centerX = containerRect.left + containerRect.width / 2 - MAX_IMAGE_SIZE / 2;
|
||||
const centerY = containerRect.top + containerRect.height / 2 - MAX_IMAGE_SIZE / 2;
|
||||
|
||||
const clientX = Math.max(0, Math.min(viewportWidth, centerX));
|
||||
const clientY = Math.max(0, Math.min(viewportHeight, centerY));
|
||||
|
||||
this.center = viewportCoordsToSceneCoords ({clientX, clientY}, appState)
|
||||
}
|
||||
|
||||
onOpen(): void {
|
||||
this.containerEl.classList.add("excalidraw-release");
|
||||
this.titleEl.setText(`Insert File From Vault`);
|
||||
this.createForm();
|
||||
}
|
||||
|
||||
async createForm() {
|
||||
const ce = this.contentEl;
|
||||
let sectionPicker: DropdownComponent;
|
||||
let sectionPickerSetting: Setting;
|
||||
let actionIFrame: ButtonComponent;
|
||||
let actionImage: ButtonComponent;
|
||||
let actionPDF: ButtonComponent;
|
||||
let sizeToggleSetting: Setting
|
||||
let anchorTo100: boolean = false;
|
||||
let file: TFile;
|
||||
|
||||
const updateForm = async () => {
|
||||
const ea = this.plugin.ea;
|
||||
const isMarkdown = file && file.extension === "md" && !ea.isExcalidrawFile(file);
|
||||
const isImage = file && (IMAGE_TYPES.contains(file.extension) || ea.isExcalidrawFile(file));
|
||||
const isIFrame = file && !isImage;
|
||||
const isPDF = file && file.extension === "pdf";
|
||||
const isExcalidraw = file && ea.isExcalidrawFile(file);
|
||||
|
||||
if (isMarkdown) {
|
||||
sectionPickerSetting.settingEl.style.display = "";
|
||||
sectionPicker.selectEl.style.display = "block";
|
||||
while(sectionPicker.selectEl.options.length > 0) {
|
||||
sectionPicker.selectEl.remove(0);
|
||||
}
|
||||
sectionPicker.addOption("","");
|
||||
(await app.metadataCache.blockCache
|
||||
.getForFile({ isCancelled: () => false },file))
|
||||
.blocks.filter((b: any) => b.display && b.node?.type === "heading")
|
||||
.forEach((b: any) => {
|
||||
sectionPicker.addOption(
|
||||
`#${b.display.replaceAll(REG_BLOCK_REF_CLEAN, "").trim()}`,
|
||||
b.display)
|
||||
});
|
||||
} else {
|
||||
sectionPickerSetting.settingEl.style.display = "none";
|
||||
sectionPicker.selectEl.style.display = "none";
|
||||
}
|
||||
|
||||
if (isExcalidraw) {
|
||||
sizeToggleSetting.settingEl.style.display = "";
|
||||
} else {
|
||||
sizeToggleSetting.settingEl.style.display = "none";
|
||||
}
|
||||
|
||||
if (isImage || (file?.extension === "md")) {
|
||||
actionImage.buttonEl.style.display = "block";
|
||||
} else {
|
||||
actionImage.buttonEl.style.display = "none";
|
||||
}
|
||||
|
||||
if (isIFrame) {
|
||||
actionIFrame.buttonEl.style.display = "block";
|
||||
} else {
|
||||
actionIFrame.buttonEl.style.display = "none";
|
||||
}
|
||||
|
||||
if (isPDF) {
|
||||
actionPDF.buttonEl.style.display = "block";
|
||||
} else {
|
||||
actionPDF.buttonEl.style.display = "none";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const search = new TextComponent(ce);
|
||||
search.inputEl.style.width = "100%";
|
||||
const suggester = new FileSuggestionModal(this.app, search,app.vault.getFiles().filter((f: TFile) => f!==this.view.file));
|
||||
search.onChange(() => {
|
||||
file = suggester.getSelectedItem();
|
||||
updateForm();
|
||||
});
|
||||
|
||||
sectionPickerSetting = new Setting(ce)
|
||||
.setName("Select section heading")
|
||||
.addDropdown(dropdown => {
|
||||
sectionPicker = dropdown;
|
||||
sectionPicker.selectEl.style.width = "100%";
|
||||
})
|
||||
|
||||
sizeToggleSetting = new Setting(ce)
|
||||
.setName("Anchor to 100% of original size")
|
||||
.setDesc("This is a pro feature, use it only if you understand how it works. If enabled even if you change the size of the imported image in Excalidraw, the next time you open the drawing this image will pop back to 100% size. This is useful when embedding an atomic Excalidraw idea into another note and preserving relative sizing of text and icons.")
|
||||
.addToggle(toggle => {
|
||||
toggle.setValue(anchorTo100)
|
||||
.onChange((value) => {
|
||||
anchorTo100 = value;
|
||||
})
|
||||
})
|
||||
|
||||
new Setting(ce)
|
||||
.addButton(button => {
|
||||
button
|
||||
.setButtonText("As IFrame")
|
||||
.setCta()
|
||||
.onClick(() => {
|
||||
const path = app.metadataCache.fileToLinktext(
|
||||
file,
|
||||
this.view.file.path,
|
||||
file.extension === "md",
|
||||
)
|
||||
|
||||
insertIFrameToView (
|
||||
getEA(this.view),
|
||||
this.center,
|
||||
//this.view.currentPosition,
|
||||
undefined,
|
||||
`[[${path}${sectionPicker.selectEl.value}]]`,
|
||||
)
|
||||
this.close();
|
||||
})
|
||||
actionIFrame = button;
|
||||
})
|
||||
.addButton(button => {
|
||||
button
|
||||
.setButtonText("As PDF")
|
||||
.setCta()
|
||||
.onClick(() => {
|
||||
const insertPDFModal = new InsertPDFModal(this.plugin, this.view);
|
||||
insertPDFModal.open(file);
|
||||
this.close();
|
||||
})
|
||||
actionPDF = button;
|
||||
})
|
||||
.addButton(button => {
|
||||
button
|
||||
.setButtonText("As Image")
|
||||
.setCta()
|
||||
.onClick(() => {
|
||||
insertImageToView (
|
||||
getEA(this.view),
|
||||
this.center,
|
||||
//this.view.currentPosition,
|
||||
file,
|
||||
anchorTo100,
|
||||
)
|
||||
this.close();
|
||||
})
|
||||
actionImage = button;
|
||||
})
|
||||
|
||||
search.inputEl.focus();
|
||||
updateForm();
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ export default {
|
||||
IMPORT_SVG: "Import an SVG file as Excalidraw strokes (limited SVG support, TEXT currently not supported)",
|
||||
INSERT_MD: "Insert markdown file from vault",
|
||||
INSERT_PDF: "Insert PDF file from vault",
|
||||
UNIVERSAL_ADD_FILE: "Add a file from the Vault to the drawing",
|
||||
INSERT_LATEX:
|
||||
`Insert LaTeX formula (e.g. \\binom{n}{k} = \\frac{n!}{k!(n-k)!}). ${labelALT()}+CLICK to watch a help video.`,
|
||||
ENTER_LATEX: "Enter a valid LaTeX expression",
|
||||
|
||||
18
src/main.ts
18
src/main.ts
@@ -103,6 +103,7 @@ import Taskbone from "./ocr/Taskbone";
|
||||
import { emulateCTRLClickForLinks, linkClickModifierType, PaneTarget } from "./utils/ModifierkeyHelper";
|
||||
import { InsertPDFModal } from "./dialogs/InsertPDFModal";
|
||||
import { ExportDialog } from "./dialogs/ExportDialog";
|
||||
import { UniversalInsertFileModal } from "./dialogs/UniversalInsertFileModal";
|
||||
|
||||
declare module "obsidian" {
|
||||
interface App {
|
||||
@@ -1351,6 +1352,23 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: "universal-add-file",
|
||||
name: t("UNIVERSAL_ADD_FILE"),
|
||||
checkCallback: (checking: boolean) => {
|
||||
if (checking) {
|
||||
return Boolean(this.app.workspace.getActiveViewOfType(ExcalidrawView))
|
||||
}
|
||||
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
|
||||
if (view) {
|
||||
const insertFileModal = new UniversalInsertFileModal(this, view);
|
||||
insertFileModal.open();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: "insert-LaTeX-symbol",
|
||||
name: t("INSERT_LATEX"),
|
||||
|
||||
@@ -583,6 +583,22 @@ export const ICONS = {
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M211.1 303c8 37.5-1 85.2-27.5 131.6 22.2-46 33-90.1 24-131l3.5-.7Z" fill="url(#h)"/>
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M302.7 299.5c43.5 16.3 60.3 52 72.8 81.9-15.5-31.2-37-65.7-74.4-78.5-28.4-9.8-52.4-8.6-93.5.7l-.9-4c43.6-10 66.4-11.2 96 0Z" fill="url(#i)"/>
|
||||
</svg>
|
||||
),
|
||||
"add-file": (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="var(--icon-fill-color)"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
|
||||
<polyline points="14 2 14 8 20 8"/>
|
||||
<line x1="12" x2="12" y1="18" y2="12"/>
|
||||
<line x1="9" x2="15" y1="15" y2="15"/>
|
||||
</svg>
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { PenStyle } from "src/PenTypes";
|
||||
import { PENS } from "src/utils/Pens";
|
||||
import ExcalidrawPlugin from "../main";
|
||||
import { ICONS, penIcon, stringToSVG } from "./ActionIcons";
|
||||
import { UniversalInsertFileModal } from "src/dialogs/UniversalInsertFileModal";
|
||||
|
||||
declare const PLUGIN_VERSION:string;
|
||||
|
||||
@@ -254,6 +255,23 @@ export class ObsidianMenu {
|
||||
{ICONS.obsidian}
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
className={clsx(
|
||||
"ToolIcon",
|
||||
"ToolIcon_size_medium",
|
||||
{
|
||||
"is-mobile": isMobile,
|
||||
},
|
||||
)}
|
||||
onClick={() => {
|
||||
const insertFileModal = new UniversalInsertFileModal(this.plugin, this.view);
|
||||
insertFileModal.open();
|
||||
}}
|
||||
>
|
||||
<div className="ToolIcon__icon" aria-hidden="true">
|
||||
{ICONS["add-file"]}
|
||||
</div>
|
||||
</label>
|
||||
{this.renderCustomPens(isMobile,appState)}
|
||||
{this.renderPinnedScriptButtons(isMobile,appState)}
|
||||
</>
|
||||
|
||||
45
src/utils/ExcalidrawViewUtils.ts
Normal file
45
src/utils/ExcalidrawViewUtils.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
import { MAX_IMAGE_SIZE } from "src/Constants";
|
||||
import { TFile } from "obsidian";
|
||||
import { IMAGE_TYPES } from "src/Constants";
|
||||
import { ExcalidrawAutomate } from "src/ExcalidrawAutomate";
|
||||
|
||||
export const insertImageToView = async (
|
||||
ea: ExcalidrawAutomate,
|
||||
position: { x: number, y: number },
|
||||
file: TFile,
|
||||
scale?: boolean,
|
||||
) => {
|
||||
ea.clear();
|
||||
const api = ea.getExcalidrawAPI();
|
||||
ea.canvas.theme = api.getAppState().theme;
|
||||
await ea.addImage(
|
||||
position.x,
|
||||
position.y,
|
||||
file,
|
||||
scale,
|
||||
);
|
||||
ea.addElementsToView(false, false, true);
|
||||
}
|
||||
|
||||
export const insertIFrameToView = async (
|
||||
ea: ExcalidrawAutomate,
|
||||
position: { x: number, y: number },
|
||||
file?: TFile,
|
||||
link?: string,
|
||||
) => {
|
||||
ea.clear();
|
||||
if(file && IMAGE_TYPES.contains(file.extension) || ea.isExcalidrawFile(file)) {
|
||||
await insertImageToView(ea, position, file);
|
||||
} else {
|
||||
ea.addIFrame(
|
||||
position.x,
|
||||
position.y,
|
||||
MAX_IMAGE_SIZE,
|
||||
MAX_IMAGE_SIZE,
|
||||
link,
|
||||
file,
|
||||
);
|
||||
ea.addElementsToView(false, false, true);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ import { DEVICE, isDarwin } from "src/Constants";
|
||||
export type ModifierKeys = {shiftKey:boolean, ctrlKey: boolean, metaKey: boolean, altKey: boolean};
|
||||
export type KeyEvent = PointerEvent | MouseEvent | KeyboardEvent | React.DragEvent | React.PointerEvent | React.MouseEvent | ModifierKeys;
|
||||
export type PaneTarget = "active-pane"|"new-pane"|"popout-window"|"new-tab"|"md-properties";
|
||||
export type ExternalDragAction = "insert-link"|"image-url"|"image-import";
|
||||
export type InternalDragAction = "link"|"image"|"image-fullsize";
|
||||
export type ExternalDragAction = "insert-link"|"image-url"|"image-import"|"iframe";
|
||||
export type InternalDragAction = "link"|"image"|"image-fullsize"|"iframe";
|
||||
|
||||
export const labelCTRL = () => DEVICE.isIOS || DEVICE.isMacOS ? "CMD" : "CTRL";
|
||||
export const labelALT = () => DEVICE.isIOS || DEVICE.isMacOS ? "OPT" : "ALT";
|
||||
@@ -31,6 +31,7 @@ export const linkClickModifierType = (ev: KeyEvent):PaneTarget => {
|
||||
}
|
||||
|
||||
export const externalDragModifierType = (ev: KeyEvent):ExternalDragAction => {
|
||||
if( isSHIFT(ev) && isCTRL(ev) && !isALT(ev) && !isMETA(ev)) return "iframe";
|
||||
if(!isSHIFT(ev) && isCTRL(ev) && !isALT(ev) && !isMETA(ev)) return "insert-link";
|
||||
if(!isSHIFT(ev) && !isCTRL(ev) && !isALT(ev) && isMETA(ev)) return "insert-link";
|
||||
if( isSHIFT(ev) && !isCTRL(ev) && !isALT(ev) && !isMETA(ev)) return "image-import";
|
||||
@@ -40,6 +41,7 @@ export const externalDragModifierType = (ev: KeyEvent):ExternalDragAction => {
|
||||
|
||||
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/468
|
||||
export const internalDragModifierType = (ev: KeyEvent):InternalDragAction => {
|
||||
if( isSHIFT(ev) && isCTRL(ev) && !isALT(ev) && !isMETA(ev)) return "iframe";
|
||||
if( isSHIFT(ev) && !isCTRL(ev) && !isALT(ev) && !isMETA(ev)) return "image";
|
||||
if(!isSHIFT(ev) && isCTRL(ev) && !isALT(ev) && !isMETA(ev)) return "image";
|
||||
if(scaleToFullsizeModifier(ev)) return "image-fullsize";
|
||||
|
||||
Reference in New Issue
Block a user