Commit Graph

6374 Commits

Author SHA1 Message Date
Benoit Marty 1a18da8ead Merge pull request #7395 from hayaksi1/fix/7393-bug-report-submission
Fix bug reports failing to send after the app has crashed
2026-08-13 09:12:44 +02:00
Benoit Marty a3e7d9cc1a Merge pull request #7413 from element-hq/feature/bma/fixThreadPlaceholder
Fix wrong TextComposer placeholder displayed when in a thread.
2026-08-13 09:01:24 +02:00
Benoit Marty 00e9a8ab71 Fix wrong TextComposer placeholder displayed when in a thread.
We cannot only use MessageComposerMode since use can edit a message in a thread, so this is becoming handly.
2026-08-12 17:05:08 +02:00
Jorge Martín 7c648b34b7 Remove the legacy web-based account creation for matrix.org
This was added as a temporary measure to allow matrix.org users to use Element X before it supported MAS, but it hasn't been needed for a very long time
2026-08-12 16:48:53 +02:00
hayaksi1 d4863db03e Group the GitHub issue body limit constant with an underscore
The GITHUB_MAX_ISSUE_BODY_SIZE constant added with the description truncation
is a five-digit literal, above detekt's acceptableLength of 4, so
:features:rageshake:impl:detekt failed. Write it as 65_536, matching
MAX_LOG_LINES_SIZE in RageshakeConfig.
2026-08-12 16:06:02 +03:00
Benoit Marty 539437da22 Merge pull request #7343 from hayaksi1/fix/7190-forward-live-location
Hide the forward action on live location shares
2026-08-12 13:47:36 +02:00
Benoit Marty 6cc581d2d3 Merge pull request #7379 from hayaksi1/fix/7314-invalid-pinned-events
Do not display pinned events that the client cannot render
2026-08-12 13:44:48 +02:00
Benoit Marty 7b0745c5f1 Fix layout issues. 2026-08-12 11:00:55 +02:00
Benoit Marty 7c4e81679f Animate visibility of the developer option entry point.
Related to #6703
2026-08-12 09:49:24 +02:00
Benoit Marty fae7df16f9 Merge pull request #7338 from element-hq/feature/bma/linkNewDeviceTimeout
[Link new device] Add timeout
2026-08-11 17:51:39 +02:00
Benoit Marty c0fbdd78ca Merge pull request #7369 from hayaksi1/fix/6130-space-left-room-joinable
Hide space children you have left that can only be joined by invitation
2026-08-11 17:17:55 +02:00
Benoit Marty 18e76b569f Merge pull request #7340 from hayaksi1/fix/7289-custom-map-style-url
Do not append the application MapTiler key to a custom map style url
2026-08-11 16:53:53 +02:00
hayaksi1 055fea8d25 Hide the forward action on live location shares
The timeline action sheet offered Forward on a live location share, but
forwarding one always failed: Mode.Live maps to the SDK's
MsgLikeKind.LiveLocation, which RoomContentForwarder rejects outright. So
the action was shown for exactly the set of events on which it could
never work.

canBeForwarded() now returns true for a location event only when its mode
is Static. Ended live shares keep Mode.Live and fail for the same reason,
so they are excluded too. ActionListPresenter needs no change: its check
is the function's only call site in the repo, so the single gate covers
the timeline sheet, the threaded timeline and the pinned messages list.

Hiding the action mirrors Element Web and the sticker exclusion already
present in the same function. Converting a live share into a static
m.location on forward would be a product decision and is out of scope.

Relates to https://github.com/element-hq/element-x-android/issues/7190
2026-08-11 17:48:45 +03:00
Benoit Marty 223973805f Create function to limit code duplication. 2026-08-11 16:30:11 +02:00
Benoit Marty 749ecb4576 No need for a companion object. 2026-08-11 16:28:07 +02:00
Benoit Marty 9116b8a776 Merge pull request #7342 from hayaksi1/fix/5383-incompatible-room-list-filters
Ignore a room list filter that is incompatible with an already selected one
2026-08-11 16:21:51 +02:00
Benoit Marty bea89fee41 Merge pull request #7352 from hayaksi1/fix/6189-no-call-in-empty-dm
Do not offer to start a call in a DM with no other member
2026-08-11 16:21:02 +02:00
Benoit Marty 15addc522b Merge pull request #7367 from hayaksi1/fix/2925-room-notification-mute-string
Use a dedicated string for the Mute room notification mode
2026-08-11 15:59:55 +02:00
Benoit Marty 12f4330724 Merge pull request #7371 from hayaksi1/fix/5428-send-to-room-subtitle
Show the alias or the direct message user's Matrix ID in the room picker
2026-08-11 15:59:29 +02:00
Benoit Marty 005cbf6579 Merge pull request #7372 from hayaksi1/fix/4893-copy-blocked-user-id
Copy a blocked user's Matrix ID by long pressing them
2026-08-11 14:04:19 +02:00
Jorge Martín e371b46c68 Rename GetUrlResolver to UrlContentFetcher and TemporaryMatrixClientFactory.createTemporaryMatrixClient to just create 2026-08-11 13:18:49 +02:00
Jorge Martín e24468c74f Fix and add tests 2026-08-11 13:18:49 +02:00
Jorge Martín 90d4fbe0bd Apply the GetUrlResolver pattern using unauthenticated matrix clients where possible 2026-08-11 13:18:49 +02:00
Jorge Martín fd3c671301 Create RemoteEnterpriseConfigProvider wrapper
For Pro, this will check different remote config sources and return the result. For FOSS, this will always return a `NotFound` result
2026-08-11 13:18:49 +02:00
Jorge Martín 59758a20a5 Add RemoteEnterpriseConfig typealias for ElementWellKnown
In the future, we want to move the enterprise config to the private Element Pro repo, this is a first step
2026-08-11 13:18:49 +02:00
ganfra 6d6ca97899 Merge pull request #7328 from element-hq/feature/fga/user_status_last_pieces
User status last pieces
2026-08-11 11:11:12 +02:00
ganfra 0de78ed956 Merge branch 'develop' into feature/fga/user_status_last_pieces 2026-08-11 10:04:18 +02:00
bmarty 17c5d7db59 Sync Strings from Localazy 2026-08-11 09:27:29 +02:00
hayaksi1 84b38e291a Fix bug reports failing to send after the app has crashed
The whole crash call stack was appended to the bug report description, and the
bug report server copies that description verbatim into the GitHub issue it
opens. GitHub refuses an issue body over 65536 characters, so the server's save
step failed and answered "Could not save report". The stored crash data is only
cleared after a successful send, so every retry failed the same way.

Truncate the description before sending it. The user's own text and the GitHub
issue link come first, so only the tail of the crash stack is dropped. The
uncaught exception handler already writes the full stack through Timber, so it
stays available in the attached log files.

