if people did weird room ids with non-url-safe chars like
`blah/whatever` it wouldn't work. this fixes that
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with…
An example of how to subscribe to values in the store and run side
effects using reactors.
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Added an example that shows how to use track, useValue and useReactor
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
As discussed in #4135 I'm doing a quick follow up to help me sleep at
night.
Sorry sorry sorry sorry
![Kapture 2024-07-12 at 12 47
45](https://github.com/user-attachments/assets/ee9babf0-6b7e-4ddb-a427-5aef9436f922)
i couldn't figure out the magic overlay css so I reverted to ugly static
toolbar. again so sorry
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with…
Move our bemo playground from dotcom to the examples app. In preparation
for more multiplayer examples, I built our a little bit of chrome around
example room IDs: if you create an example with `multiplayer: true`, the
examples app will render a little room ID picker above your example. The
room IDs are scoped to each example, and each deploy of the examples
app. By default people on the same example will be in the same room, but
the default ID changes every hour.
As I was doing this, I noticed you could get an ugly situation where the
docs site was in dark mode, tldraw was in dark mode, but the little bit
of examples chrome was in light mode. To fix this I through together an
extremely rough dark mode for the examples which switches on whenever
the tldraw instance inside is in dark mode.
### Change type
- [x] `other`
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
An example of how to make a shape with custom geometry. It's a house.
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Added an example for creating a shape with custom geometry
Unify the VS Code extension menus with what we have on dot com. Prevent
an error cycle.
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Release notes
- Unify the VS Code extension menus (Help and Main menus) with what we
have on tldraw.com
- Prevent an onerror cycle.
Sets up worker analytics. No further grafana setup needed, just need to
start querying once this is live.
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with…
two changes in one here because I'm feeling lazy
- fix bug in staging, introduced in whichever bemo PR refactored the
sync client+indexeddb stuff
1. go to `/`
2. file -> new shared project
3. oh_no.jpg
<img width="618" alt="image"
src="https://github.com/tldraw/tldraw/assets/1242537/8bff3498-2cc5-4c71-b407-830d459d3d36">
- fix bug in production
1. make a new room
2. clear localstorage
3. refresh
4. duplicate current tab in same browser context
6. oh_no.jpg (there should only be one person)
<img width="99" alt="image"
src="https://github.com/tldraw/tldraw/assets/1242537/f4e434ba-8455-4913-a698-71661e5074fd">
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
8.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with…
I tested this by adding a custom shape on the bemo example page, it
works 👍🏼
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with…
For non-commercial usage of tldraw, this adds a watermark in the corner,
both for branding purposes and as an incentive for our enterprise
customers to purchase a license.
For commercial usage of tldraw, you add a license to the `<Tldraw
licenseKey={YOUR_LICENSE_KEY} />` component so that the watermark
doesn't show.
The license is a signed key that has various bits of information in it,
such as:
- license type
- hosts that the license is valid for
- whether it's an internal-only license
- expiry date
We check the license on load and show a watermark (or throw an error if
internal-only) if the license is not valid in a production environment.
This is a @MitjaBezensek, @Taha-Hassan-Git, @mimecuvalo joint
production! 🤜🤛
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `bugfix` — Bug fix
- [x] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
### Test Plan
1. We will be dogfooding on staging.tldraw.com and tldraw.com itself
before releasing this.
### Release Notes
- SDK: wires up tldraw to have licensing mechanisms.
---------
Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com>
Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com>
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR fixes a bug where a shape created with dynamic size would
preserve the origin
### Change type
- [x] `bugfix`
### Test plan
1. Turn on dynamic size
2. Zoom in
3. Create a text shape
4. Give a label
5. Try to resize the shape to be narrow
### Release notes
- Fixed a bug with the minimum size on dynamically scaled text shapes
Renames `@tldraw/sync` to `@tldraw/sync-core`, and `@tldraw/sync-react`
to `@tldraw/sync`. This also adds an export * from sync-core to sync.
- [x] `other`
Adds a new `multiplayerStatus` store prop. This can either be `null`
(indicating this isn't a multiplayer store) or a signal containing
`online` or `offline` indicating that it is. We move a bunch of
previously dotcom specific UI into `tldraw` and use this new prop to
turn it on or off by default.
closes TLD-2611
### Change type
- [x] `improvement`
Adds a new `onEditorMount` callback to the store, allowing store
creators to do things like registering bookmark handlers. We use this in
the new demo hook.
This also renames `useRemoteSyncClient` to `useMultiplayerSync`, and
`useRemoteSyncDemo` to `useMultiplayerDemo`.
Closes TLD-2601
### Change type
- [x] `api`
Reworks the store to include information about how blob assets
(images/videos) are stored/retrieved. This replaces the old
internal-only `assetOptions` prop, and supplements the existing
`registerExternalAssetHandler` API.
Previously, `registerExternalAssetHandler` had two responsibilities:
1. Extracting asset metadata
2. Uploading the asset and returning its URL
Existing `registerExternalAssetHandler` implementation will still work,
but now uploading is the responsibility of a new `editor.uploadAsset`
method which calls the new store-based upload method. Our default asset
handlers extract metadata, then call that new API. I think this is a
pretty big improvement over what we had before: overriding uploads was a
pretty common ask, but doing so meant having to copy paste our metadata
extraction which felt pretty fragile. Just in this codebase, we had a
bunch of very slightly different metadata extraction code-paths that had
been copy-pasted around then diverged over time. Now, you can change how
uploads work without having to mess with metadata extraction and
vice-versa.
As part of this we also:
1. merge the old separate asset indexeddb store with the main one.
because this warrants some pretty big migration stuff, i refactored our
indexed-db helpers to work around an instance instead of being free
functions
2. move our existing asset stuff over to the new approach
3. add a new hook in `sync-react` to create a demo store with the new
assets
### Change type
- [x] `api`
### Release notes
Introduce a new `assets` option for the store, describing how to save
and retrieve asset blobs like images & videos from e.g. a user-content
CDN. These are accessible through `editor.uploadAsset` and
`editor.resolveAssetUrl`. This supplements the existing
`registerExternalAssetHandler` API: `registerExternalAssetHandler` is
for customising metadata extraction, and should call
`editor.uploadAsset` to save assets. Existing
`registerExternalAssetHandler` calls will still work, but if you're only
using them to configure uploads and don't want to customise metadata
extraction, consider switching to the new `assets` store prop.
Previously, we had a single hard-coded DOM ID for grids. This meant that
if you had multiple editors with grids on a page, they would all point
at the svg `<defs>` from the first instance. Now, each grid generates a
unique ID.
### Change type
- [x] `bugfix`
### Release notes
- Fix a bug causing multiple tldraw instances to share the same grid
background
This has been something we've been asked about 3-4 times on the discord
so far. So here is an example to point people towards in the future.
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- [examples app] added an example of how to export the page as an image
Allow us to preview docs + examples changes on staging.tldraw.dev. Also
allow previewing the docs app on phones in local dev.
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
Looks like some leftovers since we are conditionally doing the same
thing on the next line. I might be missing something though.
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Release notes
- Remove some duplicate code which should make some of the exports a bit
smaller.
This icon went missing. I had a larger diff here that made the icon
types stricter to catch errors but I'll save it for another PR.
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with…
Adds toasts for cases when the file type is not allowed or the file is
too big.
Resolves
https://github.com/orgs/tldraw/projects/53?pane=issue&itemId=70298205
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Upload a file that is either too big (over 10mb) or of incorrect file
type (pdf, docx,...).
2. You should see a toast explaining what went wrong.
### Release notes
- Show a toast when uploading an unsupported file type or a file that is
too large (more than 10mb).
This PR adds the ability to flip images.
### Change type
- [x] `improvement`
### Test plan
1. Resize an image shape
2. Select an image shape and use the flip X / flip Y options in the
context menu.
- [x] Unit tests
### Release notes
- Adds the ability to flip images.
This PR fixes the paste at point logic.
### Change type
- [x] `bugfix`
### Test plan
1. copy, paste (in original position)
2. hold shift to paste at cursor
3. turn on paste at cursor mode
4. copy, paste (at cursor)
5. hold shift to paste in original position
GET requests to the same origin don't send the `origin` headers. in
other situations we care about (CORS requests) we want to block unknown
origins, but if the origin header is missing it's probably because this
is a same-origin request, so we should allow it. Fixes an issue loading
bookmarks on mobile devices
### Change type
- [x] `bugfix`
Add an option to make paste at cursor the default.
Not sure if we also want to expose this on tldraw.com? For now I did,
but happy to remove if we'd want to keep the preferences simple.
We could also add this to the `TldrawOptions`, but it felt like some
apps might actually allow this customization on a per user level.
Solves https://github.com/tldraw/tldraw/issues/4066
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Copy / pasting should still work as it works now: `⌘ + v` pastes on
top of the shape, `⌘ + ⇧ + v` pastes at cursor.
2. There's now a new option under Preferences to paste at cursor. This
just swaps the logic between the two shortcuts: `⌘ + v` then pastes at
cursor and `⌘ + ⇧ + v` pastes on top of the shape.
### Release notes
- Allow users and sdk users to make pasting at the cursor a default
instead of only being available with `⌘ + ⇧ + v`.
Fixes asset loading/processing on staging/previews by introducing a new
image processing worker. This worker acts as a proxy for our various
image hosts and resizes/optimizes/caches images on the fly. Like the old
bookmark worker, this one is deployed in an ad-hoc fashion as it works
across environments and we're not likely to change it often.
### Change type
- [x] `other`
This PR just adds a thing to set the bemo URL during build. No bemo
example page yet
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [x] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with...
this was a very minor oversight when doing the bindings work. It won't
have caused any bugs for anyone but conceptually this should be
`retroactive: false`
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with...
Currently, the editor gets recreated whenever the camera options (or
several other props that are only relevant at initialisation time) get
changed.
This diff makes it so that:
- init-only props are kept in a ref so they don't invalidate the editor
(but are used when the editor _does_ get recreated)
- camera options are kept up to date in a separate effect
### Change type
- [x] `bugfix`
### Release notes
Fix an issue where changing `cameraOptions` via react would cause the
entire editor to re-render
Improves share menu:
* Seems like we lost the logic of opening the share menu after sharing a
project.
* Using `/new` did open the share menu after creating a new room, but
the qr code flickered. This was because the create project action
created a new room but there were no search params set (for viewport and
page). So we first created the qr code for that url, but then we update
the url with those params and regenerate the qr code which caused the
flicker. That said the current logic does show a gray box a bit longer,
so not sure how much of an improvement this is.
### Before
https://github.com/tldraw/tldraw/assets/2523721/cdb4e3b8-46cb-48d9-bd23-66b2f4f55cff
### After
https://github.com/tldraw/tldraw/assets/2523721/f035bd48-6e59-4d3d-8e04-640c866c9395
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Share a local room. The share menu should be open after the redirect.
1. Use the `/new` route. The qr code in the share menu should not
flicker.
### Release notes
- Make sure the share menu is open after sharing a room. Prevent the qr
code from flickering when navigating to `/new`
This PR adds a component for `ShapeIndicators` to the UI component
overrides. It moves the "select tool" state logic up to the new
`TldrawShapeIndicators` component.
### Change type
- [ ] `bugfix`
- [x] `improvement`
- [ ] `feature`
- [x] `api`
- [ ] `other`
### Release notes
- Added new `ShapeIndicators` component to `components` object.
- Added new `TldrawShapeIndicators` component.
this PR puts sync stuff in the bemo worker, and sets up a temporary
dev-only page in dotcom for testing bemo stuff
### Change type
- [ ] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with...
This adds the HTMLRewriter-based bookmark unfurler to the demo server.
It moves the unfurler into worker-shared, and adds some better shared
error handling across our workers.
I removed the fallback bookmark fetcher where we try and fetch websites
locally. This will almost never work, as it requires sites to set public
CORS.
### Change type
- [x] `other`
In dev mode you get the below error when visiting the `/new` route. The
route seems to be hit several times before finally navigating to the
correct room. This seems to solve it.
![image](https://github.com/tldraw/tldraw/assets/2523721/cbc4a6ef-9168-414f-b07a-b4d6af6d7256)
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Release notes
- Fixed a but with navigating to `/new`.
Adds an assets server to the demo worker, and reworks the existing asset
server to use the same code. There are a few simplifications to the code
due to some DX improvements working with R2 and caches. I also removed
the `HEAD` request from the assets server: i took a look at our logs and
it's not actually used at all.
This also fixes an issue where users could overwrite the contents of the
asset uploads bucket.
### Change type
- [x] `other`
Describe what your pull request does. If you can, add GIFs or images
showing the before and after of your change.
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Test plan
1. Create a shape...
2.
- [ ] Unit tests
- [ ] End to end tests
### Release notes
- Fixed a bug with...
---------
Co-authored-by: alex <alex@dytry.ch>
This is a more surgical fix while these other diffs are being hashed
out: https://github.com/tldraw/tldraw/pull/4045 and
https://github.com/tldraw/tldraw/pull/4048
Problem was that we always waited a minimum of 500ms and we really
should have a `leading: true` to our debounce.
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`
### Release notes
- Assets: fix artificial delay in showing an image.
This PR fixes the distance between duplicated shapes to match the
editor.options.adjacentPositions value.
### Change type
- [x] `bugfix`
### Release notes
- Fixed a bug that caused the distance offset for duplicated shapes to
not match other duplication distance offsets.
This PR adds a `GET /api/unfurl?url=blahblah` endpoint to our worker.
I tried out the existing cheerio implementation but it added 300kb to
our worker bundle in the end, due to transitive dependencies.
So I implemented the same logic with cloudflare's sanctioned streaming
HTML parser `HTMLRewriter` and it seems to work fine.
I also made the vscode extension do its fetching locally (from the node
process so it's not bound by security policies), retaining the cheerio
version for that. At the same time I fixed a bug in the RPC layer that
was preventing unfurled metadata from loading correctly.
In a few months we can retire the bookmark-extractor app by just
deleting it in the vercel dashboard.
### Change Type
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `feature` — New feature
- [x] `improvement` — Product improvement
- [ ] `api` — API change
- [ ] `bugfix` — Bug fix
- [ ] `other` — Changes that don't affect SDK users, e.g. internal or
.com changes
### Test Plan
1. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Do link unfurling on the same subdomain as all our other api
endpoints.
- Structure wrangler.toml for asset uploads the same way we structure it
for other workers
- Extract worker name from wrangler output, not wrangler.toml - not all
workers have explicit names for all environments
- Remove DNS settings for preview workers - `tldraw.workers.dev` is fine
### Change type
- [x] `bugfix`