Replace the pairs of true / false toggle tests and their private helpers by
single tests taking a @TestParameter initialState.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add previews for the uninitialized state, the activity / invite / @room switches,
other room notification modes, the message sound dialog with a custom sound and a
single failing push distributor. Group the preview states by screen section.
Each factory now takes exactly the parameters of the object it builds
(aNotificationSettingsState, aValidMatrixSettings, anInvalidMatrixSettings,
anAppSettings, aSoundChannelUiState), and the default message sound display name
matches the default sound.
Fix the push provider test, which needs 2 distributors for the advanced settings
to be displayed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The distributors are now loaded on the IO dispatcher, which was a StandardTestDispatcher in the test, so the initial state could be read before they were loaded. Use an unconfined test dispatcher so that they are loaded deterministically.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Extract the logic to observe the total unread count of a MatrixClient, refreshed on each sync
heartbeat, to a shared extension and use it in HomePresenter and PreferencesRootPresenter.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
In the settings screen, when the other accounts section is expanded, display a counter with the
total number of unread notifications for each non-active account. The count is read from the
account's MatrixClient (if in memory) and refreshed on its sync heartbeat.
Part of #7769
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
Getting the distributors queries the PackageManager and the Play Services, it was done during the first composition of the screen.
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>
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.
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>
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>
Remove the direct logout dialog from the settings and from the home screen, where it was never triggered.
The sign out screen will later display the account information (#7765).
The direct logout is still used in the FTUE session verification screen, so remove only the now unused `canDoDirectSignOut` field.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add an optional thumbnail to `MatrixUser` and `AvatarData`, filled from the session
database for the other accounts in the room list header, the settings and the account
selection screen. `ImageAvatar` renders this thumbnail instead of the initial letter while
the avatar is loading or when it fails to load, for instance when the homeserver of the
current account is not federated with the one of the other account.
Fixes#5571
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PreferencesFlowNode routed navigateToLinkNewDevice() to
callback.navigateToAddAccount(), so tapping "Link new device" under
Account settings opened the "Add an account" screen instead — the
opposite direction, signing an extra account into this device rather
than authorising a new one.
The correct destination was already implemented and simply unreachable:
LoggedInFlowNode handles navigateToLinkNewDevice() by pushing
NavTarget.LinkNewDevice. Call that instead.
Regression from 9b2577f1dd ("Split settings: app settings / account
settings"); the previous code called callback.navigateToLinkNewDevice().
It went unnoticed because FeatureFlags.QrCodeLogin defaults to false,
which hides the entry point on default builds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017y1etzTCPzowrNcPyRBdjm
The item is removed from the account section of the root settings screen and
added at the bottom of the Moderation and safety screen. As before, it is only
shown when at least one user is blocked, with the number of blocked users.
ModerationAndSafetyPresenter now computes the number of blocked users, and
ModerationAndSafetyNode exposes a Callback to navigate to the blocked users
screen. Tests are moved accordingly.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>