canvas node wip

This commit is contained in:
zsviczian
2023-07-07 06:26:39 +02:00
parent de5b8b64a6
commit b869bd6861
8 changed files with 139 additions and 46 deletions

View File

@@ -93,10 +93,11 @@ import {
hyperlinkIsYouTubeLink,
getYouTubeThumbnailLink,
isContainer,
fragWithHTML,
} from "./utils/Utils";
import { getLeaf, getParentOfClass } from "./utils/ObsidianUtils";
import { splitFolderAndFilename } from "./utils/FileUtils";
import { ConfirmationPrompt, NewFileActions, Prompt } from "./dialogs/Prompt";
import { ConfirmationPrompt, GenericInputPrompt, NewFileActions, Prompt } from "./dialogs/Prompt";
import { ClipboardData } from "@zsviczian/excalidraw/types/clipboard";
import { updateEquation } from "./LaTeX";
import {
@@ -778,7 +779,14 @@ export default class ExcalidrawView extends TextFileView {
el.addClass(SHOW);
el = el.parentElement;
}
if(el) el.addClass(SHOW);
if(el) {
el.addClass(SHOW);
el.querySelectorAll(`div.workspace-split:not(.${SHOW})`).forEach(el=>el.addClass(SHOW));
el.querySelector(`div.workspace-leaf-content.${SHOW} > .view-header`).addClass(SHOW);
el.querySelectorAll(`div.workspace-tab-container.${SHOW} > div.workspace-leaf:not(.${SHOW})`).forEach(el=>el.addClass(SHOW));
el.querySelectorAll(`div.workspace-tabs.${SHOW} > div.workspace-tab-header-container`).forEach(el=>el.addClass(SHOW));
el.querySelectorAll(`div.workspace-split.${SHOW} > div.workspace-tabs:not(.${SHOW})`).forEach(el=>el.addClass(SHOW));
}
const doc = this.ownerDocument;
doc.body.querySelectorAll(`div.workspace-split:not(.${SHOW})`).forEach(el=>el.addClass(HIDE));
doc.body.querySelector(`div.workspace-leaf-content.${SHOW} > .view-header`).addClass(HIDE);
@@ -991,22 +999,28 @@ export default class ExcalidrawView extends TextFileView {
ef.file.extension === "md" &&
!this.plugin.isExcalidrawFile(ef.file)
) {
const prompt = new Prompt(
app,
"Customize the link",
ef.linkParts.original,
"",
"Do not add [[square brackets]] around the filename!<br>Follow this format when editing your link:<br><mark>filename#^blockref|WIDTHxMAXHEIGHT</mark>",
);
prompt.openAndGetValue(async (link: string) => {
const handler = async (link:string) => {
if (!link || ef.linkParts.original === link) {
return;
}
ef.resetImage(this.file.path, link);
this.setDirty(2);
await this.save(false);
await this.loadSceneFiles();
this.setDirty(2);
});
}
GenericInputPrompt.Prompt(
this,
this.plugin,
app,
"Customize the link",
undefined,
ef.linkParts.original,
[{caption: "✅", action: handler}],
1,
false,
(container) => container.createEl("p",{text: fragWithHTML("Do not add [[square brackets]] around the filename!<br>Follow this format when editing your link:<br><mark>filename#^blockref|WIDTHxMAXHEIGHT</mark>")}),
false
).then(handler, () => {});
return;
}
}
@@ -3769,7 +3783,7 @@ export default class ExcalidrawView extends TextFileView {
}
},
iframeURLWhitelist: [/.*/],
iframeURLWhitelist: [true],
renderCustomIFrame: (
element: NonDeletedExcalidrawElement,
radius: number,

View File

@@ -2,7 +2,7 @@ import { NonDeletedExcalidrawElement } from "@zsviczian/excalidraw/types/element
import ExcalidrawView from "./ExcalidrawView";
import { Notice, Workspace, WorkspaceLeaf, WorkspaceSplit } from "obsidian";
import * as React from "react";
import { getParentOfClass, isObsidianThemeDark } from "./utils/ObsidianUtils";
import { ConstructableWorkspaceSplit, getContainerForDocument, getParentOfClass, isObsidianThemeDark } from "./utils/ObsidianUtils";
import { getLinkParts } from "./utils/Utils";
import { DEVICE, REG_LINKINDEX_INVALIDCHARS } from "./Constants";
import { ExcalidrawImperativeAPI, UIAppState } from "@zsviczian/excalidraw/types/types";
@@ -58,17 +58,6 @@ const VIMEO_REG =
/^(?:http(?:s)?:\/\/)?(?:(?:w){3}.)?(?:player\.)?vimeo\.com\/(?:video\/)?([^?\s]+)(?:\?.*)?$/;
const TWITTER_REG = /^(?:http(?:s)?:\/\/)?(?:(?:w){3}.)?twitter.com/;
type ConstructableWorkspaceSplit = new (ws: Workspace, dir: "horizontal"|"vertical") => WorkspaceSplit;
const getContainerForDocument = (doc:Document) => {
if (doc !== document && app.workspace.floatingSplit) {
for (const container of app.workspace.floatingSplit.children) {
if (container.doc === doc) return container;
}
}
return app.workspace.rootSplit;
};
export const useDefaultExcalidrawFrame = (element: NonDeletedExcalidrawElement) => {
return element.link.match(YOUTUBE_REG) || element.link.match(VIMEO_REG);
}
@@ -226,6 +215,8 @@ function RenderObsidianView(
return;
}
leafRef.current.view.setMode(modes['source']);
//@ts-ignore
window.al = leafRef.current;
app.workspace.setActiveLeaf(leafRef.current);
isEditingRef.current = true;
patchMobileView();
@@ -309,22 +300,6 @@ export const CustomIFrame: React.FC<{element: NonDeletedExcalidrawElement; radiu
view={view}
containerRef={containerRef}
appState={appState}/>
{(appState.activeIFrame?.element === element && appState.activeIFrame?.state === "hover") && (<div
style={{
content: "",
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 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>
)
}

View File

@@ -192,12 +192,15 @@ export class UniversalInsertFileModal extends Modal {
.setButtonText("as Image")
.onClick(async () => {
const ea:ExcalidrawAutomate = getEA(this.view);
const isMarkdown = file && file.extension === "md" && !ea.isExcalidrawFile(file);
ea.selectElementsInView(
[await insertImageToView (
ea,
this.center,
//this.view.currentPosition,
file,
isMarkdown && sectionPicker.selectEl.value && sectionPicker.selectEl.value !== ""
? `${file.path}${sectionPicker.selectEl.value}`
: file,
ea.isExcalidrawFile(file) ? !anchorTo100 : undefined,
)]
);

View File

@@ -100,6 +100,7 @@ export default {
CACHE_NOT_READY: "I am sorry, but there was an error loading your file. The plugin has a backup cache, but it looks like as if you've just started Obsidian. Initialization of the Backup Cache " +
"can take up to a minute (or more depending on your device). You will be notified when the cache initialization is completed." +
"<br><br>Press OK to try again, or Cancel to manually correct your file or to come back later.",
OBSIDIAN_TOOLS_PANEL: "Obsidian Tools Panel",
//settings.ts
RELEASE_NOTES_NAME: "Display Release Notes after update",

View File

@@ -10,6 +10,7 @@ import { PENS } from "src/utils/Pens";
import ExcalidrawPlugin from "../main";
import { ICONS, penIcon, stringToSVG } from "./ActionIcons";
import { UniversalInsertFileModal } from "src/dialogs/UniversalInsertFileModal";
import { t } from "src/lang/helpers";
declare const PLUGIN_VERSION:string;
@@ -251,7 +252,7 @@ export class ObsidianMenu {
);
}}
>
<div className="ToolIcon__icon" aria-hidden="true">
<div className="ToolIcon__icon" aria-label={t("OBSIDIAN_TOOLS_PANEL")}>
{ICONS.obsidian}
</div>
</label>
@@ -268,7 +269,7 @@ export class ObsidianMenu {
insertFileModal.open();
}}
>
<div className="ToolIcon__icon" aria-hidden="true">
<div className="ToolIcon__icon" aria-label={t("UNIVERSAL_ADD_FILE")}>
{ICONS["add-file"]}
</div>
</label>

View File

@@ -0,0 +1,88 @@
/*
l = app.workspace.activeLeaf
canvas = app.internalPlugins.plugins["canvas"].views.canvas(l)
f = app.vault.getAbstractFileByPath("Daily Notes/2022-03-18 Friday.md")
node = canvas.canvas.createFileNode({pos: {x:0,y:0}, file:f, subpath: "#Work", save: false})
node.setFilePath("Daily Notes/2022-03-18 Friday.md","#Work");
node.render();
container.appendChild(node.contentEl)
*/
import { TFile, WorkspaceLeaf, WorkspaceSplit } from "obsidian";
import ExcalidrawView from "src/ExcalidrawView";
import { getContainerForDocument, ConstructableWorkspaceSplit } from "./ObsidianUtils";
declare module "obsidian" {
interface Workspace {
floatingSplit: any;
}
interface WorkspaceSplit {
containerEl: HTMLDivElement;
}
}
interface ObsidianCanvas {
createFileNode: Function;
removeNode: Function;
}
interface ObsidianCanvasNode {
startEditing: Function;
child: any;
}
export class CanvasNodeFactory {
leaf: WorkspaceLeaf;
canvas: ObsidianCanvas;
nodes = new Map<string, ObsidianCanvasNode>();
constructor(
private view: ExcalidrawView,
) {
}
public async initialize() {
//@ts-ignore
const canvasPlugin = app.internalPlugins.plugins["canvas"];
if(!canvasPlugin._loaded) {
await canvasPlugin.load();
}
const doc = this.view.ownerDocument;
const rootSplit:WorkspaceSplit = new (WorkspaceSplit as ConstructableWorkspaceSplit)(app.workspace, "vertical");
rootSplit.getRoot = () => app.workspace[doc === document ? 'rootSplit' : 'floatingSplit'];
rootSplit.getContainer = () => getContainerForDocument(doc);
this.leaf = app.workspace.createLeafInParent(rootSplit, 0);
this.canvas = canvasPlugin.views.canvas(this.leaf);
}
public createFileNote(file: TFile, subpath: string, containerEl: HTMLDivElement, elementId: string) {
const node = this.canvas.createFileNode({pos: {x:0,y:0}, file, subpath, save: false});
node.setFilePath(file.path,subpath);
node.render();
containerEl.style.background = "var(--background-primary)";
containerEl.appendChild(node.contentEl)
this.nodes.set(elementId, node);
}
public startEditing(elementId: string, theme: string) {
const node = this.nodes.get(elementId);
if(!node) return;
node.startEditing();
node.child.editor.containerEl.parentElement.parentElement.removeClass("theme-light");
node.child.editor.containerEl.parentElement.parentElement.removeClass("theme-dark");
node.child.editor.containerEl.parentElement.parentElement.addClass(theme);
}
public stopEditing(elementId: string) {
}
public purgeNodes() {
this.nodes.forEach(node => {
this.canvas.removeNode(node);
});
this.nodes.clear();
}
}

View File

@@ -7,7 +7,7 @@ import { ExcalidrawAutomate } from "src/ExcalidrawAutomate";
export const insertImageToView = async (
ea: ExcalidrawAutomate,
position: { x: number, y: number },
file: TFile,
file: TFile | string,
scale?: boolean,
):Promise<string> => {
ea.clear();

View File

@@ -1,7 +1,7 @@
import { main } from "@popperjs/core";
import {
App,
normalizePath, Notice, WorkspaceLeaf
normalizePath, Notice, Workspace, WorkspaceLeaf, WorkspaceSplit
} from "obsidian";
import { DEVICE } from "src/Constants";
import ExcalidrawPlugin from "../main";
@@ -189,3 +189,14 @@ export const getAttachmentsFolderAndFilePath = async (
};
export const isObsidianThemeDark = () => document.body.classList.contains("theme-dark");
export type ConstructableWorkspaceSplit = new (ws: Workspace, dir: "horizontal"|"vertical") => WorkspaceSplit;
export const getContainerForDocument = (doc:Document) => {
if (doc !== document && app.workspace.floatingSplit) {
for (const container of app.workspace.floatingSplit.children) {
if (container.doc === doc) return container;
}
}
return app.workspace.rootSplit;
};