Skip to content

Commit

Permalink
Merge from jon-dez/main
Browse files Browse the repository at this point in the history
  • Loading branch information
jon-dez committed Aug 26, 2024
2 parents e0fe7ca + 5bfb359 commit e3e48e9
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 52 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/manual-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# This is a basic workflow that is manually triggered

name: Manual workflow

# Controls when the action will run. Workflow runs when manually triggered using the UI
# or API.
on:
workflow_dispatch:
# Inputs the workflow accepts.
inputs:
tag:
# Friendly description to be shown in the UI instead of 'name'
description: 'Existing tag to create release from.'
# Default value if no value is explicitly provided
default: '0.0.0'
# Input has to be provided for the workflow to run
required: true
# The data type of the input
type: string

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: "18.x"

- name: Build plugin
run: |
npm install
npm run dist
- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag="${{inputs.tag}}"
gh release create "$tag" \
--title="$tag" \
--draft \
main.js manifest.json styles.css
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "tldraw",
"name": "Tldraw",
"version": "1.2.0",
"version": "1.3.0",
"minAppVersion": "0.15.0",
"description": "Integrates Tldraw into Obsidian, allowing users to draw and edit content on a virtual whiteboard.",
"author": "Sam Alhaqab",
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"esbuild": "0.17.3",
"obsidian": "latest",
"tslib": "2.6.3",
"typescript": "5.4.5"
"typescript": "^5.5.4"
},
"dependencies": {
"@tldraw/tldraw": "2.4.4",
Expand Down
24 changes: 23 additions & 1 deletion src/components/TldrawApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createRoot } from "react-dom/client";
import {
DefaultMainMenu,
DefaultMainMenuContent,
Editor,
TLComponents,
TLStore,
Tldraw,
Expand All @@ -26,6 +27,12 @@ import { createRawTldrawFile } from "src/utils/tldraw-file";
type TldrawAppOptions = {
isReadonly?: boolean,
autoFocus?: boolean,
inputFocus?: boolean,
hideUi?: boolean,
/**
* Whether to call `.selectNone` on the Tldraw editor instance when it is mounted.
*/
selectNone?: boolean,
/**
* Whether or not to initially zoom to the bounds of the document when the component is mounted.
*/
Expand Down Expand Up @@ -68,7 +75,10 @@ function LocalFileMenu() {

const TldrawApp = ({ settings, initialData, setFileData, options: {
autoFocus = true,
hideUi = false,
inputFocus = false,
isReadonly = false,
selectNone = false,
zoomToBounds = false,
defaultFontOverrides
} }: TldrawAppProps) => {
Expand Down Expand Up @@ -114,26 +124,38 @@ const TldrawApp = ({ settings, initialData, setFileData, options: {
};
}, [store]);

const editorRef = React.useRef<Editor | null>(null);
return (
<div
id="tldraw-view-root"
className="tldraw-view-root"
// e.stopPropagation(); this line should solve the mobile swipe menus bug
// The bug only happens on the mobile version of Obsidian.
// When a user tries to interact with the tldraw canvas,
// Obsidian thinks they're swiping down, left, or right so it opens various menus.
// By preventing the event from propagating, we can prevent those actions menus from opening.
onTouchStart={(e) => e.stopPropagation()}
onBlur={!inputFocus ? undefined : () => {
editorRef.current?.selectNone()
editorRef.current?.blur()
}}
onFocus={!inputFocus ? undefined : () => editorRef.current?.focus()}
>
<Tldraw
assetUrls={{
fonts: defaultFontOverrides
}}
hideUi={hideUi}
overrides={uiOverrides}
store={store}
components={components}
// Set this flag to false when a tldraw document is embed into markdown to prevent it from gaining focus when it is loaded.
autoFocus={autoFocus}
onMount={(editor) => {
editorRef.current = editor;
if(selectNone) {
editor.selectNone();
}

const {
themeMode,
gridMode,
Expand Down
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ export default class TldrawPlugin extends Plugin {
return await this.createTldrFile(res.filename, res.folder);
};

public openTldrFile = async (file: TFile, location: PaneTarget) => {
public openTldrFile = async (file: TFile, location: PaneTarget, viewType: ViewType = VIEW_TYPE_TLDRAW) => {
let leaf: WorkspaceLeaf;

if (location === "current-tab")
Expand All @@ -472,7 +472,7 @@ export default class TldrawPlugin extends Plugin {
else leaf = this.app.workspace.getLeaf(false);

await leaf.openFile(file);
await this.updateViewMode(VIEW_TYPE_TLDRAW, leaf);
await this.updateViewMode(viewType, leaf);
};

public createAndOpenUntitledTldrFile = async (location: PaneTarget) => {
Expand Down
140 changes: 101 additions & 39 deletions src/obsidian/plugin/markdown-post-processor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MarkdownPostProcessorContext, TFile } from "obsidian";
import { ButtonComponent, MarkdownPostProcessorContext, MarkdownView, TFile } from "obsidian";
import { createRootAndRenderTldrawApp } from "src/components/TldrawApp";
import TldrawPlugin from "src/main";
import { MARKDOWN_ICON_NAME, TLDRAW_ICON_NAME } from "src/utils/constants";
import { CustomMutationObserver } from "src/utils/debug-mutation-observer";
import { ConsoleLogParams, LOGGING_ENABLED, logFn } from "src/utils/logging";
import { parseTLDataDocument } from "src/utils/parse";
Expand Down Expand Up @@ -90,61 +91,30 @@ export async function markdownPostProcessor(plugin: TldrawPlugin, element: HTMLE

internalEmbedDiv.empty()

internalEmbedDiv.addClass('tldraw-markdown-view');

if (markdownEmbed) {
const tldrawViewHeader = internalEmbedDiv.createDiv({
cls: ['tldraw-view-header'],
});

tldrawViewHeader.style.display = 'flex';
tldrawViewHeader.style.justifyContent = 'space-between';
tldrawViewHeader.style.alignItems = 'baseline';

const tldrawTitle = tldrawViewHeader.createDiv({
cls: ['embed-title', 'markdown-embed-title']
})

tldrawTitle.innerText = file.name;

tldrawViewHeader.createEl('button', {
cls: ['clickable'],
text: 'Edit',
}, (el) => {
el.addEventListener('click', async (ev) => {
plugin.openTldrFile(file, 'new-tab')
})
});

internalEmbedDiv.removeClass("markdown-embed");
internalEmbedDiv.removeClass("inline-embed");
// TODO: Uncomment later when added prerendered tldraw view support.
// internalEmbedDiv.addClass("media-embed");
// internalEmbedDiv.addClass("image-embed");
}

const tldrawViewContent = internalEmbedDiv.createDiv({
cls: ['tldraw-view-content'],
}, (el) => {
el.style.height = '300px';
// Prevent the Obsidian editor from selecting the embed link with the editing cursor when a user interacts with the view.
el.addEventListener('click', (ev) => ev.stopPropagation());
el.addEventListener('focus', function tldrawFocusListener() {
log(`${tldrawFocusListener.name}`)
});
const tldrawEmbedView = createTldrawEmbedView(internalEmbedDiv, {
file, plugin
});

const tldrawEmbedViewContent = tldrawEmbedView.createDiv({
cls: 'ptl-view-content'
})

const parent = internalEmbedDiv.parentElement;

if (parent === null) throw Error(`${markdownPostProcessor.name}: No parent element for internalEmbedDiv.\n\n\tIt is needed to ensure the attached react root component is unmounted properly.`);

const fileData = await plugin.app.vault.read(file);
const parsedData = parseTLDataDocument(plugin.manifest.version, fileData);
log('tldrawViewContent', tldrawViewContent);
log('parsedData', parsedData);

const reactRoot = createRootAndRenderTldrawApp(tldrawViewContent,
const reactRoot = createRootAndRenderTldrawApp(tldrawEmbedViewContent,
parsedData,
(_) => {
console.log('Ignore saving file due to read only mode.');
Expand All @@ -153,8 +123,11 @@ export async function markdownPostProcessor(plugin: TldrawPlugin, element: HTMLE
{
isReadonly: true,
autoFocus: false,
inputFocus: true,
selectNone: true,
hideUi: true,
zoomToBounds: true,
defaultFontOverrides: plugin.getFontOverrides(),
defaultFontOverrides: plugin.getFontOverrides()
}
);

Expand Down Expand Up @@ -202,3 +175,92 @@ export async function markdownPostProcessor(plugin: TldrawPlugin, element: HTMLE
}
throw new Error(`${markdownPostProcessor.name}: Unexpected`);
}


function createTldrawViewHeader(embedViewContent: HTMLElement, {
file, plugin, selectEmbedText
}: {
file: TFile,
plugin: TldrawPlugin,
selectEmbedText: (ev: MouseEvent) => void
}) {
const tldrawViewHeader = embedViewContent.createDiv({
cls: ['ptl-embed-context-bar'],
});

const tldrawTitle = tldrawViewHeader.createDiv({
cls: ['ptl-embed-title-bar']
}, (el) => {
el.onClickEvent((ev) => {
selectEmbedText(ev);
ev.stopPropagation();
})
})

tldrawTitle.innerText = file.name;

const actionBar = tldrawViewHeader.createDiv({ cls: 'ptl-embed-action-bar' })

new ButtonComponent(actionBar)
.setClass('clickable-icon')
.setIcon(MARKDOWN_ICON_NAME)
.setTooltip('Open as markdown').onClick(() => {
plugin.openTldrFile(file, 'new-tab', 'markdown')
});

new ButtonComponent(actionBar)
.setClass('clickable-icon')
.setIcon(TLDRAW_ICON_NAME)
.setTooltip('Edit').onClick(() => {
plugin.openTldrFile(file, 'new-tab')
});

new ButtonComponent(actionBar)
.setClass('clickable-icon')
.setIcon('view')
.setTooltip('Read-only view').onClick((ev) => {
plugin.openTldrFile(file, 'new-tab', 'tldraw-read-only')
});

return tldrawViewHeader;
}

function createTldrawEmbedView(internalEmbedDiv: HTMLElement, {
file, plugin
}: {
file: TFile,
plugin: TldrawPlugin,
}) {
return internalEmbedDiv.createDiv({
cls: 'ptl-markdown-embed'
}, (el) => {
const viewHeader = createTldrawViewHeader(el, {
file, plugin,
selectEmbedText: (ev) => {
internalEmbedDiv.dispatchEvent(new MouseEvent('click', {
bubbles: ev.bubbles,
cancelable: ev.cancelable,
clientX: ev.clientX,
clientY: ev.clientY
}))
}
})

// Prevent the Obsidian editor from selecting the embed link with the editing cursor when a user interacts with the view.
el.addEventListener('click', (ev) => ev.stopPropagation());

viewHeader.hide();

internalEmbedDiv.addEventListener('focusin', () => {
plugin.app.workspace.getActiveViewOfType(MarkdownView)?.editor.setCursor(0, 0)
viewHeader.show();
})

internalEmbedDiv.addEventListener('focusout', (event) => {
if (event.relatedTarget instanceof Node && internalEmbedDiv.contains(event.relatedTarget)) {
return;
}
viewHeader.hide();
})
})
}
Loading

0 comments on commit e3e48e9

Please sign in to comment.