Skip to content

Folders get permissions, and a channel says whether it follows its folder (GRYT-1306) - #632

Merged
sivert-io merged 1 commit into
mainfrom
claude/GRYT-1306-folder-permissions
Sep 21, 2026
Merged

sivert-io merged 1 commit into
mainfrom
claude/GRYT-1306-folder-permissions

Conversation

@sivert-io

@sivert-io sivert-io commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

Task: GRYT-1306. Server half: Gryt-chat/server#207, which has to be released first. Phone: Gryt-chat/mobile#234.

What changed

  • Folder settings have a Who can use this folder section, under the name. It's the channel editor again, moved into ScopePicker.tsx so both use it: Everyone, a template, or rules of its own with the same matrix. It only shows when the server sends server_info.folder_permissions. An older server ignores the folder events.
  • Channel settings say whether a channel follows its folder, above the dropdown: "Follows the Staff folder" or "Has its own permissions instead of the Staff folder's", with a Follow folder button on the second. The dropdown shows what applies, which is the folder's choice while the channel follows it. Picking anything gives the channel its own, and Follow folder hands it back.
  • Closing the dialog only sends a scope edit that's still waiting. It used to send the scope again on every close. With folders that would have made a following channel its own just for being opened. It also reset a channel to Everyone when the dialog was closed before its scope arrived, which a slow connection could do to a private channel.
  • createChannel puts the folder on server:channels:upsert too, beside the row. The server then puts the new channel's first row straight into the folder, so a channel made in a hidden folder is never sent to everybody at the top level first. An older server ignores the field.

sidebarTree.ts keeps hideEmptyFolders from GRYT-1305. A newer server doesn't send a folder nobody can see into, so this only matters against an older one, and the comments say that now.

Things to look at

  • The flush change in SidebarEditDialog.tsx. pendingScopeRulesRef carries the matrix the timer was holding, and Follow folder cancels a waiting save so it can't land after the follow.
  • The folder copy lives in folderPermissionRules.ts here and in channelRules.ts on the phone. Both belong in @gryt/core, but that needs a core release first, so it's GRYT-1347.

Tests

e2e/tests/folder-permissions.spec.ts sets a folder's permissions from its settings, by right-click, Edit and the dropdown. Then a guest joins, and the test checks the guest's sidebar and every socket frame the guest got carry neither the folder's name nor its channels'. It gives one channel its own Everyone, checks the guest gets that channel and the folder back but not the other channel, then presses Follow folder and checks both go again. Last, it opens and closes a following channel's settings and asks the server whether it still follows.

It skips itself when the server doesn't answer server:folders:scope:get, so on this PR it's skipped against server:latest. check-channel-permissions.mjs covers the folder lines.

Verified

yarn lint, yarn build, yarn tsc -p e2e and every test:* script in ci.yml. The whole e2e suite, 44 tests, passed against an image built from the server branch, with GRYT_E2E_SERVER_IMAGE. Against server:latest the folder spec skips and sidebar-folders.spec.ts passes.

sidebar-folders.spec.ts failed in one of my three whole-suite runs, with the new channel's name showing up twice. That's GRYT-1331, and I've added what I found there.

🤖 Generated with Claude Code

…lder (GRYT-1306)

Folder settings have a Who can use this folder section under the name.
It's the channel editor again: Everyone, a template or rules of its own,
with the same matrix. It only shows on a server that sends
folder_permissions, since an older one ignores the folder events.

A channel in a folder says in its settings whether it follows the folder
or has its own permissions. The dropdown shows what applies, which is
the folder's choice while it follows. Picking anything gives the channel its
own, and Follow folder hands it back. The server answers the follow with
the channel's scope, and the dropdown goes back to the folder's choice.

Closing the dialog used to send the channel's scope again even when
nothing had changed. That would have given every following channel its
own copy of the folder's permissions just for being opened. It also reset
a channel to Everyone when the dialog closed before its scope had loaded.
Closing only sends a matrix edit that's still waiting now.

createChannel sends the folder on server:channels:upsert as well as on
the row, so a channel made in a folder is never sent at the top level
first. An older server ignores it.

The empty-folder hiding from GRYT-1305 stays. A newer server doesn't send
those folders at all, but an older one still does.

e2e/tests/folder-permissions.spec.ts puts a folder on a template from its
settings and checks a guest's sidebar and socket frames never carry the
folder's or its channels' names. It gives one channel its own Everyone,
checks the guest gets that channel and the folder back, then follows the
folder again and checks both go. Opening and closing a following
channel's settings has to leave it following. The spec skips itself on a
server without folder permissions.

Co-Authored-By: Claude Opus 5 <[email protected]>
@sivert-io
sivert-io merged commit ff3fa30 into main Sep 21, 2026
8 checks passed
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