In the new timeline renderer, the line end position is sometimes incorrectly returned when you pass the offset of the last character in the line, returning `0.0f`.
This caused the shape to draw for the line to be reversed, where the start was `0.0f` and the end was the actual start.
When we detect a `0.0f` returned value for this, just get the coordinates for the end of the line instead.
The RustMatrixClientFactory was using a single RustClientSessionDelegate for
all the clients. The delegate keeps a reference to the last bound client only,
and didReceiveAuthError does not tell which session is concerned. With several
accounts, when the session of one account was revoked, the session of the last
restored account was invalidated and its local data deleted instead, while the
revoked session kept on syncing with an invalid token. Also the isLoggingOut
flag was never reset, so any later auth error was ignored.
The clients which are not associated to a stored session (temporary clients
and clients used to perform a login) now use a NoOpClientSessionDelegate.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add search backfill worker
This will run on background at most once an hour while the device has internet connectivity and the device is charging and start back-paginating through the user's rooms to make sure the search results are populated.
It'll run for the maximum time the default workers allow, 10 minutes.
* Create `RustMatrixClient.Factory` AssistedFactory to help with DI and add `SearchBackfillService`
* Start search backfill when entering the search screen, just once. This should help getting initial search results if none or few are found at first
Toggling this value had no effect because the feature was marked as finished so it wouldn't be displayed in the developer settings, which makes our code ignore any user-set value for it.
Instead, just create a `Feature` outside the `FeatureFlags` enum.
The test was in `libraries.fullscreenintent.test`, while the presenter is in `libraries.fullscreenintent.impl`.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The fakes were in `libraries.voicerecorder.test`, the package of the `voicerecorder/test` module. Move them to `libraries.voicerecorder.impl.audio` and `libraries.voicerecorder.impl.file`.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The test was in `libraries.mediapickers`, while `PickerType` is in
`libraries.mediapickers.api`.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The namespace was `libraries.usersearch`, without the `.test` suffix, while
the sources are in `libraries.usersearch.test`.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The namespace was `libraries.push.pushstore.impl`, while the sources are in
`libraries.pushstore.impl`. Also update the `adb uninstall` hint of the
instrumentation test accordingly.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
Add the `screen.multi_account_announcement.*` keys to the home module
Localazy configuration and import the latest strings.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The permission is granted from the system settings, outside of the app,
so nothing triggered a recomposition of FullScreenIntentPermissionsPresenter
when the user came back. The "Enhance your call experience" banner kept
being displayed until something else caused a recomposition.
Check the permission again with LifecycleResumeEffect, as done in
BatteryOptimizationPresenter, and add a test for this case.
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>
The recovery key was copied without EXTRA_IS_SENSITIVE, so Android 13+
showed it in the clipboard preview and keyboards could store it in
their clipboard history.
Add an isSensitive option to CopyToClipboardUseCase and
Context.copyToClipboard, and set it when copying the recovery key.
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>
- Clear the listener when RustSessionVerificationService is destroyed.
- IncomingVerificationRequestObserver removes the listener of the clients which are not in the MatrixSessionCache anymore.
- Remove the sessions from the MatrixSessionCache when they are removed from the SessionStore (logout, account deactivation).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add remove and clear history buttons to search
* Rename `SearchHistoryResultItem` to `SearchHistoryListItem` and `MessagesSearchResultItem` to `MessageSearchListItem`
Also, add some docs.
* Update screenshots
---------
Co-authored-by: ElementBot <android@element.io>
Replace SessionDetailsView by AccountInfoCard with the DeviceVerification mode
on the incoming device verification screen, so that the account concerned by
the request is clearly indicated, with its avatar and Matrix ID.
The current user is built from the SessionStore, including the locally stored
avatar thumbnail, used as a fallback when the avatar cannot be loaded, for
instance for an account which is not the current one.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Compose 1.13 test libraries start the test window in touch mode, where the editor is
not focusable in Robolectric, so `requestFocus()` was not giving it the focus anymore.
Use `requestFocusFromTouch()`, which leaves the touch mode first.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
The factory lives in libraries/matrix/impl because that is the only module compiled against the Rust SDK, and is app-scoped because a call is started for whichever account it belongs to rather than the one on screen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>