Skip to content

Acknowledge .tldraw files from tldraw offline - #211

Merged
frolic merged 4 commits into
mainfrom
frolic/tldraw-offline-messaging
Jul 29, 2026
Merged

Acknowledge .tldraw files from tldraw offline#211
frolic merged 4 commits into
mainfrom
frolic/tldraw-offline-messaging

Conversation

@frolic

@frolic frolic commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

People are saving files out of tldraw offline and trying to open them elsewhere. Those are .tldraw files — archives holding a zipped SQLite database and its assets, rather than the JSON a .tldr file holds — so nothing in this plugin can read one. Until support lands, this recognizes the extension and explains that.

Before this, a .tldraw file in the vault landed on Obsidian's generic "no view for this file type" screen, with nothing to say tldraw was involved.

This only detects the extension — it does no parsing.

The message links to tldraw offline itself and to the export instructions in its user manual, so it points somewhere rather than just saying no. Both are built as nodes by a shared helper: Obsidian's Notice only renders a link when given a fragment rather than a string, and the file view needs the same copy.

The new view extends FileView directly rather than BaseTldrawFileView, which reads the file as text and parses it as JSON; on an archive that just produces an opaque Unable to parse TldrawFile. The view type is deliberately kept out of VIEW_TYPES, since including it would let updateViewMode fall through to setMarkdownView and flip a binary file into the markdown editor.

Claiming the extension takes away Obsidian's own handling for unrecognized files, so the view offers "open in default app" — otherwise opening a .tldraw in the vault would leave the user with no route to a program that can actually read it.

Two things worth flagging in the diff:

  • importTldrawFile now returns undefined instead of throwing when there's nothing to import. None of its three callers had a try/catch, so throwing would have surfaced as an unhandled rejection with no user feedback.
  • The extension check is case-insensitive. File dialogs on macOS and Windows match their filters that way, so Drawing.TLDRAW is selectable and would otherwise have slipped through to the JSON parser.

Not covered: ![[drawing.tldraw]] embeds inside a note still fall through to Obsidian's default handling, since embedRegistry only registers tldr.

Test plan

  1. Save a file from tldraw offline so you have a .tldraw file, and put it in a vault.
  2. Click it in the file explorer — expect "Can't open .tldraw files yet" rather than Obsidian's unknown-file screen.
  3. Use the "Open in default app" action in the tab bar, and the same item in the tab context menu.
  4. Run "Import file as new document and open in a new tab" and pick the .tldraw file — expect a notice, and no unhandled error in the console.
  5. Rename it to .TLDRAW and repeat step 4 — same notice.
  6. Confirm .tldr files still open, import, and embed exactly as before.

frolic added 4 commits July 27, 2026 11:11
tldraw offline saves documents as .tldraw archives — a zipped SQLite
database rather than the JSON a .tldr file holds — so nothing here can
read one. Until support lands, claim the extension and explain that,
rather than leaving the file on Obsidian's generic "no view for this
file type" screen.

importTldrawFile now returns undefined instead of throwing when there is
nothing to import, since none of its callers had a catch to surface an
error with.
File dialogs on macOS and Windows match their filters case-insensitively,
so a .TLDRAW file was selectable, slipped past the guard, and reached the
JSON parser — whose throw no caller catches, leaving the user with no
feedback at all.

Claiming the extension also took away Obsidian's own handling for
unrecognized files, so the view now offers "open in default app" to keep
a route to a program that can read the archive.

Move the strings to constants.ts so utils no longer imports from a view.
Drops "still" from the copy, and links "export as a .tldr file" to the
Export as .tldr section of the tldraw offline user manual, so the view
and the import notice both offer a way forward rather than just a no.

The notice is built as a DocumentFragment because Obsidian's Notice only
renders a link when given nodes rather than a string.
Gives the app a destination as well as the export instructions.

Both links now live in one helper that appends the message as nodes,
rather than a growing set of string fragments in constants.ts split
around each link.
@frolic
frolic marked this pull request as ready for review July 29, 2026 09:27
@frolic
frolic merged commit 36bdf39 into main Jul 29, 2026
1 check passed
@frolic
frolic deleted the frolic/tldraw-offline-messaging branch July 29, 2026 09:29
@frolic frolic mentioned this pull request Jul 29, 2026
frolic added a commit that referenced this pull request Jul 29, 2026
Bumps the version so 1.30.0 can be released to everyone, rather than
only to BRAT users as `1.30.0-alpha.1` was.

What ships in it:

- **tldraw 5.2.5** (#212), so `.tldr` files saved by a current version
of tldraw open instead of failing with `Incompatible schema?` and an
empty tab — likely closing #184, #138, and the "corrupted file" report
on #193
- **`.tldraw` messaging** (#211): opening one from tldraw offline
explains why it can't be opened yet and links to the export
instructions, rather than landing on Obsidian's unknown-file screen
- the e2e suite now running in CI (#214) and a one-click release (#215)

`npm version` cascades the version into `release/manifest.json` and
`release/versions.json` on its own — the repo has a `version` lifecycle
script — so those changes are mechanical.

### One thing that isn't mechanical

This drops a `"1.29.1"` entry from `release/versions.json`. That version
was staged in b48442c and never released — there's no tag and no GitHub
release for it. It matters here because releasing a non-prerelease
copies `release/versions.json` over the root `versions.json`, which is
the file the plugin registry reads, so the phantom entry would have been
published. Everything in that file shares the same `minAppVersion`, so
it was unlikely to misresolve anyone's install, but it shouldn't go out
either way.

After this, `release/versions.json` matches the published file exactly
apart from the new `1.30.0` line.

### Release plan

Merge, then Actions → Manual Release → Run workflow with `ref: main`.
Unlike the alpha, this path adds the `versions.json` entry and pushes
the manifest commit back, which is what makes it visible to everyone on
the community plugin list.

### Worth knowing before merging

`1.30.0-alpha.1` was published but, as far as I know, never installed
and exercised through BRAT. So the evidence behind this release is the
CI suite (8 behaviours, including opening a current `.tldr`, the theme,
the edit round trip, view mode and embeds) plus manual checks in a
scratch vault — not a soak on a real vault. Mobile is untested by
anything.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant