The tests and fakes were in `features.viewfolder.test.*`, which looks like a package of a test module, while they are in the `impl` module and test code from `features.viewfolder.impl.*`.
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>
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 `Provider` suffix reads as a dependency provider rather than as preview
data, and it collides with the real providers in the codebase — `StringProvider`,
`PickerProvider`, the login feature's `AccountProvider` — so the name says
nothing about which of the two a class is. `PreviewParam` says it.
195 classes are renamed, along with the 185 files named after them, the konsist
rule that enforces the convention, the presentation-class file templates and the
onboarding documentation.
This cannot be split. `Konsist.scopeFromProduction()` scans the whole project, so
flipping the assertion before every class has moved leaves the rule red, and a
rule that accepted either suffix during a transition would be exactly the kind of
compatibility layer this convention change is meant to remove.
Two judgement calls in the rule itself. The `name.endsWith("PreviewProvider")`
exclusion is dropped: its only job was to reject a redundant `Preview` before
`Provider`, and the new suffix already contains it; no class currently ends with
`PreviewProvider`, so removing it changes nothing today. And
`EditableAvatarViewUriProvider` is renamed rather than deleted from the exclusion
list even though no such class exists in this repository, since it presumably
comes from the modules overlaid for the enterprise build.
Nothing keyed off the old suffix: no snapshot filename contains a provider class
name, so no Paparazzi image changes, and the Kover variants match on `*Presenter`,
`*State` and `*ViewKt`, so coverage bounds are unaffected.
Cover the last remaining interfaces across features/announcement, cachecleaner,
call, contentscanner, createroom, knockrequests, lockscreen, rolesandpermissions,
startchat, userprofile and viewfolder, with their members and parameters.
Grouped into one commit rather than eleven near-empty ones, per the AGENTS.md rule
about tiny commits.
This completes every features/* api module.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DefaultFileSave had no test at all and AndroidLocalMediaActions only exercised the
failing path, so neither the uniquifying retry nor the new IOException on a null
insert was ever executed.
FakeMediaStoreContentProvider stands in for the media authority: it records the
display names an insert is attempted with, keeps whatever is copied into it, and can
either collide a name the way MediaStore does past 32 files or refuse to create
anything. Both call sites now go through it for the plain save, the retry and the
rejected insert.
Its name cannot follow the Fake<Interface> convention because it extends the
framework ContentProvider, so it joins the existing exceptions in
KonsistClassNameTest next to FakeFileSystem and FakeKeyStore.
MediaStore de-duplicates the display name of a new file itself, but its
uniquifier gives up after 32 collisions and throws IllegalStateException.
Saving then failed with "Sorry, an error occurred" and wrote nothing, and
because image.png is the name most screenshots arrive with, a user who
saves media regularly could reach a state where that name never saved
again without deleting files from Downloads by hand.
A new saveWithUniqueFileName helper in androidutils retries the insert
once with a suffixed name when the platform reports it cannot build a
unique one; a second failure propagates so genuine errors still surface.
withFileNameSuffix builds that name by inserting the suffix before the
extension, and handles names without one.
Both call sites are fixed: AndroidLocalMediaActions and DefaultFileSave
carried byte-identical logic and therefore the identical defect. While in
AndroidLocalMediaActions, a null output uri from ContentResolver.insert
now throws instead of reporting success without writing anything.
The pre-Android-Q path is untouched: it overwrites rather than
uniquifying, so it never reaches this limit.
Relates to https://github.com/element-hq/element-x-android/issues/6371
* Update metro to v0.11.0
* Fix `@AssistedInject` usages
Now the injected variables in the factories must match the names in the constructors
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
* Update metro to v0.6.7
* Replace `@Inject` with `@AssistedInject` where needed
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
- Add `runCatchingExceptions` and `mapCatchingExceptions` to replace `runCatching` and `mapCatching`.
- Make `tryOrNull { ... }` catch only exceptions too.
- Apply the changes to the whole project.
- Add new Rust fakes for tests to handle the code that's now unblocked - previously it just threw an `UnsatisfiedLinkError` which we ignored.
- Add a new `detekt-rules` project with a `RunCatchingRule` to prevent `runCatching` and `mapCatching` usages.
2 replace all actions have been performed:
- "SPDX-License-Identifier: AGPL-3.0-only" to "SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial"
- "Please see LICENSE in the repository root for full details." to "Please see LICENSE files in the repository root for full details."