This PR:
- creates `Editor.run` (previously `Editor.batch`)
- deprecates `Editor.batch`
- introduces a `ignoreShapeLock` option top the `Editor.run` method that
allows the editor to update and delete locked shapes
- fixes a bug with `updateShapes` that allowed updating locked shapes
- fixes a bug with `ungroupShapes` that allowed ungrouping locked shapes
- makes `Editor.history` private
- adds `Editor.squashToMark`
- adds `Editor.clearHistory`
- removes `History.ignore`
- removes `History.onBatchComplete`
- makes `_updateCurrentPageState` private
```ts
editor.run(() => {
editor.updateShape({ ...myLockedShape })
editor.deleteShape(myLockedShape)
}, { ignoreShapeLock: true })
```
It also:
## How it works
Normally `updateShape`/`updateShapes` and `deleteShape`/`deleteShapes`
do not effect locked shapes.
```ts
const myLockedShape = editor.getShape(myShapeId)!
// no change from update
editor.updateShape({ ...myLockedShape, x: 100 })
expect(editor.getShape(myShapeId)).toMatchObject(myLockedShape)
// no change from delete
editor.deleteShapes([myLockedShape])
expect(editor.getShape(myShapeId)).toMatchObject(myLockedShape)
```
The new `run` method adds the option to ignore shape lock.
```ts
const myLockedShape = editor.getShape(myShapeId)!
// update works
editor.run(() => { editor.updateShape({ ...myLockedShape, x: 100 }) }, { ignoreShapeLock: true })
expect(editor.getShape(myShapeId)).toMatchObject({ ...myLockedShape, x: 100 })
// delete works
editor.run(() => { editor.deleteShapes([myLockedShape]), { ignoreShapeLock: true })
expect(editor.getShape(myShapeId)).toBeUndefined()
```
## History changes
This is a related but not entirely related change in this PR.
Previously, we had a few ways to run code that ignored the history.
- `editor.history.ignore(() => { ... })`
- `editor.batch(() => { ... }, { history: "ignore" })`
- `editor.history.batch(() => { ... }, { history: "ignore" })`
- `editor.updateCurrentPageState(() => { ... }, { history: "ignore" })`
We now have one way to run code that ignores history:
- `editor.run(() => { ... }, { history: "ignore" })`
## Design notes
We want a user to be able to update or delete locked shapes
programmatically.
### Callback vs. method options?
We could have added a `{ force: boolean }` property to the
`updateShapes` / `deleteShapes` methods, however there are places where
those methods are called from other methods (such as
`distributeShapes`). If we wanted to make these work, we would have also
had to provide a `force` option / bag to those methods.
Using a wrapper callback allows for "regular" tldraw editor code to work
while allowing for updates and deletes.
### Interaction logic?
We don't want this change to effect any of our interaction logic.
A lot of our interaction logic depends on identifying which shapes are
locked and which shapes aren't. For example, clicking on a locked shape
will go to the `pointing_canvas` state rather than the `pointing_shape`.
This PR has no effect on that part of the library.
It only effects the updateShapes and deleteShapes methods. As an example
of this, when `_force` is set to true by default, the only tests that
should fail are in `lockedShapes.test.ts`. The "user land" experience of
locked shapes is identical to what it is now.
### Change type
- [x] `bugfix`
- [ ] `improvement`
- [x] `feature`
- [x] `api`
- [ ] `other`
### Test plan
1. Create a shape
2. Lock it
3. From the console, update it
4. From the console, delete it
- [x] Unit tests
### Release notes
- SDK: Adds `Editor.force()` to permit updating / deleting locked shapes
- Fixed a bug that would allow locked shapes to be updated
programmatically
- Fixed a bug that would allow locked group shapes to be ungrouped
programmatically
---------
Co-authored-by: alex <alex@dytry.ch>
We currently serve icons in the form of 141 separate svg files. This is
pretty inefficient: it results in 141 http requests each with its own
overheads and costs. Each one is generally less than 1kb of data.
This PR merges all of our icons into a single 44kb icon file. Each item
in the svg has an ID, and we use the ID in the asset url to target the
specific icon. This also fixes a lot of the icon preloading issues:
because the icon file is already loaded, there's no extra request needed
when panels open etc.
I was messing with this whilst killing time before a late meeting so
made a shitty overengineered code generator, dont at me
### Change type
- [x] `improvement`
### Release notes
- Serve icons more efficiently, and make sure they're still available if
tldraw goes offline.
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>
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>
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.
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`
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 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`.
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.
Sets up preview deploys etc. for bemo worker.
There's enough going on here that I wanted to make it its own PR. I'll
rework david's spike on top of it once it's landed.
### Change Type
- [x] `internal` — Does not affect user-facing stuff
- [x] `chore` — Updating dependencies, other boring stuff
---------
Co-authored-by: David Sheldrick <d.j.sheldrick@gmail.com>
fixes#4033
### Change Type
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `feature` — New feature
- [ ] `improvement` — Product improvement
- [ ] `api` — API change
- [x] `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
- Add a brief release note for your PR here.
This PR:
- simplifies a lot of z-index layers
### Change Type
- [x] `sdk` — Changes the tldraw SDK
- [x] `bugfix` — Bug fix
### Release Notes
- Cleans up z-indexes and removes some unused CSS.
good call out @SomeHats!
### Change Type
<!-- ❗ Please select a 'Type' label ❗️ -->
- [ ] `feature` — New feature
- [ ] `improvement` — Product improvement
- [ ] `api` — API change
- [ ] `bugfix` — Bug fix
- [x] `other` — Changes that don't affect SDK users, e.g. internal or
.com changes
### Release Notes
- CSP: only do report-only for now until we're sure it's ok.
Looking at the waterfall of fonts/images/etc. we wanted the "Loading
assets..." bit to commence earlier so it's not fighting for bandwidth
with the icons loading all at the same time.
This writes to the index.html file to start preloading the fonts we
need.
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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
- [ ] `feature` — New feature
- [x] `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
### Release Notes
- Perf: improve font loading timing on dotcom.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
this is take #2 of this PR https://github.com/tldraw/tldraw/pull/3745
As I look at LOD holistically and whether we have multiple sources when
working locally, I learned that our system used base64 encoding of
assets directly. Issue https://github.com/tldraw/tldraw/issues/3728
<img width="1350" alt="assetstore"
src="https://github.com/tldraw/tldraw/assets/469604/e7b41e29-6656-4d9b-b462-72d43b98f3f7">
The motivations and benefits are:
- store size: not having a huge base64 blobs injected in room data
- perf on loading snapshot: this helps with loading the room data more
quickly
- multiple sources: furthermore, if we do decide to have multiple
sources locally (for each asset), then we won't get a multiplicative
effect of even larger JSON blobs that have lots of base64 data in them
- encoding/decoding perf: this also saves the (slow) step of having to
base64 encode/decode our assets, we can just strictly with work with
blobs.
Todo:
- [x] decodes video and images
- [x] make sure it syncs to other tabs
- [x] make sure it syncs to other multiplayer room
- [x] fix tests
### 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
- [ ] `feature` — New feature
- [x] `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. Test the shit out of uploading/downloading video/image assets,
locally+multiplayer.
- [ ] Need to fix current tests and write new ones
### Release Notes
- Assets: store as reference to blob in indexedDB instead of storing
directly as base64 in the snapshot.
couple fixes and improvements for the LOD work.
- add `format=auto` for Cloudflare to send back more modern image
formats
- fix the broken asset logic that regressed (should not have looked at
`url`)
- fix stray parenthesis, omg
- rm the `useValueDebounced` function in lieu of just debouncing the
resolver. the problem was that the initial load in a multiplayer room
has a zoom of 1 but then the real zoom comes in (via the url) and so we
would double load all images 😬. this switches the debouncing to the
resolving stage, not making it tied to the zoom specifically.
### 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 ❗️ -->
- [x] `bugfix` — Bug fix
- [ ] `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
Before:
![Screenshot 2024-06-12 at 12 57
26](https://github.com/tldraw/tldraw/assets/1489520/2a9f6098-ef2a-4f52-88f5-d6e4311c067d)
After:
![Screenshot 2024-06-12 at 12 59
16](https://github.com/tldraw/tldraw/assets/1489520/51733c2a-a2b4-4084-a89a-85bce5b47672)
React components in docs now list their props, and appear under a new
"Component" section instead of randomly under either `Function` or
`Variable`. In order to have our docs generate this, a few criteria need
to be met:
1. They need to be tagged with the `@react` tsdoc tag
2. Their props need to be a simple type alias, typically to an
interface.
Both of these rules are enforced with a new lint rule - any component
tagged as `@public` will have these rules enforced.
### Change Type
- [x] `docs` — Changes to the documentation, examples, or templates.
- [x] `improvement` — Improving existing features
This PR prevents the document name input becoming editable in Readonly
mode, and also removes the rename menu item from the dropdown.
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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
- [ ] `feature` — New feature
- [x] `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. Open a shared project in read only mode
2. You shouldn't be able to edit the document name by clicking the
input, and the option to rename should not be visible in the dropdown.
### Release Notes
- Remove ability to rename document while in readonly mode
this is take #2 of this PR https://github.com/tldraw/tldraw/pull/3764
This continues the idea kicked off in
https://github.com/tldraw/tldraw/pull/3684 to explore LOD and takes it
in a different direction.
Several things here to call out:
- our dotcom version would start to use Cloudflare's image transforms
- we don't rewrite non-image assets
- we debounce zooming so that we're not swapping out images while
zooming (it creates jank)
- we load different images based on steps of .25 (maybe we want to make
this more, like 0.33). Feels like 0.5 might be a bit too much but we can
play around with it.
- we take into account network connection speed. if you're on 3g, for
example, we have the size of the image.
- dpr is taken into account - in our case, Cloudflare handles it. But if
it wasn't Cloudflare, we could add it to our width equation.
- we use Cloudflare's `fit=scale-down` setting to never scale _up_ an
image.
- we don't swap the image in until we've finished loading it
programatically (to avoid a blank image while it loads)
TODO
- [x] We need to enable Cloudflare's pricing on image transforms btw
@steveruizok 😉 - this won't work quite yet until we do that.
### 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. Test images on staging, small, medium, large, mega
2. Test videos on staging
- [x] Unit Tests
- [ ] End to end tests
### Release Notes
- Assets: make option to transform urls dynamically to provide different
sized images on demand.
followup to https://github.com/tldraw/tldraw/pull/3881 to enforce this
in the codebase
Describe what your pull request does. If appropriate, add GIFs or images
showing the before and after.
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [x] `sdk` — Changes the tldraw SDK
- [x] `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
- [ ] `feature` — New feature
- [x] `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
the fix in https://github.com/tldraw/tldraw/pull/3906 actually made
things worse. the CSP setting was broken from the beginning. i'll rework
it in another PR.
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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 ❗️ -->
- [x] `bugfix` — Bug fix
- [ ] `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
I recently noticed some browser error spam in my
[tldraw-cli](https://github.com/kitschpatrol/tldraw-cli) tool...
```sh
The Content-Security-Policy directive name 'default-src:' contains one or more invalid characters. Only ASCII alphanumeric characters or dashes '-' are allowed in directive names.
```
Also seeing the same on tldraw.com in the browser console:
```sh
Unrecognized Content-Security-Policy directive 'default-src:'.
```
Looks like `'Content-Security-Policy': 'default-src: *'` is not [valid
syntax](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources)
for this header, instead we need 'Content-Security-Policy': 'default-src
*'.
This heroic PR deletes a single `:` character to correct the syntax and
silence the error. 😅
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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 ❗️ -->
- [x] `bugfix` — Bug fix
- [ ] `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. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [x] End to end tests
It could certainly be automated... but I've just been looking at the
browser console.
### Release Notes
- Fix Content-Security-Policy warnings
Previously, we had the `ae-forgotten-export` rule from api-extractor
disabled. This rule makes sure that everything that's referred to in the
public API is actually exported. There are more details on the rule
[here](https://api-extractor.com/pages/messages/ae-forgotten-export/),
but not exporting public API entires is bad because they're hard to
document and can't be typed/called from consumer code. For us, the big
effect is that they don't appear in our docs at all.
This diff re-enables that rule. Now, if you introduce something new to
the public API but don't export it, your build will fail.
### Change Type
- [x] `docs` — Changes to the documentation, examples, or templates.
- [x] `improvement` — Improving existing features
This code has started to bitrot a bit and this freshens it up a bit.
- there's a double request happening for every bookmark paste at the
moment, yikes! One request originates from the paste logic, and the
other originates from the `onBeforeCreate` in `BookmarkShapeUtil`. They
both see that an asset is missing and race to make the request at the
same time. It _seems_ like we don't need the `onBeforeCreate` anymore.
But, if I'm mistaken on some edge case here lemme know and we can
address this in a different way.
- the extractor is really crusty (the grabity code is from 5 yrs ago and
hasn't been updated) and we don't have control over it. i've worked on
unfurling stuff before with Paper and my other projects and this reworks
things to use Cheerio, which is a more robust library.
- this adds `favicon` to the response request which should usually
default to the apple-touch-icon. this helps with some better bookmark
displays (e.g. like Wikipedia if an image is empty)
In general, this'll start to make this more maintainable and improvable
on our end.
Double request:
<img width="1496" alt="Screenshot 2024-05-31 at 17 54 49"
src="https://github.com/tldraw/tldraw/assets/469604/22033170-caaa-4fd2-854f-f19b61611978">
Before:
<img width="355" alt="Screenshot 2024-05-31 at 17 55 02"
src="https://github.com/tldraw/tldraw/assets/469604/fd272669-ee52-4cc7-bed7-72a8ed8d53a0">
After:
<img width="351" alt="Screenshot 2024-05-31 at 17 55 44"
src="https://github.com/tldraw/tldraw/assets/469604/87d27342-0d49-4cfc-a811-356370562d19">
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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 ❗️ -->
- [x] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `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. Test pasting links in, and pasting again.
### Release Notes
- Bookmarks: fix up double request and rework extractor code.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This PR ensures that the share menu is open when navigating from the
create new shared project button.
This could be achieved by calling ```editor.addOpenMenu('share-menu')```
after ```navigate('/new')``` , but that opens the menu on the local
editor first so you get a flash of that before the multiplayer editor
loads.
Instead I've used the state prop on the Navigate component/function to
pass a property called shouldOpenShareMenu.
If the user presses the back button to return to the local editor
instance then the open state of the share menu is preserved, which is
actually something we don't want in this case. Not sure how to deal with
that without adding a ton more complexity, is it worth it?
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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
- [ ] `feature` — New feature
- [x] `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. Click create new shared project from the file menu
2. Share menu should open after navigating to the new room
### Release Notes
- Open share menu when navigating from the create new shared project
button.
---------
Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
Rel #3861 TLD-2551
This PR adds a menu item to both multiplayer and local editor
components, to create a new shared project in the file menu.
I think it might be helpful to add a dialog as well. At the moment it
feels a bit sudden to jump to a new page right after clicking. However
it's non-destructive, and it would add an unnecessary extra step. What
do you think?
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Add a brief release note for your PR here.
We're currently sending `referrer` with path for image/bookmark
requests. We shouldn't do that as it exposes the rooms to other servers.
## `<img>`
- `<img>` tags have the right referrerpolicy to be
`strict-origin-when-cross-origin`:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy
- _however_, because we use React, it looks like react creates a raw DOM
node and adds properties one by one and it loses the default
referrerpolicy it would otherwise get! So, in `BookmarkShapeUtil` we
explicitly state the `referrerpolicy`
- `background-image` does the right thing 👍
- _also_, I added this to places we do programmatic `new Image()`
## `fetch`
- _however_, fetch does not! wtf.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
it's almost a footnote in this section of the docs
(https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options)
that `no-referrer-when-downgrade` is the default.
## `new Image()`
ugh, but _also_ doing a programmatic `new Image()` doesn't do the right
thing and we need to set the referrerpolicy here as well
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [x] `sdk` — Changes the tldraw SDK
- [x] `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 ❗️ -->
- [x] `bugfix` — Bug fix
- [ ] `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. Test on staging that referrer with path isn't being sent anymore.
### Release Notes
- Security: fix referrer being sent for bookmarks and images.
Lots of people are having a bad time with loading/restoring snapshots
and there's a few reasons for that:
- It's not clear how to preserve UI state independently of document
state.
- Loading a snapshot wipes the instance state, which means we almost
always need to
- update the viewport page bounds
- refocus the editor
- preserver some other sneaky properties of the `instance` record
### 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
- [ ] `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. Add a step-by-step description of how to test your PR here.
2.
- [ ] Unit Tests
- [ ] End to end tests
### Release Notes
- Add a brief release note for your PR here.
Right now when you hit Share/Fork on production it can take a good 5
seconds for something to happen.
In the meantime, it can feel like nothing happened when you clicked the
button. Maybe you click it again to see if that'll fix it, which doesn't
do anything. Same thing for the Copy action, sometimes we don't have an
icon to subtly show that it's been copied.
This adds some toasts and disables the Share menu while a project is
being created.
Also, has two drive-by fixes:
- the getShareUrl logic is old and needed to be superseded by the new
stuff
- the icon fix for clipboard-copied.svg from the readonly omnibus PR
(https://github.com/tldraw/tldraw/pull/3192) got overridden in a
different PR (https://github.com/tldraw/tldraw/pull/3627) - this
restores the fix
<img width="304" alt="Screenshot 2024-05-30 at 11 38 39"
src="https://github.com/tldraw/tldraw/assets/469604/f9a3b7c7-f9ea-41f0-ad00-7fc5d71da93f">
<img width="257" alt="Screenshot 2024-05-30 at 11 38 14"
src="https://github.com/tldraw/tldraw/assets/469604/c0a2d762-64c3-44da-b61e-c237133dd8cd">
### 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
- [ ] `feature` — New feature
- [x] `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
### Release Notes
- Share menu: make sharing/fork/copy actions clearer
When switching to a non-Select tool, it should disable the Duplicate and
Trash button (and others). They don't do anything when clicking on them!
(drive-by tiny tweak to a `focus()` call)
### 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 ❗️ -->
- [x] `bugfix` — Bug fix
- [ ] `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
### Release Notes
- Toolbar: disable menu items that don't work when not in select mode.
As I was setting up the Zoom app, it turns out they're very strict about
requiring OWASP headers for their apps.
https://developers.zoom.us/docs/zoom-apps/security/owasp/
- `Strict-Transport-Security`: max-age is set to 2 years, and is
suffixed with preload, which is necessary for inclusion in all major web
browsers' HSTS preload lists, like Chromium, Edge, and Firefox.
- CSP: just set to the default, not blocking anything at the moment to
avoid going down this rabbit hole.
### Change Type
<!-- ❗ Please select a 'Scope' label ❗️ -->
- [ ] `sdk` — Changes the tldraw SDK
- [x] `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
- [ ] `feature` — New feature
- [x] `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
Typescript's type aliases (`type X = thing`) can refer to basically
anything, which makes it hard to write an automatic document formatter
for them. Interfaces on the other hand are only object, so they play
much nicer with docs. Currently, object-flavoured type aliases don't
really get expanded at all on our docs site, which means we have a bunch
of docs content that's not shown on the site.
This diff introduces a lint rule that forces `interface X {foo: bar}`s
instead of `type X = {foo: bar}` where possible, as it results in a much
better documentation experience:
Before:
<img width="437" alt="Screenshot 2024-05-22 at 15 24 13"
src="https://github.com/tldraw/tldraw/assets/1489520/32606fd1-6832-4a1e-aa5f-f0534d160c92">
After:
<img width="431" alt="Screenshot 2024-05-22 at 15 33 01"
src="https://github.com/tldraw/tldraw/assets/1489520/4e0d59ee-c38e-4056-b9fd-6a7f15d28f0f">
### Change Type
- [x] `sdk` — Changes the tldraw SDK
- [x] `docs` — Changes to the documentation, examples, or templates.
- [x] `improvement` — Improving existing features