This is mostly done when uploading bug reports and on one hand, it doesn't really make sense since the binary contents will be unreadable anyway, and on the other it also messes up with our debug tools, making debugging some issues harder.
The case where we move the pointer once we've started the click on a link wasn't taken into account, so the click or long click gestures weren't canceled if the gesture ended up being a 'move' one.
Simplify the handler and make it more idiomatic too.
The `File.length()` docs state:
> Returns the length of the file denoted by this abstract pathname. The return value is unspecified if this pathname denotes a directory.
On Android, it *seems* to currently have the right behaviour, summing up the size of its children, which made `File.getSizeOfFiles()` double-count the size of some directories.
To avoid this, and be able to control the actual behaviour no matter what future Android versions do, let's count those ourselves.
PreferencesRootPresenter and HomePresenter were updating the latest session
in the session store directly, relying on RootNavStateFlow to trigger the
navigation as a side effect. Changing the current session is app-level
navigation, so it is now forwarded through a new `navigateToSession` callback
up to RootFlowNode, which performs the session store update.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Remove the default values from the Gradle file, the public MapTiler defaults
are now only defined in MapTilerDefaults. buildConfigFieldStr now accepts a
null value.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The map URL builders now only use the MapTilerConfig they are given, falling
back to the public MapTiler defaults for the missing values, instead of the
values defined at build time. This avoids for instance sending the build time
API key to a tile server provided by the homeserver.
When there is no config, no static map URL builder is created, so no request
is performed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
LocationService now exposes the MapTiler config to use: the one provided by the
homeserver takes precedence over the build time one, and null means that no map
provider is configured. It is now session scoped, and isServiceAvailable()
returns a StateFlow derived from this config.
When no config is available:
- the location sharing option is hidden from the composer, and location events
cannot be opened in the location viewer;
- the "Location sharing" entry is hidden from the settings;
- location events in the timeline render a placeholder, without performing any
request to MapTiler.
The show and share location screens now get the config from LocationService
rather than fetching the homeserver config by themselves.
Closeselement-hq/element-android-enterprise#69
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add total unread notification count to home screen
This will be calculated on each sync heartbeat (for now, using the state updates for the room list service).
* Simplify `counter` parameter logic
* Read the total unread count when the home screen is first displayed
---------
Co-authored-by: Benoit Marty <benoitm@element.io>
* Update Matrix Rust SDK to 26.10.07-nightly
* Adapt to the new QR code login task API
`generate()` and `scan()` of `GrantLoginWithQrCodeHandler` and `LoginWithQrCodeHandler`
now return a task instead of suspending until the flow is over. Wait for the task to
complete, and cancel it if the coroutine is cancelled, so that the flow is also stopped
on the Rust side.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add tests for the cancellation of the QR code login tasks
Check that cancelling the coroutine of the link new device handlers and of the QR code
login cancels the task returned by the SDK, so that the flow is stopped on the Rust side.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Fix import ordering in the link new device handler tests
ktlint expects the imports to be sorted in lexicographic order.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`getUserProfile()` was storing the user profile (DB read, avatar Base64 encoding, DB write) on the caller
dispatcher, i.e. the main thread when called from a presenter, causing glitches in the screen transition.
- Run the whole `getUserProfile()` on the session dispatcher.
- Make `DatabaseSessionStore` main-safe by running the queries on the IO dispatcher.
- Do not refresh the profile twice from the settings screen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Render an AccountInfoCard with the current user on the "Confirm your digital identity" screen,
so the user knows which account needs to be verified.
Closes#7898
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The incoming share is now displayed on top of the root, so the FTUE, and the session verification in particular, could be bypassed.
- When the current account is not verified, wait for the FTUE to be complete before displaying the incoming share, as before.
- When the user selects another account which is not verified in the room select screen, display the session verification flow of
the FTUE for this account on top of the share. As in the FTUE, the user has to verify the session or to sign out.
- Expose the FTUE session verification flow with a new SessionVerificationEntryPoint, displayed by OtherSessionVerificationNode
which sets up the session graph of the account to verify.
- Introduce RoomSelectNavigator so that RoomSelectPresenter can request the verification of the selected session.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Scroll the list to the top using a LaunchedEffect instead of recreating the LazyListState on each search query change.
- Use isBlank to check the search query, to match the logic of RoomSelectSearchDataSource.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Use try/finally instead of the awaitClose block, so that the entries stream, the controller and the
dynamic adapters are destroyed even if the suspending onControllerCreated callback is cancelled or
throws before awaitClose is reached.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The enterprise repository is private, so only mention the number of new
commits in the generated PR description.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Expose edit/redaction send states and retry/abort send from the Rust SDK
Pending edits and redactions have their own send queue entries, separate
from the original event. Surface them so the UI can reflect and act on them:
- Add `SendTarget` (Event, Edit, Redaction, Reaction) to the matrix API,
with a mapper to the Rust SDK type.
- Add `editSendState` and `redactionSendState` to `EventTimelineItem` and
map them from the SDK item.
- Add `Timeline.retrySend` / `Timeline.abortSend`, which take a `SendTarget`
so the right queued request is retried or removed. Implement them in
`RustTimeline` and in `FakeTimeline`.
* Track edit and redaction send states on timeline events
`TimelineItem.Event` now carries `editSendState` and `redactionSendState`
next to `localSendState`.
- `failedToSend` is true when any of the three states is failed, so a
failed edit or redaction is shown like a failed message.
- `pendingSend()` returns the first pending state together with its
`SendTarget`; the read receipt row, the send failure dialog and the
timeline presenter use it instead of reading `localSendState` directly.
- `TimelineItemReadReceiptView` is restructured so the row is only
rendered when there is something to show, and the send state takes
precedence over read receipts.
- Update the previews provider and test fixtures for the new fields, and
make `aMessageEvent`'s send state nullable.
* Retry and remove failed sends through the timeline
Retrying or removing a failed message used the event's `SendHandle`, which
only knows about the original send. Route both through the timeline with
the `SendTarget` of the pending request instead:
- `TimelineController` gains `retrySend` (which also re-enables the send
queue) and `abortSend`, acting on the current timeline.
- `MessagesPresenter` retries via `retrySend`, and does nothing when the
event has no pending send state.
- Redacting something that was never sent (no event ID) or a pending
edit/redaction now aborts the queued request rather than sending a
redaction, and no confirmation is asked for.
- Update the presenter tests accordingly.
* Log send queue errors
Log when the SDK reports a send queue error for a room, and when the
send queue is disabled, to help diagnose messages stuck in the queue.
* Make sure we display send queue errors before verification states
* Fix logic for displaying read receipts and add more screenshot tests
* Only use states with read receipts in `ReadReceiptBottomSheetStatePreviewParam`
* Handle `LocalEventSendState = null` state just like `LocalEventSendState.Sent`
* Add `TimelineItemAction.AbortSend` and use it for both:
1. Aborting sending a message/edit/redaction from the 'sending failed' dialog.
2. Abort sending a local message when selected from the timeline -> redact action.
* Update screenshots
---------
Co-authored-by: ElementBot <android@element.io>
When a PR is merged on develop with the enterprise submodule targeting a commit
which is not on the enterprise main branch, open a PR to update it to the latest
commit of main. The workflow also runs daily and manually to keep the submodule
up to date.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Previously, only the small remove button could get the keyboard focus, and the
focus ring was barely visible. Now the whole item is focusable, the focus ring is
drawn around it, and pressing an activation key (Enter, Space, D-pad center)
removes the item. Touch behavior is unchanged: only the remove button is clickable.
Also add a shared `activationKeys` set in the designsystem module.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>