The 40 KB budget leaves room for the other reported fields, mainly the list of
omitted log file names, which is not otherwise bounded.
2026-08-10 22:53:50 +03:00
Benoit Marty a95f02497e Merge pull request #7378 from hayaksi1/fix/6853-remember-revealed-images
Keep manually revealed media visible when re-entering a room
2026-08-10 19:23:39 +02:00
Benoit Marty b4189f5ee0 Merge pull request #7375 from hayaksi1/fix/3444-login-with-full-matrix-id
Let users enter their full Matrix user ID when searching for a homeserver
2026-08-10 18:17:53 +02:00
hayyaksi 348c7bcea8 Expand the emoji picker to full height when the keyboard is shown (#7382)
* Expand the emoji picker to full height when the keyboard is shown

The picker content is rendered with fillMaxSize, so the sheet measures itself to
the full window height. That makes the partially expanded anchor available, and
the modal sheet auto-shows at that anchor, half way down the screen.

The sheet reserves the IME inset through its content window insets, but applies
that padding at its own bottom edge, which is off-screen while it rests half way
down. The band that is both on-screen and above the keyboard is then only about
a tenth of the screen, which is why the matching emoji end up behind it.

Expand the sheet while the keyboard is visible so its bottom edge returns to the
screen edge and the inset it already reserves lands on top of the keyboard.
Modifier.imePadding on the sheet content is not an option: the sheet applies the
insets with windowInsetsPadding, which consumes them, so a nested imePadding
reads zero.

* Cover the keyboard driven sheet expansion with a test

The IME reaction moves into ExpandSheetWhenImeIsVisible so a Robolectric test can
drive it: dispatching window insets to the composition flips
WindowInsets.isImeVisible, and the sheet state is observable from the test. Both
the shown and the hidden case are asserted, which is the patch coverage this
change was missing.

* Do not leave a blank strip below the expanded emoji search

The 10dp of bottom padding on the search bar separates the collapsed
field from the category tabs underneath it. It stayed applied once the
search bar expanded to fill the picker, so the picker stopped 10dp short
of its own bottom edge.

That strip used to sit below the visible part of a half height sheet.
Now that the sheet expands against the keyboard it reads as a gap
between the results and the keyboard, so only pad while collapsed.
2026-08-10 16:35:38 +02:00
hayaksi1 629dc15a86 Only show a Matrix ID in the room picker for a direct message
heroes is populated for any room whose name is derived from its members,
not only for direct messages, so a two person room that is not a DM
showed a member's Matrix ID as its subtitle.

Carry isDm on SelectRoomInfo and read the hero only when it is set. The
canonical alias still takes precedence, so nothing changes for a room
that has one.
2026-08-10 16:46:58 +03:00
Jorge Martin Espinosa e101963814 Display 'add reactions' menu in the threads screen (#7388) 2026-08-10 15:38:57 +02:00
hayaksi1 1b833df727 Expose the revealed event ids as a SnapshotStateSet
Restore the snapshot backed set the store started with and declare
allowedEventIds as SnapshotStateSet so the interface says out loud that
reads of it are observable.

TimelineProtectionPresenter reads the set inside derivedStateOf, so a
plain set silently stops the timeline from re-rendering when an event is
revealed. Naming the type keeps that requirement from being mistaken for
an implementation detail.
2026-08-10 16:36:36 +03:00
Benoit Marty 1693d325c1 Update UI according to https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=5781-5862 2026-08-10 12:12:55 +02:00
Benoit Marty 650b38429c Show a Message not found placeholder when a replied to message cannot be loaded (#7376)
* Show a Message not found placeholder when a replied to message cannot be loaded

When the replied to event could not be fetched, the reply preview rendered the
raw SDK error string in critical styling, and tapping it emitted a focus
request that could never succeed, so the user got a dead end dialog.

Render the localised error_message_not_found string in the neutral italic style
already used for redacted and undecryptable replies, and drop the click handler
for that case. The existing key is reused rather than adding a new one; a "you
do not have access" wording was rejected because this state covers any failure
to load the event, not only a permission problem.

* Update screenshots

* Trigger CI after recording screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-08-10 11:59:37 +02:00
hayaksi1 09efb04a8f Hold the revealed event ids in a plain set
The store no longer needs a mutableStateSetOf: an ordinary Set kept in a
mutableStateOf does the same job, and matches DefaultMediaPreviewConfigStateStore.

The Compose state itself has to stay. TimelineProtectionPresenter derives
ProtectionState from the store inside a derivedStateOf, so the set must be a
snapshot object for a reveal to invalidate it and reach the timeline. Backing it
with a plain mutableSetOf leaves the presenter with nothing to observe and it
stops emitting after ShowContent.
2026-08-10 10:59:22 +03:00
Eklavya Jandial 19c6526841 [Task] Show active call participants in the people list #7199 (#7300) 2026-08-10 09:40:12 +02:00
hayaksi1 7f56c15fb8 Drop the comments from the empty DM call guard
Review feedback: the member-count condition reads on its own.
2026-08-09 15:33:51 +03:00
hayaksi1 b725d37b0e Do not display pinned events that the client cannot render
The pinned events timeline is built with an exclusion filter rather than an
allowlist, so an event of a type the app has no renderer for reaches both
pinned surfaces. The banner falls through to the formatter catch-all and reads
"Unsupported event", and the list renders an unknown content tile.

Drop unknown content and message-like or state events that failed to parse from
both surfaces, along with any day divider left without an event to introduce,
and show the empty state when nothing renderable remains. The spec makes this
the client's call. Such an event can still be unpinned from the room timeline,
where it is still rendered.

Undecryptable and redacted events are untouched: they carry information the
user needs.
2026-08-09 15:20:13 +03:00
hayaksi1 6533a10ab9 Keep manually revealed media visible when re-entering a room
The set of revealed event ids lived on TimelineProtectionPresenter, which is
scoped to the room graph. That graph is rebuilt every time the room is opened,
so the set was empty on re-entry and every revealed image was hidden again.

Move it into a session scoped TimelineProtectionStore. The store is in memory
rather than persisted: revealing media is a privacy control and there is no
hide action today, so keeping the reveals for the session leaves restarting the
app as a way to undo one, and the set is dropped on logout.
2026-08-09 15:19:46 +03:00
hayaksi1 05528dbd3d Let users enter their full Matrix user ID when searching for a homeserver
The account provider search treated its whole input as a host, so a full user
ID was probed as https://@alice:example.org, which never resolves, and the
permissive URL fallback then offered that invalid address as a provider.

Recognise a complete user ID and resolve the homeserver from its server name,
preserving a port when there is one. Input that starts with @ but is not yet a
complete user ID resolves nothing, so no candidate is produced while the user
is still typing. Detection reuses MatrixPatterns.isUserId and UserId.domainName
rather than a new pattern.
2026-08-09 15:19:45 +03:00
hayaksi1 38398c24b2 Show a Message not found placeholder when a replied to message cannot be loaded
When the replied to event could not be fetched, the reply preview rendered the
raw SDK error string in critical styling, and tapping it emitted a focus
request that could never succeed, so the user got a dead end dialog.

Render the localised error_message_not_found string in the neutral italic style
already used for redacted and undecryptable replies, and drop the click handler
for that case. The existing key is reused rather than adding a new one; a "you
do not have access" wording was rejected because this state covers any failure
to load the event, not only a permission problem.
2026-08-09 15:19:45 +03:00
hayaksi1 d04779c8fd Copy a blocked user's Matrix ID by long pressing them
The blocked users list displayed each Matrix ID but offered no way to get it
out of the app, which is what someone who blocked a user for abuse needs in
order to report them onwards.

Long press now copies the Matrix ID and confirms with a snackbar, reusing the
ClipboardHelper and SnackbarDispatcher idiom from the user profile screen. A
short tap still opens the unblock confirmation. The row declares a long click
label so the action is announced by a screen reader. No new string is needed.
2026-08-09 15:09:59 +03:00
hayaksi1 1299b5c897 Hide space children you have left that can only be joined by invitation
After leaving a room listed in a space, the room stayed in the child list with
a Join button, even though it can only be entered with a new invitation. It
disappeared only after leaving and reopening the space, because the server
omits it from the refetched hierarchy.

Apply the same rule locally in the presenter. The filter keys on the LEFT
membership combined with an invite join rule rather than on the derived
visibility, which collapses knock and unknown join rules into private and
would wrongly remove the Join button from knockable rooms.
2026-08-09 15:09:34 +03:00
hayaksi1 aff71cf1b9 Use a dedicated string for the Mute room notification mode
Two of the three modes on the room notification settings screen had
screen-scoped keys; the third reused common_mute, which also labels the Mute
action button on the room details screen. A translator could not fix one
occurrence without breaking the other.

Add screen_room_notification_settings_mode_mute and use it at both places on
that screen. The English value is unchanged, so nothing renders differently.
The action button keeps common_mute, which is the one context where the
generic verb is correct.
2026-08-09 15:09:33 +03:00
hayaksi1 8943c4e724 Drop the comments from the filter selection guard
Review feedback: the guard and the test name already say what the check
is for, so the narration was redundant.
2026-08-09 14:46:13 +03:00
hayaksi1 7ebcb86ee1 Drop the comment on the custom map style branch
Review feedback: the branch already reads as "use the custom url as it
is", so the explanation belongs in the commit rather than the source.
2026-08-09 14:44:30 +03:00
hayaksi1 717efe46c5 Do not offer to start a call in a DM with no other member
A DM whose other member has left still offered the call button. Starting
that call put the user alone in a room nobody could join, with no way out
of the call screen.

The presenter now clears canStartCall for a DM with no other active
member. activeMembersCount counts joined and invited members, so a fresh
DM whose peer has been invited but has not joined yet can still start a
call. Joining an already ongoing call is untouched, so a call started
before the other member left stays reachable.

Relates to https://github.com/element-hq/element-x-android/issues/6189
2026-08-09 04:09:27 +03:00