* 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>
* Fix timestamp color to match the designs.
* Don't limit the call and unread row height to 16dp: the font size is not fixed and it might display components in a broken state
* Ensure the alignment works
* Remove `SemanticColors.unreadIndicator` and use `.iconAccentPrimary` and `.textActionAccent` instead
* Simplify and document `UnreadIndicatorAtom`
* Use `fontBodySmMedium` for the font size in the unread indicator
* Update screenshots
---------
Co-authored-by: ElementBot <android@element.io>
The matrixmedia modules were using the `libraries.matrix.ui.media` package
(shared with the matrixui module) and `libraries.matrix.ui.media.*`
namespaces. Use `libraries.matrixmedia.api`, `libraries.matrixmedia.impl`
and `libraries.matrixmedia.test` instead, matching the module paths.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Some modules were using package names or namespaces inherited from copy-paste
or from older module names (e.g. `features.logout.impl` in the deactivation
module, `features.api` in the migration api module, `sessionstorage` in the
cachestore module), or containing typos (`roomaliasesolver`,
`roomdetetailsedit`).
Move the sources to the package matching their module, update the imports, and
rename the impacted screenshots accordingly.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Since Android 13, the system displays its own confirmation when content
is copied to the clipboard, so the application does not render its own
Toast or Snackbar anymore on those versions.
Context.copyToClipboard, CopyToClipboardUseCase and the direct
ClipboardManager usage in EventDebugInfoView are removed.
ClipboardHelper.copyPlainText(text, isSensitive, onSuccessOnOldDevice)
is now the only entry point, and AndroidClipboardHelper is the only
class using ClipboardManager.
Copy actions from the views are moved to their Presenter through new
events, or to the Node when there is no Presenter. A ToastHelper is
introduced so that Toasts are kept where they were used before.
Snackbars are kept where they were already used.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Remove dependencies flagged as unused by the Dependency Analysis Gradle Plugin
(`./gradlew buildHealth`) and explicitly declared in module build files.
Removals were skipped when the dependency provides transitively something the
module (or a consumer of an `api` dependency) uses directly, as well as for
runtime-only dependencies (element-call-embedded, sentry-android,
rustls-platform-verifier). Dependencies added by the convention plugin helpers
(composeDependencies, testCommonDependencies) are left untouched.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Allow displaying only unread notifications
Add `FeatureFlags.ShowAllActivityInRoomList` (enabled by default, to match the current behavior) that, when disabled, will display the unread messages of a room instead of unread notifications if no unread notifications are found
* Restore UI changes to the badges, `RoomSummaryRow` and `HorizontalFloatingToolbar`
* Fix `NavigationBarIcon`: use `BadgeBox` component.
* Adjust padding in `RoomSummaryRow` to 6.dp
* Fix other indicators not displaying a dot anymore
* Update screenshots
---------
Co-authored-by: ElementBot <android@element.io>
Many Material3 APIs are now stable, so the `ExperimentalMaterial3Api` and `ExperimentalMaterial3ExpressiveApi`
opt-ins are not required anymore at those places. Also remove the propagating `@ExperimentalMaterial3Api`
marker from `TopAppBarScrollBehaviorLayout`, which does not use experimental API anymore.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Bump SDK bindings to `v26.09.26`
This version contains a fix for issues in `v26.09.25` related to certificate verification.
* Fix breaking API changes in the latest bindings
* Unify `FeatureFlags.RoomThreadList` with `FeatureFlags.Threads`
* Fix forwarding an event not working in threads
Add the `TimelineProvider` for the event to the navigation flow so the events can be fetched from the right timeline.
* Integrate the new renderer with the timeline UI
* Composable functions are now in `:libraries:htmlrenderer:api` so we don't need to add `impl` to other modules.
* Improve inline code span
* Return both the text and URL in `onLinkClick` and `onLinkLongClick` so we can check the URL is not misleading
* Remove `SelectionContainer` for now - it creates issues when long pressing
* Make `LocalComposeTimelineEventRenderer` contain a `ComposeLocalTimelineEventRendererData` instance. This checks if the new rendering is enabled and what is the current user id so it can be used for styling mention pills
* Add fading edges to code block to indicate scrolling is possible
* Long pressing in a code block copies its contents to the clipboard
* Fix alignment of ordered list item prefixes
* Don't use default values in State data classes
---------
Co-authored-by: ElementBot <android@element.io>
* Add linear animation to voice message playback progress
Instead of animating the small `progress` value changes, calculate an animation for the range `maxProgress - progress`, with a linear interpolator so it's completely smooth. Previously, the progress was updated in 'steps' that were quite noticeable.
* Added HTML parser to abstract tree nodes
* Add HTML renderer using `HtmlMessageContent`
* Add custom rendering for inline code nodes besides the monospace font
* Support `<s>` and `<strike>` too
* Add `ContentAvoidingLayoutData` support
* Improve the last block node behaviour and its integration with `ContentAvoidingLayout`
* Move `ContentAvoidingLayout` to `:libraries:ui-common` so it can be shared
* Add missing `:libraries:htmlrenderer:impl` entry in `DependencyHandlerScope.allLibrariesImpl`
* Update screenshots
---------
Co-authored-by: ElementBot <android@element.io>
detekt's default configuration excludes test source sets from
`TooManyFunctions` and `StringLiteralDuplication`, but not from
`LargeClass`, so large test classes were reported and had to carry a
`@Suppress("LargeClass")` annotation.
Add the same kind of exclusion to the `LargeClass` rule in
`tools/detekt/detekt.yml` and remove the 24 now-redundant suppressions
from test files. The two remaining suppressions are in production code,
where the rule still applies.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The problem seemed to be sometimes the background work to switch from live timeline to a focused event timeline wasn't finished in time and an assertion failed from time to time.
By providing the coroutine to run this on we can pass a `TestScope` and force it to reliably run immediately instead in unit tests.