Skip to content

[pull] main from tldraw:main#583

Merged
pull[bot] merged 4 commits into
code:mainfrom
tldraw:main
Jun 10, 2026
Merged

[pull] main from tldraw:main#583
pull[bot] merged 4 commits into
code:mainfrom
tldraw:main

Conversation

@pull

@pull pull Bot commented Jun 10, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

max-drake and others added 4 commits June 10, 2026 09:25
Closes #7677

In order to give touch users an accessible way to zoom without requiring
a two-finger pinch gesture, this PR adds a double-tap-and-drag zoom
interaction to the HandTool.

On coarse-pointer (touch) devices, double-tapping the canvas and
dragging vertically zooms in/out — dragging down zooms in, dragging up
zooms out, matching the Google Maps convention. The zoom anchors to the
initial touch point so content stays stable under the finger. On
pointer-up, any remaining velocity triggers a momentum-based zoom slide.

Original branch: `max/one-finger-zoom`

### Change type

- [x] `feature`

### Test plan

1. Open tldraw on a touch device (or enable touch simulation in
devtools)
2. Double-tap the canvas and hold on the second tap
3. Drag down to zoom in, drag up to zoom out
4. Verify zoom anchors to the tap point
5. Release quickly and verify momentum zoom continues briefly

- [ ] Unit tests
- [ ] End to end tests

### Release notes

- Add double-tap-and-drag zoom gesture for touch devices

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches core camera animation math and hand-tool input handling, which
can affect pan/zoom behavior across devices. Risk is moderate because
changes are localized but interact with high-frequency tick/input code
paths.
> 
> **Overview**
> Adds a **double-tap-and-drag one-finger zoom gesture** for coarse
pointers: `PointingCanvas` transitions into a new `OneFingerZooming`
state on double-click down, where vertical drag adjusts camera zoom
while keeping the initial touch point anchored, then returns to idle.
> 
> Extends `editor.slideCamera` to support **z-direction zoom animation**
(in addition to x/y panning), adjusting camera x/y to keep the viewport
center stable during zoom; `OneFingerZooming` uses this to apply
momentum-based zoom on pointer-up.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0d5c39b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Kostya Farber <kostya.farber@gmail.com>
…9088)

Should close #9017

Newly added collaborator does not appear until they've actually "moved"
on the canvas, this is mostly likely to be picked up on tablet (and
normally… phones) as users are not spending their time moving fingers on
the screen (is dirty)

### Change type

- [x] `bugfix`
- [ ] `improvement`
- [ ] `feature`
- [ ] `api`
- [ ] `other`

### Test plan

On ipad, or desktop

1. Open tldraw
2. Do a doodely diddle
3. share it with yourself
4. open link BUT DONT TOUCHY THE SCREENY
5. check other room -> should see user 

- [ ] Unit tests
- [ ] End to end tests

### Release notes

- Fixed a bug in the `CollaboratorsManager` where we're not displaying
user who just joined until they interact with the board.
…r mid-hold (#9099)

In order to fix #9095, this PR stops a held shortcut key from falling
back to an adjacent non-modifier shortcut when a modifier is released
mid-hold.

Previously, pressing `shift+q` (copy hovered styles) and then releasing
shift while still holding `q` would let the auto-repeat keydown events
start firing the plain `q` shortcut (toggle tool lock) over and over.
The keyboard shortcut hook now tracks which registration each
physically-held key first triggered (keyed by `event.code`) and won't
switch to a different shortcut while that key stays down. The same
shortcut is still allowed to repeat, so behaviors like holding `=` to
keep zooming are unaffected.

### Change type

- [x] `bugfix`

### Test plan

1. Select a shape and hover another shape with a style.
2. Press `shift+q` to copy the hovered styles.
3. Release shift but keep holding `q`.
4. Confirm the tool lock toggle does not start flickering on/off.

- [x] Unit tests

### Release notes

- Fix releasing a modifier while still holding a shortcut key triggering
the adjacent non-modifier shortcut.
In order to make the group role label match what it actually represents,
this PR renames the non-owner group role from `admin` to `member`. The
role confers no admin-level capabilities — it's a standard group member
— so the old "Admin" label was misleading. Closes #9014.

This builds on the capabilities abstraction from #9067: authorization
asks `can(role, capability)` and never branches on the role name, so the
rename is purely a relabel plus a data migration — no authorization
logic changes.

What changes:

- **Role definition** (`roles.ts`) — the `admin` key in the `roles`
capability table becomes `member`. `Role` is derived from these keys, so
the `group_user.role` enum in `tlaSchema.ts` and every `Role`-typed call
site update for free.
- **Sync worker** — accepting a group invite now assigns `role:
'member'`.
- **Client UI** — the members list and role dropdown show "Member" (the
dropdown is data-driven from the role → label map, so only the label and
the map key change).
- **Database** — migration `033` drops the `group_user` role check
constraint, rewrites existing `admin` rows to `member`, then re-adds the
constraint allowing `('member', 'owner')`.

Because the new check constraint rejects `'admin'`, the migration should
run as part of the deploy that ships this change. In the `deploy-dotcom`
flow migrations run before the sync worker is deployed, so existing rows
are rewritten and the constraint swapped before any new code writes
`'member'`. Groups is behind the `groups_backend` / `groups_frontend`
flags and was added recently, so little data has accumulated.

### Change type

- [x] `improvement`

### Test plan

1. Open a group's settings dialog as the owner.
2. Confirm the members list shows "Member" (not "Admin") next to
non-owner members.
3. Confirm the role dropdown offers "Owner" and "Member".
4. Change a member's role to Owner and back; confirm it persists.
5. Accept a group invite as a new user; confirm they join as a member.

- [x] Unit tests
- [ ] End to end tests

`roles.test.ts` covers the role → capability matrix and `isRole` under
the new name; `mutators.test.ts` group tests run against `member`
fixtures.

### Code changes

| Section         | LOC change |
| --------------- | ---------- |
| Core code       | +2 / -8    |
| Tests           | +35 / -35  |
| Automated files | +9 / -9    |
| Apps            | +17 / -4   |
@pull pull Bot locked and limited conversation to collaborators Jun 10, 2026
@pull pull Bot added the ⤵️ pull label Jun 10, 2026
@pull
pull Bot merged commit 9936302 into code:main Jun 10, 2026
@pull
pull Bot had a problem deploying to bemo-canary June 10, 2026 15:13 Failure
@pull
pull Bot had a problem deploying to deploy-staging June 10, 2026 15:13 Error
@pull
pull Bot had a problem deploying to deploy-staging June 10, 2026 15:13 Error
@pull
pull Bot had a problem deploying to bemo-canary June 10, 2026 15:13 Failure
@pull
pull Bot had a problem deploying to vsce publish June 10, 2026 15:13 Failure
@pull
pull Bot had a problem deploying to deploy-production June 10, 2026 15:13 Failure
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants