* feat(web): add a success style to `EncryptionCard`
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(web): generate the recovery key inside the logout dialog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(web): cover generating the recovery key inside the logout dialog
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: Group translations under settings|encryption|recovery
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Two colour defects in Spotlight results, plus a test that could not see either:
- The public-room alias and the room context details are 12px text in
$tertiary-content at rest, which is 3.5:1 against the dialog background in the
light and dark themes - below the WCAG AA 4.5:1 for text that size. Use
$secondary-content at rest (5.2:1 light and dark, 8.9:1 high contrast).
Hovered and selected rows keep $primary-content, since secondary is only
4.2:1 against the hover background.
- In the light high-contrast theme a leftover override painted the notification
badge with the dialog background whenever its row was hovered or selected,
turning a red count badge into a white disc and hiding the count. Remove it;
the badge's own colours are fine (count text is 5.3:1 on red and grey).
The legibility test claimed to cover "text across Spotlight surfaces" but only
ever scanned a single hovered row, so neither defect could fail it. It now
returns two matching rooms per search so a row at rest sits beside the selected
one, puts the joined room in a space so context details are rendered, and leaves
an unread mention so the first result - selected by default - carries a badge
with a count. axe scans all rows for contrast; the selected badged row and a row
at rest are also screenshotted, the former because axe reports the overlapping
badge as incomplete rather than as a violation, the latter to pin the resting
colours. No hover and no retry is needed. Against the previous CSS the test
fails in all three themes on exactly these defects; with the fix it passes 30/30
across them.
Fixes#34991Fixes#34841
Signed-off-by: David Langley <davidl@element.io>
* collapsed and uncollapsed image tile
* using the new preview tiles in upload confirm dialog
* audio and video tag
* remove old urlpreview code
* force media width in confirm dialog to be max
* fixed upload audio upload preview failing, and hide preview box when preview fails
* undo the removal of the legacy mediabody
* cleaning up PR for review
* fixed oxlint issues
* regenerate stuff for end to end tests
* upload dialogue use tallbanner instead of full images
* updated snapshots
* updated snapshots
* regenerated snapshot
* fixed tests
* Cover the non-image previews in the upload dialog
computePreviewContent only ever ran its image case: the video, audio and
plain-file cases were untested.
Claude-Session: https://claude.ai/code/session_01Gr8zCXinjjNTmAHpZDGNtW
* applied some reviews
* moved conform dialog to be a functional component
* applied review comments
* Follow the renamed media preview entry API in UploadConfirmDialog
The entry discriminator is now `type` rather than `style`, and image
entries must carry `imageAlt` — the upload preview labels it with the file
name, matching the accessible name the pre-existing dialog gave the image.
* Regenerate image-upload-preview snapshot against the production build
* Stop telling people leaving a restricted room that they need an invite to return
The leave confirmation lists the complications of going, and one of them is that the
room cannot be re-entered. It decided that by testing the join rule against `public`
alone, so every rule that is not `public` got the same sentence: that you will not be
able to rejoin without an invite. For a restricted room that is untrue. Its whole
point is that membership of an authorised space is the ticket in, and Element itself
offers such a person a join button in the space hierarchy. Somebody who is still in
the space was being told they had burnt a bridge that is in fact still standing, in
red, at the moment they were deciding whether to leave.
Restricted rooms now get their own sentence naming the authorised spaces as the way
back, and spaces get the matching one, since a subspace is restricted whenever it is
created as anything other than public. It leads with what the room is - restricted -
rather than with what it is not: "not public" is the very fact that produced the wrong
advice, and opening with it again invites the same reading. Saying "cannot be rejoined
unless" in a single clause also spares the reader a contraction that is easy to
misread as its opposite when scanned or heard. The existing sentence is untouched and
still covers invite and knock: knocking would be the same kind of overstatement, but
asking to join sits behind a labs flag that is off by default, so for almost everyone
an invite really is the only route back into a knock room.
The new strings are added rather than the old ones reworded, so no existing
translation is invalidated.
* Keep the invite warning for a restricted room with no authorised spaces
Membership of an authorised space is what lets somebody back into a restricted
room, and the allow list is where those spaces are named. A restricted room
whose allow list is empty names none of them, so nothing can satisfy the rule
and the server turns every join away. Element already reads that state the same
way: the room's own security settings render zero allowed spaces as invite only.
The warning now asks for an authorised space rather than for the join rule
alone, so such a room keeps the sentence about needing an invite. Offering the
space route there would have been the same overstatement this branch set out to
remove, only pointed the other way.
Tests: two more cases in MatrixChat.test.tsx, a room and a space whose allow
list is empty, both asserting the invite sentence. The existing restricted cases
now carry an allow list, which is what a real restricted room has.
* Ask the leave question in the dialog's title, with the room's name
The confirmation opened on "Leave room" and then spent its first sentence asking
whether you were sure you wanted to leave the room you had just chosen to leave.
The title now carries the name and the question mark, which is where a reader
looks first, and the sentence that made redundant is gone.
That leaves the body to the warnings alone, so what is actually at stake — the
last member, the way back in, the only administrator — is the whole of it rather
than the tail of a sentence. A room with nothing to warn about has no body, and
an empty dialog body no longer holds open the 68px it was reserving for text.
Tests: both leave-dialog snapshots re-recorded, and the right-panel end-to-end
spec now looks for the dialog under the title it has.
* Size the leave dialog to its message
The question moved into the title, so the body is now a couple of short sentences at most and the
shared 60vw dialog width left them stranded in whitespace. The join failure dialog had the same
problem and was sized to its message; this follows it, down to the same 320px and the same
secondary text colour.
Colouring every sentence to match the Leave button left the dialog with no ordinary text in it at
all, so the red now sits only on the button that does the destructive thing. The empty-body rule
moves out of the shared stylesheet in the same change, since this is the only dialog it was ever
written for.
* Say a private room is private
"This room is not public" defines the room by what it is not, and "you will not be able to rejoin"
takes seven words to say "cannot". Element already calls this kind of room private everywhere else
it names it, so the warning now does too: "This room is private and cannot be rejoined without an
invite." That also puts it in step with the restricted sentence beside it, which was already built
on "cannot be rejoined".
The keys are unchanged, so the forty translations stay attached and follow the source through
Localazy. None of them go blank in the meantime, and the wording they carry today means the same
thing.
---------
Co-authored-by: David Baker <dbkr@users.noreply.github.com>
* Reopen the right panel when the current card is given new state
setCard's "same phase, new state" branch swapped the state of the card at
the top of the history but left the panel's own isOpen alone. If the panel
had been closed, the card was updated behind it and nothing appeared, so
the action looked like it had done nothing.
Show the panel in that branch, as the other two branches already do.
Also drop the unguarded index into a possibly empty history while we are
here: a matching phase can only have come from this room's own history, so
guard on it rather than trusting `hist[hist.length - 1]` to exist.
* Add a PDF viewer to the right panel
Open a PDF attachment in the right panel instead of having to download it
first. The viewer is pdf.js, rendering continuously with fit-to-width zoom,
pinch and ctrl-wheel zoom, and a page selector; the reading position is
remembered per file so reopening a document comes back where you left off.
The file body gains an optional "open" control next to download, which the
view model only asks for on PDFs shown as files in a timeline — not in an
export, and not in the download-only panels. FileBodyView renders nothing
for it otherwise, so every other file body is unchanged.
Encrypted attachments work unchanged: the handle the viewer is given reads
the bytes through MediaEventHelper's sourceBlob, which decrypts first.
The card stores only the source event id, so a restored panel re-derives
the media and drops the card if the event is no longer in the room.
* Add icon into the container instead of outside.
* Update translate + new images
* Load the right panel store lazily when opening a PDF
utils/pdfViewer is reached from the message body view models, and importing
RightPanelStore from it closed a cycle back to the message bodies:
utils/pdfViewer -> RightPanelStore -> SDKContextClass -> LegacyCallHandler
-> utils/notifications -> Unread -> EventTileFactory -> MessageEvent
-> MVoiceOrAudioBody -> MVoiceMessageBody -> extends MAudioBody
MVoiceMessageBody evaluated `extends MAudioBody` while MAudioBody was still
initialising, so the whole MAudioBody suite failed to load with "Class
extends value undefined is not a constructor or null".
Pull the store in through a dynamic import instead, as StoresApi already
does for the room list store. Nothing else under views/messages or
viewmodels imports RightPanelStore, which is what kept this cycle closed
until now.
openPdfViewer becomes async as a result; the click handler fires it with
`void` since opening the panel is not something the caller waits on.
* Code split the PDF viewer behind Suspense
Importing PdfViewer from the card put pdf.js into every module graph that
reaches the right panel, so RoomView pulled it in and the Jest suites failed
to parse it:
SyntaxError: Cannot use 'import.meta' outside a module
pdf.js locates its worker with `new URL(..., import.meta.url)`, which Jest
cannot compile, since it transpiles to CJS. That took out ExtrasApi-test and
anything else reaching RoomView.
Load the viewer with React.lazy instead, as the beacon components already do
for maplibre-gl. pdf.js is large and of no use until someone opens a PDF, so
keeping it out of the main bundle is worth doing on its own account; the Jest
suites stop seeing it as a side effect.
* Put the PDF viewer behind a lab
Ship the viewer disabled by default, as feature_pdf_viewer under the
Messaging group in Labs, alongside the other flags that change how message
content renders.
Two gates:
- FileBodyViewModel leads showOpen with the flag, and showInlineDownload
follows it, so with the lab off the file pill renders exactly as it did
before: attachment icon, file name, no actions.
- RightPanelStore drops a stored PdfViewer card when the flag is off, ahead
of the check for a displayable event. Without it, someone who had a PDF
open when they turned the lab off would get the viewer back on reload.
The existing "drops a PdfViewer card with no event to display" test now
enables the lab first; the gate had made it pass for the wrong reason.
* Drop the brand name from the PDF viewer lab
The i18n check forbids hardcoding "Element" in translations, since the brand
is configurable, and "Open PDFs in Element" tripped it:
"labs|pdf_viewer": contains forbidden hardcoded word
Keys that genuinely need the brand are allow-listed in the i18n job, but this
one does not: the label reads fine without it, and naming a panel the viewer
happens to use is the description's job anyway.
* Update card header to show file name + change edit icon to expend icon on filepreview
* Update storybook images to reflect new icon
* Update apps/web/src/viewmodels/message-body/FileBodyViewModel.ts
Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
* Removed @link as it did not go anywhere.
* Drop the self-referential @link in PdfViewerState docs
* Comment why the file tile actions are hidden in forward previews
* Test the RightPanel PdfViewer phase renders the viewer card
* Take the PDF viewer lab as a prop on FileBodyViewModel
* Dispatch an action to open the PDF viewer instead of importing the store
* Check the PDF signature before parsing the attachment
* MVVM PDF Viewer
* Fix Sonar
* Cap decoded image size and pin XFA off when opening a PDF
* Update apps/web/src/i18n/strings/en_EN.json
Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
* Use the real SettingsStore for the PDF viewer lab in tests
* Read the PDF viewer lab in the view, not the view model
* Declare the mock viewer's page field with the others
* Use the minified pdf.js worker
* Allow clicking on links in the PDF.
* Force use of a PDF worker
* Reduce logging noise.
* Cap PDF size
* Check blob size too
* Add support for clicking links in the canvas
* Report file size
* Tests
* cleanup
---------
Co-authored-by: Will Hunt <2072976+Half-Shot@users.noreply.github.com>
Co-authored-by: Half-Shot <will@half-shot.uk>
* 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
* Say why the homeserver refused an invite instead of blaming permissions
Every M_FORBIDDEN from an invite was reported as "You do not have
permission to invite people to this room", and the rest of the batch was
abandoned on the spot. That is only one of the reasons a server has for
refusing: the invitee may have invites switched off, or their homeserver
may not accept ours. Someone who did have the power to invite was told
they did not, and given nothing to act on.
The claim is now checked before it is made. If the room says we cannot
invite, the message and the abandoned batch are exactly as they were,
because that will hold for everyone in the batch. If we can invite, the
server's own reason is shown instead and the remaining invites are still
attempted, since a refusal aimed at one person says nothing about the
next.
The unfederated case comes out of the same branch unchanged. It was
reached through a nested conditional that had to spell itself out twice,
once for rooms and once for spaces, and reads better checked first.
Tests: a refusal we are allowed to send through now surfaces the server's
text and lets the batch continue, while a genuine lack of power still
gives the permission message and stops.
* Drop the homeserver's own wording from the invite refusal message
The reason a server gives for an M_FORBIDDEN comes back in English whatever
language the client is running in, so showing it leaves the user reading a
sentence they may not understand inside an otherwise translated dialog.
Nothing else in the app passes server text through to the UI.
The message now says only that the invite was refused, which is fully
translatable. The reason is not lost: the catch block already logs the whole
error, so it stays in the console and in a rageshake, where an untranslated
string does no harm and is where anyone diagnosing the refusal would look
anyway.
The rest of the change stands. Permissions are blamed only when the room says
we genuinely cannot invite, and a refusal aimed at one invitee no longer
abandons the rest of the batch.
* Reword the dialog that lists the invites a batch could not send
The dialog headed "Some invites couldn't be sent" goes on to say "We sent the others, but the below
people couldn't be invited to <room>". "Some" reads as more than one, though a batch of two can fail
on exactly one; "below" names the list by where it sits on the screen rather than by what it is; and
the room name is repeated back from the very room the user opened the invite dialog in.
The heading now reports what happened rather than what was possible, the list is introduced as the
following people, and the contractions are spelled out. The room name goes with them: nothing reaches
this dialog except invites the user has just sent into a room they are already looking at.
Dropping the name drops the RoomName substitution too, which is why the key is renamed rather than
reworded in place. The forty translations still carry the tag, and under the unchanged key they would
render it as literal text until each language is retranslated.
* Report a refused invite in place of the invite dialog, not on top of it
Design review asked for the failure report to take the invite dialog's place:
once the batch has run there is nothing left to go back to, because everyone who
could be invited already has been. The dialog now finishes before the report
opens, which also lets showAnyInviteErrors stop doubling as the decision about
whether to close it.
The reason line now reads as the reason rather than as a report of machinery.
The client cannot tell a person's own invite filter apart from a server that
refuses invites wholesale — both come back as a bare M_FORBIDDEN with nothing to
key off — so the wording states the effect, which is the same either way, rather
than guessing at a cause the way the permission message used to.
The report is capped at 600px, and each reason starts at the avatar's left edge
with a space above it, so it reads as a note about the person rather than as a
third line of their name.
* Keep the refusal report's own button inside its 600px box
BaseDialog puts the fixed-width class on the focus lock inside .mx_Dialog rather
than on .mx_Dialog itself, so capping the outer box alone left the body at its
old 704px and hung the OK button 144px past the right edge — measured in the
browser, not guessed. Pinning the outer box and letting the body size to it puts
them back together, and the viewport cap keeps a narrow window from overflowing.
* Stop the refusal line from pushing a name away from its avatar
Spanning the reason across both columns made it a grid item of the avatar
track, and that track was sized max-content, so the longest reason set the
avatar column's width and left a 158px hole between each avatar and its name.
Sizing the track from the avatar itself takes the reason out of that
calculation; the gap is back to the grid's own 12px and the reason still starts
at the avatar's left edge. The avatar size now has one definition instead of
being repeated as the track width.
* State each refusal once, under the people it applies to
Repeating an identical sentence under every name read as three failures with
three causes rather than one cause with three people behind it, and the eye had
to compare the lines to find out which. The failures are now grouped by the text
they would have printed, in the order the batch hit them, and each group says
its reason once beneath its own list.
Grouping also takes the reason out of the tile, which undoes the layout work the
earlier rounds needed: the tile is back to upstream's avatar-and-name grid, so
the spanning item that was inflating the max-content avatar column is gone along
with the track override that compensated for it. Spacing now comes from the
group — 8px between people, 16px above the reason — instead of a margin on every
tile.
* Play down the reason an invite could not be sent
The reason sat under the people it applies to in alert red, at the size of their names, which reads
as something gone wrong that the reader must act on. It is neither: nobody can do anything about a
homeserver turning an invite down, and the invites that did go out are unaffected. It now takes the
size and colour of the tertiary lines around it, so it explains without competing with the names
above it.
The reasons themselves repeated a subject the list had already given. Each one sits directly under
the person it describes, so "User is already in the room" said "user" twice over; the already-invited
and space wordings carried the same redundancy and lose it too. "They are not accepting invitations"
becomes "Not accepting invites", in the terser register the app already uses for a state the reader
cannot change.
* Keep the refusal reason in alert red
The reason was toned down to tertiary size and colour on the assumption that a homeserver turning an
invite down is informational. Review settled the opposite: the layout americanrefugee approved states
the reason once beneath the people it applies to, and at that position it is the only thing telling
the reader those invites did not happen. Tertiary grey at 12px reads as a caption on the list above
it rather than as the outcome, so it goes back to the alert red and the size of the names it explains.
The wording simplifications stay. Dropping the redundant subject was a separate ask and does not
depend on how the line is styled.
* Put the refusal reason above the people it applies to
The reason trailed the list it explains, so a reader met the names first and had to look back up once the
explanation arrived. Leading with it makes the line a heading for its group, and the 8px that had held it
clear of the names above now holds it clear of the names below.
A heading takes a colon rather than a full stop, but the reason is a translated string that the
single-invite failure dialog, the /invite command and the user-info invite button each show on its own,
where a trailing colon would dangle. The colon is appended where the report renders it instead, which in
turn means every reason has to arrive without a terminal stop: leave one on the wordier reasons this
branch did not introduce and they read ".:" as soon as two differently-caused failures land in the same
report. The four "already in the room" reasons line up with their existing translations again by losing
it, since upstream's English never carried one. The longer sentences will show ".:" in the locales that
have already translated them until Localazy picks the change up, which is the cheaper blemish; renaming
those keys to dodge it would throw away thirty-six translations apiece.
The alert red stays. TemoCrevlis read the line as informational and asked for tertiary grey; review
settled it the other way, on the grounds that it is the only thing on screen saying why those invites did
not happen, and red is the likelier to be read.
* Style the invite error dialog with Compound tokens
The refusal reason and the summary heading above it were still reaching
for the legacy $font-15px, $alert and $secondary-content Sass variables.
Each of those resolves to a Compound token one-for-one in every theme, so
naming the token directly costs nothing at render time and stops the
dialog depending on the compatibility layer.
The heading collapses into the --cpd-font-body-md-regular shorthand,
which already carries the regular weight and Compound's 1.5 line height.
That trades the hand-written 24px leading for 22.5px, the value Compound
intends for body-md text, rather than keeping a legacy variable alive
just to preserve a leading nobody chose deliberately.
* Add to shared components the content of section creation dialog
* Add a vm for the section creation view
* Use new vm and view in section creation dialog
* Clean up lang, test and css
* Move section name step into its own component
* Add a room picker view component
* Use room picker in section creation
* Add shared component screenshots
* Can add rooms when creating or editing a section
* Fix rich list taking too much space
* Fix exisiting e2e test
* Wire up the the selected room when creating the section from the room item menu
* Add e2e tests
* Rename "edition" to "editing"
* Fix illegible text on hovered Spotlight results in high-contrast theme
* Update Spotlight tests to use Axe for accessibility checks instead of custom contrast ratio calculations
* Refactor Spotlight accessibility tests to cover all themes and improve legibility checks across various UI elements
* Remove high-contrast theme from Spotlight legibility tests to streamline accessibility checks
* Fix invalid CSS comment breaking Oxfmt and scope out unrelated axe violation
_SpotlightDialog.pcss used // line comments, which are not valid CSS and
crashed the Oxfmt parser, causing spurious failures in Oxfmt and the
Static Analysis gate. Switched to a block comment.
The new Spotlight legibility test's broad axe scans also caught a
pre-existing nested-interactive violation (endAdornment buttons nested
inside clickable option rows), unrelated to the colour-contrast fix.
Scoped it out with axe.disableRules("nested-interactive") to keep the
contrast checks active without failing on the unrelated issue.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Update Room Directory screenshot baseline for Spotlight hover-color fix
The high-contrast legibility fix changes hover/selected text color in
Spotlight results, which is reflected in the Room Directory dialog
screenshot test.
* Use CI-rendered baseline for the Room Directory screenshot
The previous baseline still had the pre-fix colours for
.mx_SpotlightDialog_result_publicRoomAlias and
.mx_SpotlightDialog_result_publicRoomDescription, so the Linux CI run
reported a 418px diff on filtered-one-result.png. Replace it with the
image the Linux CI runner actually produced with the fix applied.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Retrigger CI (transient Electron install failure in Vitest job)
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* Refactor NotificationBadge to shared MVVM
* Added snapshot images
* Replace legacy NotificationBadge with adapter
* Fix Eslint
* Use regular NotificationBadge prop names
* Remove legacy NotificationBadge selectors
* Update TAC badge Playwright selectors
* Rename NotificationBadgeAdapter to NotificationBadge
Addresses review feedback: the component is the app-facing badge, not an
adapter, so name it NotificationBadge.
* Make NotificationBadgeView isClickable a required boolean
Addresses review feedback: there is no semantic difference between
`isClickable: false` and `isClickable: undefined` (both render the
non-interactive variant), so the field should be a plain boolean. The
view model always provides it.
* Drop redundant comparison guards in NotificationBadge view model setters
Addresses review feedback: Snapshot.merge already compares each field
with Object.is and only emits when something actually changed, so the
manual equality guards in each setter were redundant. Recompute the
snapshot unconditionally and let merge dedupe.
* Resolve notification badge labels inside NotificationBadgeView
Addresses review feedback: static UI labels belong in the view, not the
snapshot. The view now resolves the knock and unsent-message strings via
useI18n, and the snapshot exposes a showUnsentTooltip boolean instead of
a prebuilt tooltipLabel (and drops knockLabel entirely). Adds the
room|knock_sent and notifications|message_didnt_send keys to the
shared-components i18n catalogue so they resolve in tests and storybook.
* Remove unused translation because of shared components movement
* Fix typescript issue
* Fix lint issue
* Remove unused notification badge count setting
* Pass notification badge class names explicitly
* apply new design to logout dialog
* factor out check for other verified devices
* only show recovery warning when user has no other verified devices
* fix playwright tests
* tweak style to better match design
* another playwright test fix
* fix playwright
* Look for the remove button within the dialog
* Use testid to locate 'Remove this device' button
* move rendering to sub-components, rather than embedded functions
* use <Type> element
* use <Text> for the <a> element
---------
Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
* feat(sc): add section menu to section header
* feat(rls): add edit and remove sections
* feat(dialog): add editing mode to CreateSectionDialog
* feat(dialog): add remove section dialog
* feat(vm): wire up vm and stores
* test: update existing snapshots
* test(e2e): add playwright tests to edit and remove a section
* chore: fix remove section i18n key
* fix: able to send empty sections
* chore: update create section editing docs
* chore: remove useless fallback
* chore: add logs when section is unknown
* feat: use different wording when removing an empty section
* fix: only animate the chevron icon in the section header
* fix: change dialog subtitle weight to medium
* 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
* feat: add creation section dialog
* feat: add in skip list a method to change filters
* feat: add helper to creation section
* feat: add custom sections data to Settings
* feat: add custom section to room list store v3
* feat: update header and room list item vms
* feat: add toast to room list vm
* feat: add new translation
* chore: move util functions of room list specs
* test: add custom section playwright tests
* chore: call loadCustomSections in RoomListStoreV3 ctor
* Remove global h2 css rule in favour of heading styles/components
* Use Compound Heading in shared-components
and forbid hX elements
* Use Compound Heading in settings
add back margin to some legacy headings
* Tweak some headings
* Update screenshots
* Update screenshots
* Update snapshots
* Tweak .gitignore
* Update snapshots
* Iterate
* Update screenshots
* Update screenshots
* Update screenshot
* Refactor MessageActionBar into MVVM ActionBarView
* Adding tooltips for menu items and correct i18n strings
* Layout changes
* Renaming some properties
* Rename property
* Create a first version of the view model and refactor media visibility logic
* Refactor view to take options and rections menu as optional properties
* Cleaner interface between view and view model
* Refactor view properties and replace Menu and MenuItem
* Bugfixes and switching to ActionBarView instead of MessageActionBar in element-web
* Avoid creating view models and render toolbar until it is actually shown
* Added unit and playwright tests and documented the view
* Added view model unit tests and updated snapshots of dependant tests
* Remove unused components and unnecessary css
* Remove unused language tags
* Fix for handling join-rules correctly
* Prettier
* Add handling of stale view model in async calls
* Prettier
* Split the element-web css into two different. One for legacy components and one for the ActionBarView
* Missing variables used for linting
* Fix for showing ActionBarView when using keyboard for navigation
* Handle visibility on context menu closing
* ThreadPanel uses the ActionBarView so restore css rule
* Fix for visibility of the ActionBarView in Thread panel
* Fix for ActionBarVuew visibility when closing right-click context menu and not still hovering
* Add roving index to function as a toolbar
* Adjust the RoomView test to send hover to the EventTile instead of the message text
* Fix SonarCloud issues
* Fix for SonarCloud issue
* Merge fix
* Rename mx_LegacyActionBar to mx_ThreadActionBar
* Added documentation and simplified join rules
* Generalize the ActionBarView and move logic to view model
* Add the four new buttons to the ActionBarView
* Update view model and tests to use the updated ActionBarView
* Refactor element-web to use ActionBarView
* Clean up styling in element-web
* Clean up and updating snaps and screenshots
* Added unit-tests for better coverage
* Moving ActionBarView to the correct folder in shared components
* Update snaps in element-web
* Better documentation in stories
* Merge fixes
* Updates after review comments
* Review comment fixes
* Added documentation to view models and updated snaps
* Hide button had the wrong label
* Replace createRef with useRef
* Refactor MFileBody using MVVM and move to shared component
* Simplyfing rendering properties
* Create a first version of view model for the component
* Simplifying component properties and make it possible to override module css using data-* attributes
* Create a MBodyFactory in element-web and use it to render MFileBodyView from MessageEvent
* Use <MediaBody instead of <button to support legacy rendering
* Updated styling and comments
* Refactoring className from snapshot to component property
* Rename MFileBody* to FileBody*
* Rename MFileBody* to FileBody*
* Refactoring render branches to allow for displaying nothing
* Fix styling issues
* Fix lint errors
* Fix for css selectors in playwright tests
* Remove the MFileBody component and change all callers to use MBodyFactory:FileBodyView
* Remove unused strings in element-web
* Revert to render text in story iframes
* Fix for prettier error
* Fix playwright test css selectors
* Apply legacy styling in element-web
* Add legacy styling for mx_MFileBody
* Restore file
* Change from <div to <button
* Calculate span width ad update screenshots
* Remove width calculation and update snapshots
* Fix for letter-spacing and better content in story
* Updated playwright screenshots
* Updated snapshots
* Fixing Sonar errors/warnings
* Removed extra parentheses
* Changes after review
* Change border-radius to px and updated snapshots
* Fix typo in description
* And another typo fix
* Changes after review
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>