Commit Graph

6386 Commits

Author SHA1 Message Date
Benoit Marty 055fe408a6 Add KDoc to the features/roommembermoderation API interfaces
Document RoomMemberModerationState, RoomMemberModerationEvents and
RoomMemberModerationRenderer along with their members and parameters.

The renderer doc states that it draws nothing until the host screen asks for a
member's actions, and that onSelectAction exists so the host can navigate for the
actions that need a screen of their own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:06:53 +02:00
Benoit Marty 50214fe01a Add KDoc to the features/poll API interfaces
Document PollContentStateFactory, SendPollResponseAction and EndPollAction along
with their members and parameters.

The two action interfaces exist to wrap a plain timeline call, so their docs say
what they add: both capture an analytics event on success, which is the reason
callers should go through them rather than calling the timeline directly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:06:47 +02:00
Benoit Marty 76411b07fb Add KDoc to the features/leaveroom API interfaces
Document LeaveRoomState, LeaveRoomEvent and LeaveRoomRenderer.

The renderer doc records the two things a host screen needs to know, both taken
from LeaveRoomPresenter and LeaveRoomView: it draws nothing until a leave event is
sent, and onSelectNewOwners fires specifically when the user is the last owner of
a room that still has other members.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:05:31 +02:00
Benoit Marty bc6f237507 Add KDoc to the features/invitepeople API interfaces
Document InvitePeopleState and each of its properties, InvitePeopleEvents,
InvitePeopleRenderer and the presenter factory.

The state properties now say what drives them, in particular that
createRoomFromDmAction covers the case of inviting a third person into an
existing direct message, and that the factory accepts a null room for that flow.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:04:31 +02:00
Benoit Marty 186d5b65b9 Add KDoc to the features/messages API interfaces
Document HtmlConverterProvider, MessageComposerContext,
PinnedEventsTimelineProvider, the MessagesEntryPoint node proxy and the voice
message composer factory.

HtmlConverterProvider carries the ordering constraint that matters: the converter
is rebuilt from the Compose theme, so Update has to be composed before provide is
called.

MessagesEntryPoint and its Callback are navigation plumbing and out of scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:02:48 +02:00
Benoit Marty 7f3d896a3e Add KDoc to the features/enterprise API interfaces
Document EnterpriseService, SessionEnterpriseService and
RemoteEnterpriseConfigProvider along with all their members and parameters.

Two points that callers get wrong are stated explicitly: these services return
permissive defaults on a standard build, so there is no need to branch on the
build type, and SessionEnterpriseService only answers meaningfully once init has
run. The many nullable getters now say what null means in each case, which is
generally "no override, use the app default".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 10:01:14 +02:00
Benoit Marty 8bf5b9dd6f Merge pull request #7349 from hayaksi1/fix/4757-timeline-grouping-timeout
Do not group timeline messages sent more than five minutes apart
2026-08-13 09:23:01 +02:00
Benoit Marty 1abe26f4d8 Merge pull request #7354 from hayaksi1/fix/5319-linkify-matrix-uri
Turn a matrix: URI in a message into a pill
2026-08-13 09:17:32 +02:00
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 f0e791001f Drop the comments from the matrix URI pillification
Review feedback: the regex name and the test names carry the meaning.
2026-08-09 15:39:18 +03: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