* feat(shared-components): add DeleteKeyStorageView
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(shared-components): cover DeleteKeyStorageView
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(web): confirm deleting key storage in a dialog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(web): remove the delete key storage settings panel
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(web): cover the delete key storage dialog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor: Combine conditionals in KeyStoragePanelViewModel
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Update "your chats are backed up" copy
... in the Settings dialog (RecoveryPanel), and the "set up recovery" toast.
* Change labels on "set up recovery" UI
* Add help text to 'Allow key storage' toggle
* update playwright snapshots
* Stop writing removed legacy mention rules from labs notification settings
Matrix v1.17 removed the legacy text-matching mention push rules
(.m.rule.contains_display_name, .m.rule.contains_user_name,
.m.rule.roomnotif) from the base rule set (MSC4210), and Synapse is
about to stop serving them by default. The labs notification settings
page wrote those three rules on every save regardless. Against a server
that no longer serves them the page never converges: Synapse currently
accepts the writes with 200 without serving the rules, so the "Update"
banner never clears and the page stays locked, and once the server
answers 404 as the spec requires every save fails.
The reconciler now only writes the legacy rules when they are present
in the rules fetched from the server, the same way the intentional
rules are gated on supportsIntentionalMentions.
Adds reconciler tests with the legacy rules absent and present, and
Playwright specs that run against Synapse with msc4210_enabled both
off and on.
* Split the labs mention rules e2e helper into explicit steps
Replace the shared parameterised test with small helpers that each spec
calls in order, so neither spec branches on the server mode. Each spec
asserts its own precondition and its own final state of the legacy rule.
Clicking "Proceed" is now unconditional and waits for the banner. Every
fresh account shows it, and the old one-shot presence check raced the
push rules fetch.
* Update copyright holder in labs mention rules e2e tests
* Cover all legacy mention rules in the labs notification e2e tests
* Keep proceeding until the labs update banner is gone in e2e tests
While the server serves the legacy mention rules, one click on "Proceed"
does not always unlock the labs notification settings page. The page writes
a legacy rule and its intentional counterpart in parallel, and
monitorSyncedPushRules copies the legacy rule's actions onto the intentional
one whenever a sync shows them out of step. When that sync lands between
the two writes, the monitor puts the old actions back, the page re-reads
the rules, still sees a difference and keeps the banner until the user
proceeds again.
That race is in the app and predates these tests, which are about which
rules get written. It made the served-mode spec flaky, so the helper now
proceeds until the banner is gone.
* Give the labs update banner click a timeout in e2e tests
click() waits for the "Proceed" button to be visible. On a retry the banner
may already be gone, which is why the helper checks for it before clicking.
A banner that goes away between that check and the click would still make
click() wait until the test times out, so the click now gives up after a
second and the next attempt finds the banner gone.
* Collection of EN string changes, Pt. 2
The webapp itself
* Sort i18n file
* Update tests/snapshots
and also change the rest of the "room" strings to "chat"
* more tests / snapshots
* More snapshots / tests
* More tests & snapshots
* Even more tests / snapshots
* More snapshots / tests
* Playwright screenshots pt. 1
* More screenshots
* More tests / screenshots
* One more 'devices'
* Update testcontainers docker digests
* Update tests due to Synapse switching to room version 12 by default
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
* Port GenericToast to a shared component
* Update imports of GenericToast
* Remove legacy styles
* update test ids
* Move from classes to testIds
* update snap
* update toasts
* Add a test for coverage
* Show intentional mention push rules in notification settings
Matrix v1.17 removed the legacy text-matching mention push rules
(.m.rule.contains_display_name, .m.rule.contains_user_name,
.m.rule.roomnotif) from the base rule set (MSC4210), and Synapse is
about to stop serving them by default. Settings > Notifications built
its "Mentions and keywords" rows from those rule IDs, so against such a
server it lost both mention rows.
The section now renders .m.rule.is_user_mention and
.m.rule.is_room_mention, with the legacy rules as their synced rules:
servers that still serve them stay in sync, others get no writes. The
displayed state comes from the intentional rule alone, and the
intentional rule wins when the legacy rules disagree. The two legacy
user-mention rows collapse into one.
Adds unit tests for the new rows and the sync monitor, and Playwright
specs that run against Synapse with msc4210_enabled both off and on.
* Keep the legacy mention rows unchanged while the server serves them
The first version made the intentional mention rules the rows everywhere,
which dropped the "Messages containing my display name" row and changed
the displayed state and sync direction for servers that still serve the
legacy rules. Users of such servers must see no change.
The legacy definitions, the sync monitor, the strings and the screenshot
baseline are back to what develop has. .m.rule.is_user_mention and
.m.rule.is_room_mention get definitions of their own and are only
rendered when the legacy rule they replace is absent from the user's
rules; otherwise they stay hidden and remain the legacy rows' synced
rules, as before.
Unit and Playwright tests now assert both server modes.
* Asset length with .toHaveLength
* Trim down push rule definitions comments
* Cover the server dropping the legacy mention rules mid-session
A failed push rule write now re-reads the rules from the server, so
that a settings tab left open across a homeserver upgrade recovers on
the next toggle instead of retrying against rows the server no longer
serves.
Tests: the two write tests for the legacy rows are merged into one;
unit tests cover the mid-session switch with the legacy write accepted
and with it rejected; the sync monitor test that will go away with the
legacy definitions is named as transitional, and a guard checks that
matrix-js-sdk does not add legacy rules as client defaults; a Playwright
test follows a preference across the switch.
Claude-Session: https://claude.ai/code/session_01BGRjcEDsBoUibL17XP98ww
* Apply review comments on the mention rules ordering and comments
Claude-Session: https://claude.ai/code/session_01BGRjcEDsBoUibL17XP98ww
* Check the mention settings end to end in Playwright
Review feedback: rather than only reading the push rules back from the
homeserver, have a bot mention the user in a room after each change and
assert what the room list shows. The homeserver computes the unread and
highlight counts from the user's push rules, so this covers the whole
path from the settings page to the room, in both server modes.
The push rules are still read back once, to check which rules each
toggle wrote: the legacy rules along with the intentional ones while
served, and only the intentional ones otherwise.
Claude-Session: https://claude.ai/code/session_01BGRjcEDsBoUibL17XP98ww
* Add an Invites section to the room list
Invited rooms are collected in a section pinned above Favourites.
The invite tag is synthetic, derived from the membership rather than
stored as account data, so tagRoom refuses to write or remove it.
* Name the Invites section and hide its filter chip
The collapsed header shows the number of invitations: an invitation is
neither a mention nor a notification, so it would contribute nothing to
the badge otherwise. The chip is only offered when sections are off.
* Keep invited rooms out of other sections
Membership fixes the section of an invited room, so it cannot be dragged
and the Favourited, Low priority and "Move to" entries are hidden.
* Start the Invites section collapsed
The section appears on its own when an invitation arrives, so it starts
closed and its header reports the count. Expanding it lasts only while it
is on screen, so it is closed again every time it reappears.
* Update e2e tests
* Update screenshots
* Simplify dragAndDrop.ts
* Open the section header in the e2e test only if closed
* Update lifecycle e2e tests
* Align view model with the current EventTileView contract
* Use presentation context at every application call for EventTileView
* Render EventTileView from UnwrappedEventTile
* Remove the legacy styling
* Added missing receipt gutter logic
* Adding Card as a new shape, used in TimelineCard panel
* Added visual tests for the Card story
* Migrate EventTile layout styling and enhanced the story book rendering
* Migrate preview, notification, thread, and file shapes
* Use MemberAvatar and RoomAvatar in storybook
* Make slot styling self-contained and clean up corresponding application styling
* Clean up action bar styling
* Clean up event tile styling overrides
* RoomView realted styling fixes
* Adjustments for threads list
* Adjustments to File view
* Adjustments to Card shape
* More styling cleanup
* Updated Playwright test selectors
* Update the story book with more relevant data
* Fix oxlint and update story screenshots
* Restored conditional notification-badge slot rendering to avoid empty wrappers
* Fixed tests and snapshots
* Remove the unused UnreadNotificationBadge
* Updated snapshots and removed a11y failing story test
* Fix test locator hooks
* Fixed styling and logic issues in appearance settings
* Fixes to slotSender and slotBody placement for group layout
* Reorder style sheet for better readability
* Fix for spacing between slotSender, slotBody and reply-chain
* Fix more Playwright test loacators
* Clean up event tile class overrides
* Fix the slotBody styling
* More clean up of unused locators
* Styling fixes
* Fixes to test locators and styling for bubble and irc layout
* Locator fixes, updated snapshots, layout adjustements
* Fix for selected and editing markers and timestamp pos
* Styling fixes to bubble layout. Also dismiss releaseAnnouncements
* Styling updates and dont wait for release announcements anymore
* Styling adjustments
* Make the Playwright test wait for UI to settle before taking screenshot.
* Updated screenshot - the only difference is scroll pos
* Fixing test locators and styling adjustments
* Updated the test to reflect ellipsis, hence the screenshot update
* More test locators and styling adjustments
* Updated snapshots and screenshots
* More locator fixes and snapshots
* Restore the original screenshot
* Added Search result specific styling and make reply chain density aware
* Test locators and styling adjustments
* More styling fixes
* Updated snapshot
* oxfmt
* Styling adjustment and updated snapshots
* Styling adjustement
* Restore the font-12px override on thread view ViewSourceEvent
* Adjust styles for thread view bubble layout of ViewEventSoucrce
* More adjustments
* Styling adjustments
* Fix the bubble layout thread view event source alignment
* Fix the thread view without destroying the room view
* Removing !important
* Updated snapshots after merge
* Put back !important until MemberAvatarView is actually used in event tiles
* Updated snapshots
* Use hideJumpToBottomButton to avoid flakiness
* More hideJumpToBottomButton
* Make apps/web/playwright comply with strict mode
Otherwise it sometimes fails to compile matrix-js-sdk as strict mode & noImplicitAny both impact how overloads are asserted
* Iterate
* Adapt OAuth2 implementation to Matrix Spec v1.18
* Handle more cases of oidc->oauth
* Fix test
* Fix read back of oauth2 context
* Iterate
* Fix tests
* Discard changes to apps/web/playwright/e2e/settings/account-user-settings-tab.spec.ts
* Fix test
* Fix test
* Fix test
* Potential fix for pull request finding 'Unused variable, import, function or class'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Iterate
* Iterate
* Fix test
---------
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Change `feature_group_calls` to default to true.
Change state to Beta
* Add `enableLegacyCallsVoip` (clarify: Audio settings relate to Legacy)
Change `element_call.use_exclusively` to just be the default of
`enableLegacyCallsVoip`.
Allow disabling in Legacy in the settings. (overwrite `use_exclusivly`
via `enableLegacyCallsVoip`)
Rename `Voice & Video` to `Legacy Voice & Video`
* improvements
- settings title update to only show legacy when appropriate
- hide menu all together if use_exclusivly is chosen
* simplify by removing the feature_group_calls flag
* smaller cleanup
* fix tests and cleanup
* clarify settings (disable) in config.md
* add back EC relevant settings in room settings dialog
* update screenshots (now default to EC enabled (not disabled)
-> show voice and video tab in room settings
* update screenshots
* always show option to control voice messages input
* lint
* fix test
* disable -> enabled And only have on mic dropdown
* update config.md
* Back to `disabled` (on by default/no config)
* remove element call hint from voice-video settings
* Update apps/web/src/i18n/strings/en_EN.json
Co-authored-by: Robin <robin@robin.town>
* Update apps/web/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx
Co-authored-by: Robin <robin@robin.town>
* review
* cleanup element call url setting (its deprecated/not used anymore)
* clarify, that also jisti will be enabled/disabled by legacy settings
flag
* remove double section
* remove unn exassary element_call configurations
* Update en_EN.json
* Update VoiceUserSettingsTab.tsx
* Make tests use new defaults (enable element call)
* Default events power levels
* format
* review "Enable Legacy voice/video calls" label
* more radical usage of defaults in element_call config.json's
* Update config.json
* Update en_EN.json
* Update RoomSettingsDialog-test.tsx.snap
* Update useRoomCall.tsx
* fix imports
* Update request permission promp to latest designs:
https://www.figma.com/design/aOEkaJtaBmPy058V7uoqVr/Element-Call-Updates---2026?node-id=45-12591&t=7takL39icZwt9YjL-0
* Update config.json.d.ts
* fix usage of `Element` in i18n
* Update General-room-settings-tab-should-be-rendered-properly-1-linux.png
---------
Co-authored-by: Robin <robin@robin.town>
* refactor(room-list): migrate SpaceStore off the legacy room list store
SpaceStore.setActiveRoomInSpace iterated the legacy RoomListStore's
`orderedLists` in `TAG_ORDER`; switch it to the space-aware
RoomListStoreV3.getSortedRoomsInActiveSpace() accessor. This drops the
last non-UI dependency on the legacy store and on `TAG_ORDER` (exported
from LegacyRoomList, deleted next).
* feat(room-list)!: remove the legacy room list UI
Delete the old sublist-based room list and its components now that the
new RoomListPanel is the default. Removed: LegacyRoomList,
LegacyRoomListHeader, RoomSublist, ExtraTile, RoomTile (+ Subtitle/
CallSummary), RoomBreadcrumbs and RoomSearch, plus their styles and
tests.
LeftPanel collapses to the RoomListPanel-only path. The shared
`contextMenuBelow` helper is relocated into RoomResultContextMenus (its
only remaining consumer).
* feat(room-list)!: remove the legacy RoomListStore
The legacy sublist-based room list UI is gone, so the old
`stores/room-list` store (Algorithm, sorters, filters, layout store,
space
watcher) has no remaining consumers. Delete the directory and its tests.
MatrixChat.forgetRoom no longer calls the legacy `manualRoomUpdate`; the
new room list store removes the room on the `AfterForgetRoom` dispatch
that still fires. Drop the `mxRoomListStore`/`mxRoomListLayoutStore`
globals and the now-dead test imports.
* feat(room-list)!: remove the feature_new_room_list labs flag
The new room list is now the only room list, so remove the
feature_new_room_list labs flag and make its enabled behaviour
unconditional everywhere it was gated:
- LoggedInView: always use the resizable layout and
NEW_ROOM_LIST_MIN_WIDTH;
drop the collapsible/minimized legacy path.
- SpaceStore: People and Favourites are dropped from metaSpaceOrder (per
the
long-standing TODO on the removed accessor).
- MessagePreviewStore: stop appending thread replies to previews.
- Settings, SidebarUserSettingsTab, PreferencesUserSettingsTab,
QuickSettingsButton, SpacePanel, LandmarkNavigation: drop the flag
reads and
legacy branches.
Update the tests that toggled the flag; the People/Favourites meta space
tests covered behaviour that the flag (default on) already disabled.
* feat(room-list)!: remove the dead legacy left-panel resizer
LoggedInView still built the old `Resizer`/`CollapseDistributor` over an
`lp-resizer` ResizeHandle and persisted `mx_lhs_size`. That handle is no
longer rendered (the resizable layout is now driven by
LeftResizablePanelView + ResizerViewModel, which persists its own state
via RoomList.panelSize/RoomList.isPanelCollapsed), so the old resizer
was
inert dead code left over from the legacy room list.
Remove createResizer/loadResizer/loadResizerPreferences, the
_resizeContainer/resizeHandler refs, the ResizeHandle render, the
mx_lhs_size handling and NEW_ROOM_LIST_MIN_WIDTH, plus the unit tests
that
exercised the mocked resizer.
* feat(room-list)!: update i18n files
* refactor(room-list): remove the now-unused collapseLhs state
`collapseLhs` is write-only since the left panel no longer collapses: it
was last read by LoggedInView's `shouldUseMinimizedUI`, removed with the
feature_new_room_list flag. Drop it from MatrixChat's IState (and its
assignments), collapsing the hide/show_left_panel handlers to just the
`notifyLeftHandleResized()` call they still need, and from
LoggedInView's
IProps and the test props.
* fix(room-list): instantiate message previewers lazily
Removing the unused SettingsStore import from MessagePreviewStore (when
the
feature_new_room_list flag was dropped) changed module load order and
exposed a latent circular dependency: ReactionEventPreview imports
MessagePreviewStore, which eagerly did `new ReactionEventPreview()` at
module-eval — so importing ReactionEventPreview first (as its unit test
does) hit "ReactionEventPreview is not a constructor".
Construct the previewers lazily on first use (cached) instead of at
module
load, so nothing dereferences a mid-evaluation module. Fixes
ReactionEventPreview-test.
* test(room-list): remove `feature_new_room_list` labs flag in e2e tests
* chore: remove remaining `newRoomList` flag
* chore: cleanup theme files
* fix: restore the re-resizable TouchEvent polyfill
* chore: remove usage of breadcrumbs settings in BreadcrumbStore
* Revert "fix(room-list): instantiate message previewers lazily"
This reverts commit 4e6eedfff0.
* chore: remove unused function in BreadCrumbStore
* test: remove unused fuction of BreadcrumStore in tests
* test: add tests for RoomResultContextMenu
* Pluralise the multi-session remove button and confirmation dialog
When several sessions are selected in Settings > Sessions, the bulk remove button and its confirmation dialog used the singular "Remove this device" string. The singular "this" misleadingly implied the current device would be removed. Use the existing count-aware settings|sessions|sign_out_n_sessions key, matching the other-sessions menu, so the label reads "Remove N sessions".
Fixes#33812
* Update device-management e2e test for the pluralised remove button
The multi-select remove button now reads "Remove N sessions" instead of "Remove this device", so update the Playwright assertion to match.
* Put "Cancel" before "Remove N sessions" in the bulk session action bar
In the "Other sessions" multi-select action bar, "Remove N sessions" was
rendered before "Cancel", which placed the destructive action on the left.
Swap the two buttons so "Cancel" is on the left and "Remove N sessions" on the
right, per review feedback on #33983.
* Tweak new user menu design
* Update screenshots
* More screenshots
* Add story with no avatar
* add story to test
* Expand the menu so it actually shows what it's supposed to show
* Use the open parameter
which is the param to open the menu
* snapshot
* Add test for normal open menu version
* Move menu to the right of the avatar
and make it appear on top of the display name
* Fix user menu layout
* screenshots
* snapshot
* screenshots
* more screenshots
* Shift toasts to the left slightly
So they completely cover the display name of the user menu when
it's expanded. Also down slightly so they're level with the user menu.
* Tweak toast border radius & position
to match & sit on top of the user menu
* Close toasts in cider tests
* Only close the toast if it's actually there
* Fix some toasts to be dismissed & update screenshots
more to come though
* Make closeKeyStorageToast actually optional
* Fix some more toasts & races
* Screenshots again again (again)
* More screenshots
* Convert to rejectToast
* Fix toast rejectors to not wait and update screenshots
* Apparently 1ms is not long enough
* Initial quick settings menu
* Total refactor
* Quick design fixes.
* Refactor to use a view model.
* Remove unused strings
* Apply label
* Refactor naming
* Fixup most tests
* Remove specific theming for old user menu
* prettier
* Lots of cleanup
* Allow overriding the menu classes
* update snap
* Oops translations
* tidy
* Cleanup guest flows.
* Copyrights
* Remove unused classname
* Match guest view to designs
* Add guest screenshots
* Update guests
* snapshot
* Cleanup
* fix import
* Update tests
* More sceenshot fixes
* update collapsed
* move statements to prevent flake
* update snap
* Kick it along
* Click the room list
* Fiddle with the room video list.
* More screenshot adjustments
* fix imports
* fix another import
* Update snaps
* update snaps
* Fix snap flakes
* Refactor to move actions to view component, and callbacks to Actions
* Cleanup
* Cleanup
* Cleanup
* invert auth
* More bits
* fix
* Change md buttons to sm
* Try to assemble the snapshot component of the house of cards
* Consistent newlines between tests
* Update snapshot
Not sure why this was like this, this seems consistet for a logged in user
* Update snapshot
again these seem sensible for a guest
* Remove test
I don't really understand why the thing it asserts matters, so I'm removing
it for now.
* Update snapshot
* screenshot
* Don't show profile picture for guests
I'm not really sure what it meant for this interface to have a
property with a default value, so I've removed it and added the
property to the view model.
* Show avatar in story
* update snapshots for showAvatar
* Update screenshots
& hopefully make hover consistent in one
* Use outline home icon
---------
Co-authored-by: David Baker <dbkr@users.noreply.github.com>
* InviteDialog: factor out startDmOrSendInvites
Factor out the logic of calling `startDm` or `inviteUsers` to a helper
function. We're going to need to call this from a second location soon, so this
is useful groundwork.
* Add `UnknownIdentityUsersWarningDialog`
* Add unit tests
* Update playwright tests
* Convert if/else to switch statement
* Convert helper functions to React components
* Factor out "onRemove" callback
* Add clarifying comment
* [create-pull-request] automated change
* Use a dedicated string for public access in settings.
* Fix tests due to copy changes.
* Fix tests due to copy changes.
* Fix tests due to copy changes.
* Fix tests due to copy changes.
* Fix tests due to copy changes.
* Updated visual tests screenshots due to copy changes.
* Updated visual tests screenshots due to copy changes.
---------
Co-authored-by: t3chguy <2403652+t3chguy@users.noreply.github.com>
Co-authored-by: mxandreas <andreass@element.io>
mkdir apps/web/scripts
mv scripts/{cleanup.sh,ci_package.sh,copy-res.ts,deploy.py,package.sh} apps/web/scripts
And a couple of gitignore tweaks
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>