From 17685e8759cedb7ca515374eada6a2bdd2a68302 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 09:45:40 +0200 Subject: [PATCH 01/37] Fix warning: "'setter for config: ConfigurableFileCollection' is deprecated. Setter will be removed in a future release. Use `from` or `setFrom` instead." --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9272514899..a50b7673e4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -56,7 +56,7 @@ allprojects { // activate all available (even unstable) rules. allRules = true // point to your custom config defining rules to run, overwriting default behavior - config = files("$rootDir/tools/detekt/detekt.yml") + config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { detektPlugins("io.nlopez.compose.rules:detekt:0.1.12") From 996574f2c6b4b22c8f6fd1dcc98e9be97f6675c4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:03:02 +0200 Subject: [PATCH 02/37] Enable detekt rule `PreviewPublic` and fix existing issues. --- .../main/kotlin/io/element/android/x/icon/IconPreview.kt | 4 ++-- .../io/element/android/appnav/loggedin/LoggedInView.kt | 2 +- .../io/element/android/appnav/loggedin/SyncStateView.kt | 2 +- .../io/element/android/appnav/room/LoadingRoomNodeView.kt | 4 ++-- .../analytics/api/preferences/AnalyticsPreferencesView.kt | 4 ++-- .../android/features/analytics/impl/AnalyticsOptInView.kt | 4 ++-- .../createroom/impl/components/RoomPrivacyOption.kt | 4 ++-- .../createroom/impl/configureroom/ConfigureRoomView.kt | 4 ++-- .../features/createroom/impl/root/CreateRoomRootView.kt | 4 ++-- .../android/features/location/api/StaticMapView.kt | 2 +- .../location/api/internal/StaticMapPlaceholder.kt | 2 +- .../features/location/impl/send/SendLocationView.kt | 2 +- .../login/impl/accountprovider/AccountProviderView.kt | 4 ++-- .../features/login/impl/changeserver/ChangeServerView.kt | 4 ++-- .../android/features/login/impl/oidc/webview/OidcView.kt | 4 ++-- .../changeaccountprovider/ChangeAccountProviderView.kt | 4 ++-- .../confirmaccountprovider/ConfirmAccountProviderView.kt | 4 ++-- .../searchaccountprovider/SearchAccountProviderView.kt | 4 ++-- .../features/messages/impl/actionlist/ActionListView.kt | 2 +- .../impl/attachments/preview/AttachmentsPreviewView.kt | 2 +- .../features/messages/impl/forward/ForwardMessagesView.kt | 4 ++-- .../messages/impl/media/viewer/MediaViewerView.kt | 2 +- .../features/messages/impl/report/ReportMessageView.kt | 4 ++-- .../features/messages/impl/timeline/TimelineView.kt | 2 +- .../impl/timeline/components/TimelineItemReactionsView.kt | 8 ++++---- .../impl/timeline/components/group/GroupHeaderView.kt | 4 ++-- .../android/features/preferences/impl/about/AboutView.kt | 4 ++-- .../preferences/impl/analytics/AnalyticsSettingsView.kt | 4 ++-- .../preferences/impl/developer/DeveloperSettingsView.kt | 4 ++-- .../features/preferences/impl/root/PreferencesRootView.kt | 4 ++-- .../rageshake/api/preferences/RageshakePreferencesView.kt | 4 ++-- .../features/rageshake/impl/bugreport/BugReportView.kt | 4 ++-- .../android/features/roomdetails/impl/RoomDetailsView.kt | 4 ++-- .../features/roomdetails/impl/edit/RoomDetailsEditView.kt | 4 ++-- .../roomdetails/impl/invite/RoomInviteMembersView.kt | 4 ++-- .../roomdetails/impl/members/RoomMemberListView.kt | 4 ++-- .../impl/members/details/RoomMemberDetailsView.kt | 4 ++-- .../features/verifysession/impl/VerifySelfSessionView.kt | 4 ++-- .../designsystem/atomic/atoms/InfoListItemMolecule.kt | 2 +- .../designsystem/components/LabelledTextField.kt | 4 ++-- .../android/libraries/designsystem/components/PinIcon.kt | 2 +- .../libraries/designsystem/components/avatar/Avatar.kt | 2 +- .../matrix/ui/components/AvatarActionBottomSheet.kt | 4 ++-- .../libraries/matrix/ui/components/MatrixUserHeader.kt | 4 ++-- .../matrix/ui/components/MatrixUserHeaderPlaceholder.kt | 4 ++-- .../libraries/matrix/ui/components/UnsavedAvatar.kt | 4 ++-- .../android/libraries/permissions/api/PermissionsView.kt | 4 ++-- .../android/libraries/textcomposer/TextComposer.kt | 6 +++--- .../android/libraries/theme/MaterialThemeColors.kt | 4 ++-- tools/detekt/detekt.yml | 2 +- 50 files changed, 90 insertions(+), 90 deletions(-) diff --git a/app/src/main/kotlin/io/element/android/x/icon/IconPreview.kt b/app/src/main/kotlin/io/element/android/x/icon/IconPreview.kt index 49c2cc5782..52e3af1aab 100644 --- a/app/src/main/kotlin/io/element/android/x/icon/IconPreview.kt +++ b/app/src/main/kotlin/io/element/android/x/icon/IconPreview.kt @@ -28,7 +28,7 @@ import io.element.android.x.R @Preview @Composable -fun IconPreview( +internal fun IconPreview( modifier: Modifier = Modifier, ) { Box(modifier = modifier) { @@ -39,7 +39,7 @@ fun IconPreview( @Preview @Composable -fun RoundIconPreview( +internal fun RoundIconPreview( modifier: Modifier = Modifier, ) { Box(modifier = modifier.clip(shape = CircleShape)) { diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt index 60784ea4ed..964cb447aa 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt @@ -58,7 +58,7 @@ fun LoggedInView( @DayNightPreviews @Composable -fun LoggedInViewPreview(@PreviewParameter(LoggedInStateProvider::class) state: LoggedInState) = ElementPreview { +internal fun LoggedInViewPreview(@PreviewParameter(LoggedInStateProvider::class) state: LoggedInState) = ElementPreview { LoggedInView( state = state ) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt index 5108bb8716..bdec2b528f 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SyncStateView.kt @@ -91,7 +91,7 @@ private fun SyncState.mustBeVisible() = when (this) { @DayNightPreviews @Composable -fun SyncStateViewPreview() = ElementPreview { +internal fun SyncStateViewPreview() = ElementPreview { // Add a box to see the shadow Box(modifier = Modifier.padding(24.dp)) { SyncStateView( diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/LoadingRoomNodeView.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/LoadingRoomNodeView.kt index ae5ae4f8db..6adc4a026b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/LoadingRoomNodeView.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/LoadingRoomNodeView.kt @@ -123,12 +123,12 @@ private fun LoadingRoomTopBar( @Preview @Composable -fun LoadingRoomNodeViewLightPreview(@PreviewParameter(LoadingRoomStateProvider::class) state: LoadingRoomState) = +internal fun LoadingRoomNodeViewLightPreview(@PreviewParameter(LoadingRoomStateProvider::class) state: LoadingRoomState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun LoadingRoomNodeViewDarkPreview(@PreviewParameter(LoadingRoomStateProvider::class) state: LoadingRoomState) = +internal fun LoadingRoomNodeViewDarkPreview(@PreviewParameter(LoadingRoomStateProvider::class) state: LoadingRoomState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt index f6d77226b9..5aa9287d86 100644 --- a/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt +++ b/features/analytics/api/src/main/kotlin/io/element/android/features/analytics/api/preferences/AnalyticsPreferencesView.kt @@ -81,12 +81,12 @@ fun buildAnnotatedStringWithColoredPart( @Preview @Composable -fun AnalyticsPreferencesViewLightPreview(@PreviewParameter(AnalyticsPreferencesStateProvider::class) state: AnalyticsPreferencesState) = +internal fun AnalyticsPreferencesViewLightPreview(@PreviewParameter(AnalyticsPreferencesStateProvider::class) state: AnalyticsPreferencesState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun AnalyticsPreferencesViewDarkPreview(@PreviewParameter(AnalyticsPreferencesStateProvider::class) state: AnalyticsPreferencesState) = +internal fun AnalyticsPreferencesViewDarkPreview(@PreviewParameter(AnalyticsPreferencesStateProvider::class) state: AnalyticsPreferencesState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt index a27e6e7399..5453daa0f9 100644 --- a/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt +++ b/features/analytics/impl/src/main/kotlin/io/element/android/features/analytics/impl/AnalyticsOptInView.kt @@ -204,13 +204,13 @@ private fun AnalyticsOptInFooter( @Preview @Composable -fun AnalyticsOptInViewLightPreview(@PreviewParameter(AnalyticsOptInStateProvider::class) state: AnalyticsOptInState) = ElementPreviewLight { +internal fun AnalyticsOptInViewLightPreview(@PreviewParameter(AnalyticsOptInStateProvider::class) state: AnalyticsOptInState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun AnalyticsOptInViewDarkPreview(@PreviewParameter(AnalyticsOptInStateProvider::class) state: AnalyticsOptInState) = ElementPreviewDark { +internal fun AnalyticsOptInViewDarkPreview(@PreviewParameter(AnalyticsOptInStateProvider::class) state: AnalyticsOptInState) = ElementPreviewDark { ContentToPreview(state) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt index 1d900cea8c..302f72d514 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt @@ -93,11 +93,11 @@ fun RoomPrivacyOption( @Preview @Composable -fun RoomPrivacyOptionLightPreview() = ElementPreviewLight { ContentToPreview() } +internal fun RoomPrivacyOptionLightPreview() = ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun RoomPrivacyOptionDarkPreview() = ElementPreviewDark { ContentToPreview() } +internal fun RoomPrivacyOptionDarkPreview() = ElementPreviewDark { ContentToPreview() } @Composable private fun ContentToPreview() { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 9ac8f0fbde..7f533510bd 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -277,12 +277,12 @@ private fun Modifier.clearFocusOnTap(focusManager: FocusManager): Modifier = @Preview @Composable -fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = +internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun ConfigureRoomViewDarkPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = +internal fun ConfigureRoomViewDarkPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt index ac8a05f448..7411dfdae8 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -205,12 +205,12 @@ fun CreateRoomActionButton( @Preview @Composable -fun CreateRoomRootViewLightPreview(@PreviewParameter(CreateRoomRootStateProvider::class) state: CreateRoomRootState) = +internal fun CreateRoomRootViewLightPreview(@PreviewParameter(CreateRoomRootStateProvider::class) state: CreateRoomRootState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun CreateRoomRootViewDarkPreview(@PreviewParameter(CreateRoomRootStateProvider::class) state: CreateRoomRootState) = +internal fun CreateRoomRootViewDarkPreview(@PreviewParameter(CreateRoomRootStateProvider::class) state: CreateRoomRootState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt index 39b3e8a9a1..50d400092a 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt @@ -120,7 +120,7 @@ fun StaticMapView( @DayNightPreviews @Composable -fun StaticMapViewPreview() = ElementPreview { +internal fun StaticMapViewPreview() = ElementPreview { StaticMapView( lat = 0.0, lon = 0.0, diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt index d36ead5b28..84349d97c9 100644 --- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt +++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt @@ -79,7 +79,7 @@ internal fun StaticMapPlaceholder( @DayNightPreviews @Composable -fun StaticMapPlaceholderPreview( +internal fun StaticMapPlaceholderPreview( @PreviewParameter(BooleanParameterProvider::class) values: Boolean ) = ElementPreview { StaticMapPlaceholder( diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt index cdaca94b04..cfb30a5523 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt @@ -224,7 +224,7 @@ fun SendLocationView( @DayNightPreviews @Composable -fun SendLocationViewPreview( +internal fun SendLocationViewPreview( @PreviewParameter(SendLocationStateProvider::class) state: SendLocationState ) = ElementPreview { SendLocationView( diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt index 378859225e..ecc2f996cb 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/accountprovider/AccountProviderView.kt @@ -114,12 +114,12 @@ fun AccountProviderView( @Preview @Composable -fun AccountProviderViewLightPreview(@PreviewParameter(AccountProviderProvider::class) item: AccountProvider) = +internal fun AccountProviderViewLightPreview(@PreviewParameter(AccountProviderProvider::class) item: AccountProvider) = ElementPreviewLight { ContentToPreview(item) } @Preview @Composable -fun AccountProviderViewDarkPreview(@PreviewParameter(AccountProviderProvider::class) item: AccountProvider) = +internal fun AccountProviderViewDarkPreview(@PreviewParameter(AccountProviderProvider::class) item: AccountProvider) = ElementPreviewDark { ContentToPreview(item) } @Composable diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt index f9e9624503..ffa337fba7 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt @@ -71,12 +71,12 @@ fun ChangeServerView( @Preview @Composable -fun ChangeServerViewLightPreview(@PreviewParameter(ChangeServerStateProvider::class) state: ChangeServerState) = +internal fun ChangeServerViewLightPreview(@PreviewParameter(ChangeServerStateProvider::class) state: ChangeServerState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun ChangeServerViewDarkPreview(@PreviewParameter(ChangeServerStateProvider::class) state: ChangeServerState) = +internal fun ChangeServerViewDarkPreview(@PreviewParameter(ChangeServerStateProvider::class) state: ChangeServerState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt index c1235b76c5..1b7486e814 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt @@ -100,12 +100,12 @@ fun OidcView( @Preview @Composable -fun OidcViewLightPreview(@PreviewParameter(OidcStateProvider::class) state: OidcState) = +internal fun OidcViewLightPreview(@PreviewParameter(OidcStateProvider::class) state: OidcState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun OidcViewDarkPreview(@PreviewParameter(OidcStateProvider::class) state: OidcState) = +internal fun OidcViewDarkPreview(@PreviewParameter(OidcStateProvider::class) state: OidcState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderView.kt index 0f444350c9..0e35f9eda5 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/changeaccountprovider/ChangeAccountProviderView.kt @@ -127,12 +127,12 @@ fun ChangeAccountProviderView( @Preview @Composable -fun ChangeAccountProviderViewLightPreview(@PreviewParameter(ChangeAccountProviderStateProvider::class) state: ChangeAccountProviderState) = +internal fun ChangeAccountProviderViewLightPreview(@PreviewParameter(ChangeAccountProviderStateProvider::class) state: ChangeAccountProviderState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun ChangeAccountProviderViewDarkPreview(@PreviewParameter(ChangeAccountProviderStateProvider::class) state: ChangeAccountProviderState) = +internal fun ChangeAccountProviderViewDarkPreview(@PreviewParameter(ChangeAccountProviderStateProvider::class) state: ChangeAccountProviderState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt index 2bc002b3fc..faaabf38cd 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt @@ -143,12 +143,12 @@ fun ConfirmAccountProviderView( @Preview @Composable -fun ConfirmAccountProviderViewLightPreview(@PreviewParameter(ConfirmAccountProviderStateProvider::class) state: ConfirmAccountProviderState) = +internal fun ConfirmAccountProviderViewLightPreview(@PreviewParameter(ConfirmAccountProviderStateProvider::class) state: ConfirmAccountProviderState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun ConfirmAccountProviderViewDarkPreview(@PreviewParameter(ConfirmAccountProviderStateProvider::class) state: ConfirmAccountProviderState) = +internal fun ConfirmAccountProviderViewDarkPreview(@PreviewParameter(ConfirmAccountProviderStateProvider::class) state: ConfirmAccountProviderState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt index 84c5bf4fac..8cfaae2a9e 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt @@ -211,12 +211,12 @@ private fun HomeserverData.toAccountProvider(): AccountProvider { @Preview @Composable -fun SearchAccountProviderViewLightPreview(@PreviewParameter(SearchAccountProviderStateProvider::class) state: SearchAccountProviderState) = +internal fun SearchAccountProviderViewLightPreview(@PreviewParameter(SearchAccountProviderStateProvider::class) state: SearchAccountProviderState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun SearchAccountProviderViewDarkPreview(@PreviewParameter(SearchAccountProviderStateProvider::class) state: SearchAccountProviderState) = +internal fun SearchAccountProviderViewDarkPreview(@PreviewParameter(SearchAccountProviderStateProvider::class) state: SearchAccountProviderState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index fd2ad94345..613caba586 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -405,7 +405,7 @@ private fun EmojiButton( @DayNightPreviews @Composable -fun SheetContentPreview( +internal fun SheetContentPreview( @PreviewParameter(ActionListStateProvider::class) state: ActionListState ) = ElementPreview { SheetContent( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt index 6f33ef5d0b..ecdbc183b1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewView.kt @@ -166,7 +166,7 @@ private fun AttachmentsPreviewBottomActions( @Preview @Composable -fun AttachmentsPreviewViewDarkPreview(@PreviewParameter(AttachmentsPreviewStateProvider::class) state: AttachmentsPreviewState) = +internal fun AttachmentsPreviewViewDarkPreview(@PreviewParameter(AttachmentsPreviewStateProvider::class) state: AttachmentsPreviewState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt index 467a963088..1b9a3c5c99 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt @@ -283,12 +283,12 @@ private fun ForwardingErrorDialog(onDismiss: () -> Unit, modifier: Modifier = Mo @Preview @Composable -fun ForwardMessagesViewLightPreview(@PreviewParameter(ForwardMessagesStateProvider::class) state: ForwardMessagesState) = +internal fun ForwardMessagesViewLightPreview(@PreviewParameter(ForwardMessagesStateProvider::class) state: ForwardMessagesState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun ForwardMessagesViewDarkPreview(@PreviewParameter(ForwardMessagesStateProvider::class) state: ForwardMessagesState) = +internal fun ForwardMessagesViewDarkPreview(@PreviewParameter(ForwardMessagesStateProvider::class) state: ForwardMessagesState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerView.kt index 5fb14a6ca0..ff2e4d49f4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerView.kt @@ -255,7 +255,7 @@ private fun ErrorView( @Preview @Composable -fun MediaViewerViewDarkPreview(@PreviewParameter(MediaViewerStateProvider::class) state: MediaViewerState) = +internal fun MediaViewerViewDarkPreview(@PreviewParameter(MediaViewerStateProvider::class) state: MediaViewerState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt index d9851c82a9..7924f07620 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt @@ -168,12 +168,12 @@ fun ReportMessageView( @Preview @Composable -fun ReportMessageViewLightPreview(@PreviewParameter(ReportMessageStateProvider::class) state: ReportMessageState) = +internal fun ReportMessageViewLightPreview(@PreviewParameter(ReportMessageStateProvider::class) state: ReportMessageState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun ReportMessageViewDarkPreview(@PreviewParameter(ReportMessageStateProvider::class) state: ReportMessageState) = +internal fun ReportMessageViewDarkPreview(@PreviewParameter(ReportMessageStateProvider::class) state: ReportMessageState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index d7c259eba2..cecc2d7a63 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -310,7 +310,7 @@ private fun JumpToBottomButton( @DayNightPreviews @Composable -fun TimelineViewPreview( +internal fun TimelineViewPreview( @PreviewParameter(TimelineItemEventContentProvider::class) content: TimelineItemEventContent ) = ElementPreview { val timelineItems = aTimelineItemList(content) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemReactionsView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemReactionsView.kt index 962d3a2b2b..6682a302d2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemReactionsView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemReactionsView.kt @@ -106,7 +106,7 @@ private fun TimelineItemReactionsView( @DayNightPreviews @Composable -fun TimelineItemReactionsViewPreview() = ElementPreview { +internal fun TimelineItemReactionsViewPreview() = ElementPreview { ContentToPreview( reactions = aTimelineItemReactions(count = 1).reactions ) @@ -114,7 +114,7 @@ fun TimelineItemReactionsViewPreview() = ElementPreview { @DayNightPreviews @Composable -fun TimelineItemReactionsViewFewPreview() = ElementPreview { +internal fun TimelineItemReactionsViewFewPreview() = ElementPreview { ContentToPreview( reactions = aTimelineItemReactions(count = 3).reactions ) @@ -122,7 +122,7 @@ fun TimelineItemReactionsViewFewPreview() = ElementPreview { @DayNightPreviews @Composable -fun TimelineItemReactionsViewIncomingPreview() = ElementPreview { +internal fun TimelineItemReactionsViewIncomingPreview() = ElementPreview { ContentToPreview( reactions = aTimelineItemReactions(count = 18).reactions ) @@ -130,7 +130,7 @@ fun TimelineItemReactionsViewIncomingPreview() = ElementPreview { @DayNightPreviews @Composable -fun TimelineItemReactionsViewOutgoingPreview() = ElementPreview { +internal fun TimelineItemReactionsViewOutgoingPreview() = ElementPreview { ContentToPreview( reactions = aTimelineItemReactions(count = 18).reactions, isOutgoing = true diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt index a631e34266..ce853b84b5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/group/GroupHeaderView.kt @@ -91,12 +91,12 @@ fun GroupHeaderView( @Preview @Composable -fun GroupHeaderViewLightPreview() = +internal fun GroupHeaderViewLightPreview() = ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun GroupHeaderViewDarkPreview() = +internal fun GroupHeaderViewDarkPreview() = ElementPreviewDark { ContentToPreview() } @Composable diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/about/AboutView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/about/AboutView.kt index b7c2663b72..81075969c6 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/about/AboutView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/about/AboutView.kt @@ -50,12 +50,12 @@ fun AboutView( @Preview @Composable -fun AboutViewLightPreview(@PreviewParameter(AboutStateProvider::class) state: AboutState) = +internal fun AboutViewLightPreview(@PreviewParameter(AboutStateProvider::class) state: AboutState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun AboutViewDarkPreview(@PreviewParameter(AboutStateProvider::class) state: AboutState) = +internal fun AboutViewDarkPreview(@PreviewParameter(AboutStateProvider::class) state: AboutState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsView.kt index 165406c6f5..3ee7365122 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/analytics/AnalyticsSettingsView.kt @@ -46,12 +46,12 @@ fun AnalyticsSettingsView( @Preview @Composable -fun AnalyticsSettingsViewLightPreview(@PreviewParameter(AnalyticsSettingsStateProvider::class) state: AnalyticsSettingsState) = +internal fun AnalyticsSettingsViewLightPreview(@PreviewParameter(AnalyticsSettingsStateProvider::class) state: AnalyticsSettingsState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun AnalyticsSettingsViewDarkPreview(@PreviewParameter(AnalyticsSettingsStateProvider::class) state: AnalyticsSettingsState) = +internal fun AnalyticsSettingsViewDarkPreview(@PreviewParameter(AnalyticsSettingsStateProvider::class) state: AnalyticsSettingsState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt index 7c5b5d91c8..23ea4faf86 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt @@ -96,12 +96,12 @@ fun FeatureListContent( @Preview @Composable -fun DeveloperSettingsViewLightPreview(@PreviewParameter(DeveloperSettingsStateProvider::class) state: DeveloperSettingsState) = +internal fun DeveloperSettingsViewLightPreview(@PreviewParameter(DeveloperSettingsStateProvider::class) state: DeveloperSettingsState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun DeveloperSettingsViewDarkPreview(@PreviewParameter(DeveloperSettingsStateProvider::class) state: DeveloperSettingsState) = +internal fun DeveloperSettingsViewDarkPreview(@PreviewParameter(DeveloperSettingsStateProvider::class) state: DeveloperSettingsState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt index 90eade31ab..ba8dc05f35 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt @@ -129,12 +129,12 @@ fun DeveloperPreferencesView(onOpenDeveloperSettings: () -> Unit) { @LargeHeightPreview @Composable -fun PreferencesRootViewLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = +internal fun PreferencesRootViewLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = ElementPreviewLight { ContentToPreview(matrixUser) } @LargeHeightPreview @Composable -fun PreferencesRootViewDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = +internal fun PreferencesRootViewDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = ElementPreviewDark { ContentToPreview(matrixUser) } @Composable diff --git a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/preferences/RageshakePreferencesView.kt b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/preferences/RageshakePreferencesView.kt index 73e04fb5d4..3cc2a8211a 100644 --- a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/preferences/RageshakePreferencesView.kt +++ b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/preferences/RageshakePreferencesView.kt @@ -68,12 +68,12 @@ fun RageshakePreferencesView( @Preview @Composable -fun RageshakePreferencesViewLightPreview(@PreviewParameter(RageshakePreferencesStateProvider::class) state: RageshakePreferencesState) = +internal fun RageshakePreferencesViewLightPreview(@PreviewParameter(RageshakePreferencesStateProvider::class) state: RageshakePreferencesState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun RageshakePreferencesViewDarkPreview(@PreviewParameter(RageshakePreferencesStateProvider::class) state: RageshakePreferencesState) = +internal fun RageshakePreferencesViewDarkPreview(@PreviewParameter(RageshakePreferencesStateProvider::class) state: RageshakePreferencesState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt index 74f3a13d13..3748f2931b 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt @@ -176,11 +176,11 @@ fun BugReportView( @Preview @Composable -fun BugReportViewLightPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreviewLight { ContentToPreview(state) } +internal fun BugReportViewLightPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun BugReportViewDarkPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreviewDark { ContentToPreview(state) } +internal fun BugReportViewDarkPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreviewDark { ContentToPreview(state) } @Composable private fun ContentToPreview(state: BugReportState) { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 63868c8227..b3db986bf9 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -321,12 +321,12 @@ internal fun OtherActionsSection(onLeaveRoom: () -> Unit, modifier: Modifier = M @LargeHeightPreview @Composable -fun RoomDetailsLightPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) = +internal fun RoomDetailsLightPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) = ElementPreviewLight { ContentToPreview(state) } @LargeHeightPreview @Composable -fun RoomDetailsDarkPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) = +internal fun RoomDetailsDarkPreview(@PreviewParameter(RoomDetailsStateProvider::class) state: RoomDetailsState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt index 029f5ac5df..ba470d631e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt @@ -287,12 +287,12 @@ private fun Modifier.clearFocusOnTap(focusManager: FocusManager): Modifier = @Preview @Composable -fun RoomDetailsEditViewLightPreview(@PreviewParameter(RoomDetailsEditStateProvider::class) state: RoomDetailsEditState) = +internal fun RoomDetailsEditViewLightPreview(@PreviewParameter(RoomDetailsEditStateProvider::class) state: RoomDetailsEditState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun RoomDetailsEditViewDarkPreview(@PreviewParameter(RoomDetailsEditStateProvider::class) state: RoomDetailsEditState) = +internal fun RoomDetailsEditViewDarkPreview(@PreviewParameter(RoomDetailsEditStateProvider::class) state: RoomDetailsEditState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt index 555f04af20..b53800236e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt @@ -220,12 +220,12 @@ private fun RoomInviteMembersSearchBar( @Preview @Composable -fun RoomInviteMembersLightPreview(@PreviewParameter(RoomInviteMembersStateProvider::class) state: RoomInviteMembersState) = +internal fun RoomInviteMembersLightPreview(@PreviewParameter(RoomInviteMembersStateProvider::class) state: RoomInviteMembersState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun RoomInviteMembersDarkPreview(@PreviewParameter(RoomInviteMembersStateProvider::class) state: RoomInviteMembersState) = +internal fun RoomInviteMembersDarkPreview(@PreviewParameter(RoomInviteMembersStateProvider::class) state: RoomInviteMembersState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 3bfde66c06..bad1dc3591 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -257,12 +257,12 @@ private fun RoomMemberSearchBar( @Preview @Composable -fun RoomMemberListLightPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = +internal fun RoomMemberListLightPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun RoomMemberListDarkPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = +internal fun RoomMemberListDarkPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt index 72b9d4c20c..dcd9232d60 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt @@ -146,12 +146,12 @@ internal fun SendMessageSection(onSendMessage: () -> Unit, modifier: Modifier = @LargeHeightPreview @Composable -fun RoomMemberDetailsViewLightPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) = +internal fun RoomMemberDetailsViewLightPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) = ElementPreviewLight { ContentToPreview(state) } @LargeHeightPreview @Composable -fun RoomMemberDetailsViewDarkPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) = +internal fun RoomMemberDetailsViewDarkPreview(@PreviewParameter(RoomMemberDetailsStateProvider::class) state: RoomMemberDetailsState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt index 77984a3bb2..a116300dc6 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt @@ -242,12 +242,12 @@ internal fun BottomMenu(screenState: VerifySelfSessionState, goBack: () -> Unit) @Preview @Composable -fun VerifySelfSessionViewLightPreview(@PreviewParameter(VerifySelfSessionStateProvider::class) state: VerifySelfSessionState) = +internal fun VerifySelfSessionViewLightPreview(@PreviewParameter(VerifySelfSessionStateProvider::class) state: VerifySelfSessionState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun VerifySelfSessionViewDarkPreview(@PreviewParameter(VerifySelfSessionStateProvider::class) state: VerifySelfSessionState) = +internal fun VerifySelfSessionViewDarkPreview(@PreviewParameter(VerifySelfSessionStateProvider::class) state: VerifySelfSessionState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/InfoListItemMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/InfoListItemMolecule.kt index 6b20c96880..2af9e77b99 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/InfoListItemMolecule.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/InfoListItemMolecule.kt @@ -70,7 +70,7 @@ fun InfoListItemMolecule( @DayNightPreviews @Composable -fun InfoListItemMoleculePreview() { +internal fun InfoListItemMoleculePreview() { ElementPreview { val color = if (isSystemInDarkTheme()) Color.DarkGray else Color.LightGray Column( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledTextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledTextField.kt index cc1d92ccd8..4c790a48e2 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledTextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledTextField.kt @@ -65,11 +65,11 @@ fun LabelledTextField( @Preview @Composable -fun LabelledTextFieldLightPreview() = ElementPreviewLight { ContentToPreview() } +internal fun LabelledTextFieldLightPreview() = ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun LabelledTextFieldDarkPreview() = ElementPreviewDark { ContentToPreview() } +internal fun LabelledTextFieldDarkPreview() = ElementPreviewDark { ContentToPreview() } @Composable private fun ContentToPreview() { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt index c6af3e1cdf..93a0c5d436 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/PinIcon.kt @@ -51,6 +51,6 @@ fun PinIcon( @DayNightPreviews @Composable -fun PinIconPreview() = ElementPreview { +internal fun PinIconPreview() = ElementPreview { PinIcon() } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index b28e52a5ff..1c763a81c3 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -102,7 +102,7 @@ private fun InitialsAvatar( @Preview(group = PreviewGroup.Avatars) @Composable -fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) = +internal fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) = ElementThemedPreview { Row( verticalAlignment = Alignment.CenterVertically, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarActionBottomSheet.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarActionBottomSheet.kt index b12f577c36..d541b534b1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarActionBottomSheet.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarActionBottomSheet.kt @@ -111,12 +111,12 @@ private fun AvatarActionBottomSheetContent( @Preview @Composable -fun AvatarActionBottomSheetLightPreview() = +internal fun AvatarActionBottomSheetLightPreview() = ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun AvatarActionBottomSheetDarkPreview() = +internal fun AvatarActionBottomSheetDarkPreview() = ElementPreviewDark { ContentToPreview() } @Composable diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt index 6054aa53af..a42d44b642 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt @@ -103,12 +103,12 @@ private fun MatrixUserHeaderContent( @Preview @Composable -fun MatrixUserHeaderLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = +internal fun MatrixUserHeaderLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = ElementPreviewLight { ContentToPreview(matrixUser) } @Preview @Composable -fun MatrixUserHeaderDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = +internal fun MatrixUserHeaderDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = ElementPreviewDark { ContentToPreview(matrixUser) } @Composable diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeaderPlaceholder.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeaderPlaceholder.kt index 57901edc03..faa80f82e6 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeaderPlaceholder.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeaderPlaceholder.kt @@ -68,12 +68,12 @@ fun MatrixUserHeaderPlaceholder( @Preview @Composable -fun MatrixUserHeaderPlaceholderLightPreview() = +internal fun MatrixUserHeaderPlaceholderLightPreview() = ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun MatrixUserHeaderPlaceholderDarkPreview() = +internal fun MatrixUserHeaderPlaceholderDarkPreview() = ElementPreviewDark { ContentToPreview() } @Composable diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt index 2b5d2f6800..13fcb40792 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt @@ -85,11 +85,11 @@ fun UnsavedAvatar( @Preview @Composable -fun UnsavedAvatarLightPreview() = ElementPreviewLight { ContentToPreview() } +internal fun UnsavedAvatarLightPreview() = ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun UnsavedAvatarDarkPreview() = ElementPreviewDark { ContentToPreview() } +internal fun UnsavedAvatarDarkPreview() = ElementPreviewDark { ContentToPreview() } @Composable private fun ContentToPreview() { diff --git a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt index 30f19aa31c..d9dba2a0d3 100644 --- a/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt +++ b/libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt @@ -83,12 +83,12 @@ fun PermissionsView( @Preview @Composable -fun PermissionsViewLightPreview(@PreviewParameter(PermissionsViewStateProvider::class) state: PermissionsState) = +internal fun PermissionsViewLightPreview(@PreviewParameter(PermissionsViewStateProvider::class) state: PermissionsState) = ElementPreviewLight { ContentToPreview(state) } @Preview @Composable -fun PermissionsViewDarkPreview(@PreviewParameter(PermissionsViewStateProvider::class) state: PermissionsState) = +internal fun PermissionsViewDarkPreview(@PreviewParameter(PermissionsViewStateProvider::class) state: PermissionsState) = ElementPreviewDark { ContentToPreview(state) } @Composable diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 8c4c361707..09f493adc6 100644 --- a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -415,7 +415,7 @@ private fun BoxScope.SendButton( @DayNightPreviews @Composable -fun TextComposerSimplePreview() = ElementPreview { +internal fun TextComposerSimplePreview() = ElementPreview { Column { TextComposer( onSendMessage = {}, @@ -446,7 +446,7 @@ fun TextComposerSimplePreview() = ElementPreview { @DayNightPreviews @Composable -fun TextComposerEditPreview() = ElementPreview { +internal fun TextComposerEditPreview() = ElementPreview { TextComposer( onSendMessage = {}, onComposerTextChange = {}, @@ -459,7 +459,7 @@ fun TextComposerEditPreview() = ElementPreview { @DayNightPreviews @Composable -fun TextComposerReplyPreview() = ElementPreview { +internal fun TextComposerReplyPreview() = ElementPreview { Column { TextComposer( onSendMessage = {}, diff --git a/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/MaterialThemeColors.kt b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/MaterialThemeColors.kt index d211869f71..3d359594e1 100644 --- a/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/MaterialThemeColors.kt +++ b/libraries/theme/src/main/kotlin/io/element/android/libraries/theme/MaterialThemeColors.kt @@ -91,7 +91,7 @@ internal val materialColorSchemeDark = darkColorScheme( @Preview @Composable -fun ColorsSchemePreviewLight() = ColorsSchemePreview( +internal fun ColorsSchemePreviewLight() = ColorsSchemePreview( Color.Black, Color.White, materialColorSchemeLight, @@ -99,7 +99,7 @@ fun ColorsSchemePreviewLight() = ColorsSchemePreview( @Preview @Composable -fun ColorsSchemePreviewDark() = ColorsSchemePreview( +internal fun ColorsSchemePreviewDark() = ColorsSchemePreview( Color.White, Color.Black, materialColorSchemeDark, diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 0123535b48..cf497b944e 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -149,7 +149,7 @@ Compose: PreviewNaming: active: true PreviewPublic: - active: false + active: true # You can optionally disable that only previews with @PreviewParameter are flagged previewPublicOnlyIfParams: false RememberMissing: From f3974dd5701397bd09aa8093ca0363b1908f2252 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:11:00 +0200 Subject: [PATCH 03/37] Enable detekt rule `ImplicitDefaultLocale` and fix existing issue. --- .../android/libraries/androidutils/system/SystemUtils.kt | 2 +- tools/detekt/detekt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt index 8347990303..a9a17dcceb 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt @@ -183,7 +183,7 @@ fun Context.startInstallFromSourceIntent( noActivityFoundMessage: String = getString(R.string.error_no_compatible_app_found), ) { val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) - .setData(Uri.parse(String.format("package:%s", packageName))) + .setData(Uri.parse("package:$packageName")) try { activityResultLauncher.launch(intent) } catch (activityNotFoundException: ActivityNotFoundException) { diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index cf497b944e..0ed13accdb 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -48,7 +48,7 @@ empty-blocks: potential-bugs: ImplicitDefaultLocale: - active: false + active: true exceptions: TooGenericExceptionCaught: From 9e3679cbd67b96ebf1807e0aed293c6328cd723b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:18:28 +0200 Subject: [PATCH 04/37] Enable detekt rule `UseCheckOrError` and fix existing issues (and a potential crash on MapboxMap?). --- .../confirmaccountprovider/ConfirmAccountProviderPresenter.kt | 2 +- .../io/element/android/libraries/maplibre/compose/MapboxMap.kt | 2 +- .../matrix/impl/auth/RustMatrixAuthenticationService.kt | 2 +- tools/detekt/detekt.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt index 123d3013c7..1a021ad605 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt @@ -92,7 +92,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor( } else if (matrixHomeServerDetails.supportsPasswordLogin) { LoginFlow.PasswordLogin } else { - throw IllegalStateException("Unsupported login flow") + error("Unsupported login flow") } }.getOrThrow() }.runCatchingUpdatingState(loginFlowAction, errorTransform = ChangeServerError::from) diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt index c67be52c1c..82b5e1c237 100644 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt +++ b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt @@ -236,7 +236,7 @@ private fun MapView.lifecycleObserver(previousState: MutableState { //handled in onDispose } - else -> throw IllegalStateException() + Lifecycle.Event.ON_ANY -> Unit } previousState.value = event } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index 0bc299d020..71e6e730e5 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -93,7 +93,7 @@ class RustMatrixAuthenticationService @Inject constructor( client.restoreSession(sessionData.toSession()) createMatrixClient(client) } else { - throw IllegalStateException("No session to restore with id $sessionId") + error("No session to restore with id $sessionId") } }.mapFailure { failure -> failure.mapClientException() diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 0ed13accdb..79d8d5fe51 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -38,7 +38,7 @@ style: ProtectedMemberInFinalClass: active: false UseCheckOrError: - active: false + active: true empty-blocks: EmptyFunctionBlock: From 9894e2fed05c17c93612e2fea1f662b3f2d420a3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:19:25 +0200 Subject: [PATCH 05/37] Enable detekt rule `ProtectedMemberInFinalClass`. --- tools/detekt/detekt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 79d8d5fe51..57754a88bc 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -36,7 +36,7 @@ style: SerialVersionUIDInSerializableClass: active: false ProtectedMemberInFinalClass: - active: false + active: true UseCheckOrError: active: true From d82b47beebf8342ae99467364541581cb74787bf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:23:11 +0200 Subject: [PATCH 06/37] Enable detekt rule `UnnecessaryAbstractClass`, `LoopWithTooManyJumpStatements`, `EmptySecondaryConstructor`. --- tools/detekt/detekt.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 57754a88bc..919a9f74f8 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -9,7 +9,7 @@ style: ReturnCount: active: false UnnecessaryAbstractClass: - active: false + active: true FunctionOnlyReturningConstant: active: false UnusedPrivateMember: @@ -32,7 +32,7 @@ style: ThrowsCount: active: false LoopWithTooManyJumpStatements: - active: false + active: true SerialVersionUIDInSerializableClass: active: false ProtectedMemberInFinalClass: @@ -44,7 +44,7 @@ empty-blocks: EmptyFunctionBlock: active: false EmptySecondaryConstructor: - active: false + active: true potential-bugs: ImplicitDefaultLocale: From f055a25457ccc0bdd4cb417fa976a7bbec02a693 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:33:51 +0200 Subject: [PATCH 07/37] Enable detekt rule `ThrowingExceptionsWithoutMessageOrCause` and fix existing issues. --- .../createroom/impl/root/CreateRoomRootStateProvider.kt | 2 +- .../impl/screens/waitlistscreen/WaitListStateProvider.kt | 2 +- .../attachments/preview/AttachmentsPreviewStateProvider.kt | 2 +- .../messages/impl/media/viewer/MediaViewerStateProvider.kt | 2 +- .../messages/impl/report/ReportMessageStateProvider.kt | 2 +- .../libraries/matrix/api/permalink/PermalinkParser.kt | 6 +++--- tools/detekt/detekt.yml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt index d1484b7a4f..7a3bf6ef03 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt @@ -41,7 +41,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider { get() = sequenceOf( aWaitListState(loginAction = Async.Uninitialized), aWaitListState(loginAction = Async.Loading()), - aWaitListState(loginAction = Async.Failure(Throwable())), + aWaitListState(loginAction = Async.Failure(Throwable("error"))), aWaitListState(loginAction = Async.Failure(Throwable(message = "IO_ELEMENT_X_WAIT_LIST"))), aWaitListState(loginAction = Async.Success(SessionId("@alice:element.io"))), // Add other state here diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt index ee41ace4b0..de7f5cd47b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewStateProvider.kt @@ -30,7 +30,7 @@ open class AttachmentsPreviewStateProvider : PreviewParameterProvider get() = sequenceOf( aMediaViewerState(), aMediaViewerState(Async.Loading()), - aMediaViewerState(Async.Failure(IllegalStateException())), + aMediaViewerState(Async.Failure(IllegalStateException("error"))), aMediaViewerState( Async.Success( LocalMedia(Uri.EMPTY, anImageInfo()) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt index 89e6d7a220..de5e787a3d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt @@ -26,7 +26,7 @@ open class ReportMessageStateProvider : PreviewParameterProvider Date: Wed, 26 Jul 2023 10:34:39 +0200 Subject: [PATCH 08/37] Enable detekt rule `ComplexCondition`, `LargeClass`. --- tools/detekt/detekt.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 37b77ff957..da3735a47e 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -74,9 +74,9 @@ complexity: NestedBlockDepth: active: false ComplexCondition: - active: false + active: true LargeClass: - active: false + active: true naming: VariableNaming: From 5d0bf5dbe0ed595310e5b1a29f3eaf648226e550 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:37:44 +0200 Subject: [PATCH 09/37] Enable detekt rule `InstanceOfCheckForException`. --- tools/detekt/detekt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index da3735a47e..b8c1428c9e 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -60,7 +60,7 @@ exceptions: TooGenericExceptionThrown: active: false InstanceOfCheckForException: - active: false + active: true complexity: TooManyFunctions: From 140271069c641e7b9a6e7201461792c1ff052289 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:38:44 +0200 Subject: [PATCH 10/37] Enable detekt rule `TooGenericExceptionThrown` and fix existing issue. --- .../io/element/android/libraries/architecture/NodeInputs.kt | 2 +- tools/detekt/detekt.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeInputs.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeInputs.kt index b96d9e166b..534c9d741b 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeInputs.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeInputs.kt @@ -23,5 +23,5 @@ import com.bumble.appyx.core.plugin.plugins interface NodeInputs : Plugin inline fun Node.inputs(): I { - return plugins().firstOrNull() ?: throw RuntimeException("Make sure to actually pass NodeInputs plugin to your node") + return requireNotNull(plugins().firstOrNull()) { "Make sure to actually pass NodeInputs plugin to your node" } } diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index b8c1428c9e..d3ee4dc679 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -58,7 +58,7 @@ exceptions: ThrowingExceptionsWithoutMessageOrCause: active: true TooGenericExceptionThrown: - active: false + active: true InstanceOfCheckForException: active: true From 03cefb2c791b65d47b01668cb0640dbb5dd88c57 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 10:48:38 +0200 Subject: [PATCH 11/37] Enable detekt rules `SuspendFunSwallowedCancellation` and `SuspendFunWithCoroutineScopeReceiver`. --- tools/detekt/detekt.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index d3ee4dc679..756d145821 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -40,6 +40,15 @@ style: UseCheckOrError: active: true +coroutines: + GlobalCoroutineUsage: + # Keep false for now. + active: false + SuspendFunSwallowedCancellation: + active: true + SuspendFunWithCoroutineScopeReceiver: + active: true + empty-blocks: EmptyFunctionBlock: active: false From 1d3aa2cd0547cac25f3d9c961e51290fcf41172b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:07:11 +0200 Subject: [PATCH 12/37] Enable detekt rules `CascadingCallWrapping` and fix existing issues. --- .../io/element/android/appnav/LoggedInEventProcessor.kt | 3 ++- .../kotlin/io/element/android/appnav/LoggedInFlowNode.kt | 7 ++++--- .../io/element/android/appnav/room/RoomFlowNode.kt | 3 ++- .../io/element/android/appnav/room/RoomLoadedFlowNode.kt | 3 ++- .../messages/impl/media/viewer/MediaViewerPresenter.kt | 9 ++++++--- .../impl/messagecomposer/MessageComposerPresenter.kt | 3 ++- .../roomlist/impl/datasource/RoomListDataSource.kt | 3 ++- .../libraries/matrix/api/permalink/PermalinkParser.kt | 3 ++- .../android/libraries/matrix/impl/RustMatrixClient.kt | 6 ++++-- .../matrix/impl/room/RustRoomSummaryDataSource.kt | 3 ++- .../libraries/matrix/impl/timeline/RustMatrixTimeline.kt | 3 ++- tools/detekt/detekt.yml | 3 +++ 12 files changed, 33 insertions(+), 16 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInEventProcessor.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInEventProcessor.kt index 64c9ec7c4f..e55f059d14 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInEventProcessor.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInEventProcessor.kt @@ -58,7 +58,8 @@ class LoggedInEventProcessor @Inject constructor( .filter { it } .onEach { displayMessage(CommonStrings.common_verification_complete) - }.launchIn(this) + } + .launchIn(this) } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 4130e5da23..03ac045158 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -44,14 +44,14 @@ import io.element.android.appnav.loggedin.LoggedInNode import io.element.android.appnav.room.RoomFlowNode import io.element.android.appnav.room.RoomLoadedFlowNode import io.element.android.features.createroom.api.CreateRoomEntryPoint +import io.element.android.features.ftue.api.FtueEntryPoint +import io.element.android.features.ftue.api.state.FtueState import io.element.android.features.invitelist.api.InviteListEntryPoint import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.preferences.api.PreferencesEntryPoint import io.element.android.features.roomlist.api.RoomListEntryPoint import io.element.android.features.verifysession.api.VerifySessionEntryPoint -import io.element.android.features.ftue.api.FtueEntryPoint -import io.element.android.features.ftue.api.state.FtueState import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler @@ -305,7 +305,8 @@ class LoggedInFlowNode @AssistedInject constructor( override fun onFtueFlowFinished() { backstack.pop() } - }).build() + }) + .build() } } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt index 20ec9f48b4..661d3c5433 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt @@ -96,7 +96,8 @@ class RoomFlowNode @AssistedInject constructor( } else { backstack.newRoot(NavTarget.Loading) } - }.launchIn(lifecycleScope) + } + .launchIn(lifecycleScope) } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt index 24ec9795f7..b3156bfc84 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt @@ -115,7 +115,8 @@ class RoomLoadedFlowNode @AssistedInject constructor( room.updateMembers() .onFailure { Timber.e(it, "Fail to fetch members for room ${room.roomId}") - }.onSuccess { + } + .onSuccess { Timber.v("Success fetching members for room ${room.roomId}") } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerPresenter.kt index 7cc73ef32e..13a9ff3bee 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/viewer/MediaViewerPresenter.kt @@ -103,14 +103,17 @@ class MediaViewerPresenter @AssistedInject constructor( ) .onSuccess { mediaFile.value = it - }.mapCatching { mediaFile -> + } + .mapCatching { mediaFile -> localMediaFactory.createFromMediaFile( mediaFile = mediaFile, mediaInfo = inputs.mediaInfo ) - }.onSuccess { + } + .onSuccess { localMedia.value = Async.Success(it) - }.onFailure { + } + .onFailure { localMedia.value = Async.Failure(it) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index ec16d3342d..934a67f2e4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -268,7 +268,8 @@ class MessageComposerPresenter @Inject constructor( mediaSender.sendMedia(uri, mimeType, compressIfPossible = false, progressCallback) .onSuccess { attachmentState.value = AttachmentsState.None - }.onFailure { + } + .onFailure { val snackbarMessage = SnackbarMessage(sendAttachmentError(it)) snackbarDispatcher.post(snackbarMessage) attachmentState.value = AttachmentsState.None diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt index 8602f15910..4eb7bc9d72 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListDataSource.kt @@ -73,7 +73,8 @@ class RoomListDataSource @Inject constructor( } .onEach { _filteredRooms.value = it - }.launchIn(coroutineScope) + } + .launchIn(coroutineScope) } fun updateFilter(filterValue: String) { diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkParser.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkParser.kt index 2db607768b..ba9cdc1e80 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkParser.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkParser.kt @@ -137,7 +137,8 @@ object PermalinkParser { .parameterList .filter { it.mParameter == "via" - }.map { + } + .map { URLDecoder.decode(it.mValue, "UTF-8") } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 640e0772a9..8c418cf3e4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -147,7 +147,8 @@ class RustMatrixClient constructor( if (syncState == SyncState.Running) { onSlidingSyncUpdate() } - }.launchIn(sessionCoroutineScope) + } + .launchIn(sessionCoroutineScope) } override suspend fun getRoom(roomId: RoomId): MatrixRoom? { @@ -227,7 +228,8 @@ class RustMatrixClient constructor( roomSummaryDataSource.allRooms() .filter { roomSummaries -> roomSummaries.map { it.identifier() }.contains(roomId.value) - }.first() + } + .first() } roomId } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt index efdbcf34ad..83d35a4183 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt @@ -64,7 +64,8 @@ internal class RustRoomSummaryDataSource( .map { it.toRoomSummaryDataSourceLoadingState() } .onEach { allRoomsLoadingState.value = it - }.launchIn(this) + } + .launchIn(this) launch { // Wait until running, as invites is only available after that diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt index d9b6604170..d55585879f 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt @@ -113,7 +113,8 @@ class RustMatrixTimeline( innerRoom.backPaginationStatusFlow() .onEach { postPaginationStatus(it) - }.launchIn(this) + } + .launchIn(this) fetchMembers() } diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 756d145821..3c9f9b5a25 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -1,6 +1,9 @@ # Default rules: https://github.com/detekt/detekt/blob/main/detekt-core/src/main/resources/default-detekt-config.yml style: + CascadingCallWrapping: + active: true + includeElvis: true MaxLineLength: # Default is 120 maxLineLength: 160 From d433c3cbaacfc0872f6a367fc0f252c11748347b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:10:30 +0200 Subject: [PATCH 13/37] Enable detekt rules `AlsoCouldBeApply` and fix existing issues. --- .../login/impl/oidc/customtab/CustomTabHandler.kt | 3 +-- .../impl/DefaultLastMessageTimestampFormatterTest.kt | 2 +- .../components/avatar/AvatarDataProvider.kt | 11 ++++------- tools/detekt/detekt.yml | 2 ++ 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/customtab/CustomTabHandler.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/customtab/CustomTabHandler.kt index 48c674e0a0..b83c0eb1ac 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/customtab/CustomTabHandler.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/customtab/CustomTabHandler.kt @@ -41,8 +41,7 @@ class CustomTabHandler @Inject constructor( if (packageName != null) { customTabsServiceConnection = object : CustomTabsServiceConnection() { override fun onCustomTabsServiceConnected(name: ComponentName, client: CustomTabsClient) { - customTabsClient = client - .also { it.warmup(0L) } + customTabsClient = client.apply { warmup(0L) } prefetchUrl(url) } diff --git a/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultLastMessageTimestampFormatterTest.kt b/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultLastMessageTimestampFormatterTest.kt index 483e27af71..5aefcdcd7b 100644 --- a/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultLastMessageTimestampFormatterTest.kt +++ b/libraries/dateformatter/impl/src/test/kotlin/io/element/android/libraries/dateformatter/impl/DefaultLastMessageTimestampFormatterTest.kt @@ -101,7 +101,7 @@ class DefaultLastMessageTimestampFormatterTest { * Create DefaultLastMessageFormatter and set current time to the provided date. */ private fun createFormatter(@Suppress("SameParameterValue") currentDate: String): LastMessageTimestampFormatter { - val clock = FakeClock().also { it.givenInstant(Instant.parse(currentDate)) } + val clock = FakeClock().apply { givenInstant(Instant.parse(currentDate)) } val localDateTimeProvider = LocalDateTimeProvider(clock, TimeZone.UTC) val dateFormatters = DateFormatters(Locale.US, clock, TimeZone.UTC) return DefaultLastMessageTimestampFormatter(localDateTimeProvider, dateFormatters) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt index 1727fffd1c..14c7ad3eff 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarDataProvider.kt @@ -20,19 +20,16 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider open class AvatarDataProvider : PreviewParameterProvider { override val values: Sequence - get() { - AvatarSize.values() - .also { it.sortBy { item -> item.name } } - .asSequence() - return AvatarSize.values().asSequence().map { + get() = AvatarSize.values() + .asSequence() + .map { sequenceOf( anAvatarData(size = it), anAvatarData(size = it).copy(name = null), anAvatarData(size = it).copy(url = "aUrl"), ) } - .flatten() - } + .flatten() } fun anAvatarData( diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 3c9f9b5a25..c7a35f61d3 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -1,6 +1,8 @@ # Default rules: https://github.com/detekt/detekt/blob/main/detekt-core/src/main/resources/default-detekt-config.yml style: + AlsoCouldBeApply: + active: true CascadingCallWrapping: active: true includeElvis: true From 8458a9e937489862b53ad6d29fcb83253cc8325b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:15:52 +0200 Subject: [PATCH 14/37] Enable detekt rules `DataClassShouldBeImmutable` and fix existing issues. --- .../impl/notifications/RoomEventGroupInfo.kt | 22 +++++++++---------- .../notifications/RoomGroupMessageCreator.kt | 11 +++++----- .../model/SimpleNotifiableEvent.kt | 2 +- .../firebase/PushDataFirebase.kt | 2 +- .../unifiedpush/PushDataUnifiedPush.kt | 2 +- tools/detekt/detekt.yml | 2 ++ 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt index 734c34b051..96a8b90f06 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt @@ -23,17 +23,15 @@ import io.element.android.libraries.matrix.api.core.SessionId * Data class to hold information about a group of notifications for a room. */ data class RoomEventGroupInfo( - val sessionId: SessionId, - val roomId: RoomId, - val roomDisplayName: String, - val isDirect: Boolean = false -) { + val sessionId: SessionId, + val roomId: RoomId, + val roomDisplayName: String, + val isDirect: Boolean = false, // An event in the list has not yet been display - var hasNewEvent: Boolean = false - + val hasNewEvent: Boolean = false, // true if at least one on the not yet displayed event is noisy - var shouldBing: Boolean = false - var customSound: String? = null - var hasSmartReplyError: Boolean = false - var isUpdated: Boolean = false -} + val shouldBing: Boolean = false, + val customSound: String? = null, + val hasSmartReplyError: Boolean = false, + val isUpdated: Boolean = false, +) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt index 989ba2ad09..0f2b548a52 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt @@ -85,12 +85,11 @@ class RoomGroupMessageCreator @Inject constructor( roomId = roomId, roomDisplayName = roomName, isDirect = !roomIsGroup, - ).also { - it.hasSmartReplyError = smartReplyErrors.isNotEmpty() - it.shouldBing = meta.shouldBing - it.customSound = events.last().soundName - it.isUpdated = events.last().isUpdated - }, + hasSmartReplyError = smartReplyErrors.isNotEmpty(), + shouldBing = meta.shouldBing, + customSound = events.last().soundName, + isUpdated = events.last().isUpdated, + ), threadId = lastKnownRoomEvent.threadId, largeIcon = largeBitmap, lastMessageTimestamp, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt index f252765530..4b262983d4 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt @@ -30,7 +30,7 @@ data class SimpleNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, - override var canBeReplaced: Boolean, + override val canBeReplaced: Boolean, override val isRedacted: Boolean = false, override val isUpdated: Boolean = false ) : NotifiableEvent diff --git a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/PushDataFirebase.kt b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/PushDataFirebase.kt index 9dedf9648f..795c8bb1e8 100644 --- a/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/PushDataFirebase.kt +++ b/libraries/pushproviders/firebase/src/main/kotlin/io/element/android/libraries/pushproviders/firebase/PushDataFirebase.kt @@ -36,7 +36,7 @@ import io.element.android.libraries.pushproviders.api.PushData data class PushDataFirebase( val eventId: String?, val roomId: String?, - var unread: Int?, + val unread: Int?, val clientSecret: String? ) diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/PushDataUnifiedPush.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/PushDataUnifiedPush.kt index f092d0167c..4485cb2c7f 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/PushDataUnifiedPush.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/PushDataUnifiedPush.kt @@ -47,7 +47,7 @@ data class PushDataUnifiedPush( data class PushDataUnifiedPushNotification( @SerialName("event_id") val eventId: String? = null, @SerialName("room_id") val roomId: String? = null, - @SerialName("counts") var counts: PushDataUnifiedPushCounts? = null, + @SerialName("counts") val counts: PushDataUnifiedPushCounts? = null, ) @Serializable diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index c7a35f61d3..e65f3a3864 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -6,6 +6,8 @@ style: CascadingCallWrapping: active: true includeElvis: true + DataClassShouldBeImmutable: + active: true MaxLineLength: # Default is 120 maxLineLength: 160 From 4ba4bd1f56815d75c590fb96bf688e4bf8653ed8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:23:05 +0200 Subject: [PATCH 15/37] Enable more detekt rules and remove unused extension. --- .../core/extensions/BasicExtensions.kt | 4 -- tools/detekt/detekt.yml | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt index db07432df0..343f5ce351 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt @@ -72,7 +72,3 @@ fun String.ellipsize(length: Int): String { return "${this.take(length)}…" } - -inline fun Any?.takeAs(): R? { - return takeIf { it is R } as R? -} diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index e65f3a3864..c9e8aa395b 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -8,6 +8,14 @@ style: includeElvis: true DataClassShouldBeImmutable: active: true + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: true + ExplicitCollectionElementAccessMethod: + active: true + ExplicitItLambdaParameter: + active: true MaxLineLength: # Default is 120 maxLineLength: 160 @@ -65,6 +73,34 @@ empty-blocks: potential-bugs: ImplicitDefaultLocale: active: true + CastNullableToNonNullableType: + active: true + CastToNullableType: + active: true + Deprecation: + active: true + DontDowncastCollectionTypes: + active: true + ElseCaseInsteadOfExhaustiveWhen: + active: true + ExitOutsideMain: + active: true + ImplicitUnitReturnType: + active: true + allowExplicitReturnType: false + MissingPackageDeclaration: + active: true + excludes: ['**/*.kts'] + NullCheckOnMutableProperty: + active: true + NullableToStringCall: + active: true + PropertyUsedBeforeDeclaration: + active: true + UnconditionalJumpStatementInLoop: + active: true + UnnecessaryNotNullCheck: + active: true exceptions: TooGenericExceptionCaught: @@ -77,6 +113,8 @@ exceptions: active: true InstanceOfCheckForException: active: true + ObjectExtendsThrowable: + active: true complexity: TooManyFunctions: @@ -102,10 +140,20 @@ naming: FunctionNaming: active: true ignoreAnnotated: ['Composable'] + LambdaParameterNaming: + active: true + NonBooleanPropertyPrefixedWithIs: + active: true + VariableMaxLength: + active: true performance: SpreadOperator: active: false + CouldBeSequence: + active: true + UnnecessaryPartOfBinaryExpression: + active: true # Note: all rules for `comments` are disabled by default, but I put them here to be aware of their existence comments: From 6fff373613b50b67836e5be46c2e15f05973bf38 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:43:26 +0200 Subject: [PATCH 16/37] Enable detekt rules `OptionalUnit` and fix existing issues. --- .../kotlin/io/element/android/appnav/LoggedInFlowNode.kt | 6 +++--- .../io/element/android/appnav/room/RoomLoadedFlowNode.kt | 4 ++-- .../android/features/invitelist/impl/InviteListPresenter.kt | 3 +-- .../element/android/features/messages/impl/MessagesView.kt | 3 ++- tools/detekt/detekt.yml | 2 ++ 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 03ac045158..a32b860006 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -100,13 +100,13 @@ class LoggedInFlowNode @AssistedInject constructor( ) { interface Callback : Plugin { - fun onOpenBugReport() = Unit + fun onOpenBugReport() } interface LifecycleCallback : NodeLifecycleCallback { - fun onFlowCreated(identifier: String, client: MatrixClient) = Unit + fun onFlowCreated(identifier: String, client: MatrixClient) - fun onFlowReleased(identifier: String, client: MatrixClient) = Unit + fun onFlowReleased(identifier: String, client: MatrixClient) } data class Inputs( diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt index b3156bfc84..d00c4791f7 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomLoadedFlowNode.kt @@ -75,8 +75,8 @@ class RoomLoadedFlowNode @AssistedInject constructor( } interface LifecycleCallback : NodeLifecycleCallback { - fun onFlowCreated(identifier: String, room: MatrixRoom) = Unit - fun onFlowReleased(identifier: String, room: MatrixRoom) = Unit + fun onFlowCreated(identifier: String, room: MatrixRoom) + fun onFlowReleased(identifier: String, room: MatrixRoom) } data class Inputs( diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt index 21a57b48a7..bba497e2fd 100644 --- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt +++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt @@ -152,8 +152,7 @@ class InviteListPresenter @Inject constructor( client.getRoom(roomId)?.use { it.leave().getOrThrow() notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId) - } - Unit + }.let { } }.runCatchingUpdatingState(declinedAction) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index b68b0eea7a..6b67573b4f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -125,8 +125,9 @@ fun MessagesView( state.eventSink(MessagesEvents.ToggleReaction(emoji, event.eventId)) } - fun onMoreReactionsClicked(event: TimelineItem.Event): Unit = + fun onMoreReactionsClicked(event: TimelineItem.Event) { state.customReactionState.eventSink(CustomReactionEvents.UpdateSelectedEvent(event.eventId)) + } Scaffold( modifier = modifier, diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index c9e8aa395b..388076639f 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -54,6 +54,8 @@ style: active: true UseCheckOrError: active: true + OptionalUnit: + active: true coroutines: GlobalCoroutineUsage: From 15ac81d32a9f7f7c9246acfd47db7fe6447ca9f9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:47:50 +0200 Subject: [PATCH 17/37] Enable detekt rules `UnderscoresInNumericLiterals` and fix existing issues. --- .../rageshake/impl/crash/VectorUncaughtExceptionHandler.kt | 6 +++--- .../theme/components/previews/DatePickerPreview.kt | 2 +- .../TimelineEncryptedHistoryPostProcessorTest.kt | 2 +- .../push/impl/notifications/NotificationIdProviderTest.kt | 2 +- tools/detekt/detekt.yml | 4 ++++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/crash/VectorUncaughtExceptionHandler.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/crash/VectorUncaughtExceptionHandler.kt index a5e7edf405..b71c8af372 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/crash/VectorUncaughtExceptionHandler.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/crash/VectorUncaughtExceptionHandler.kt @@ -62,9 +62,9 @@ class VectorUncaughtExceptionHandler( totalSize = info.totalMemory() usedSize = totalSize - freeSize } - append("usedSize " + usedSize / 1048576L + " MB\n") - append("freeSize " + freeSize / 1048576L + " MB\n") - append("totalSize " + totalSize / 1048576L + " MB\n") + append("usedSize " + usedSize / 1_048_576L + " MB\n") + append("freeSize " + freeSize / 1_048_576L + " MB\n") + append("totalSize " + totalSize / 1_048_576L + " MB\n") append("Thread: ") append(thread.name) append(", Exception: ") diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/DatePickerPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/DatePickerPreview.kt index a422c5e729..685fe40302 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/DatePickerPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/DatePickerPreview.kt @@ -44,7 +44,7 @@ internal fun DatePickerPreviewDark() { @Composable private fun ContentToPreview() { val state = rememberDatePickerState( - initialSelectedDateMillis = 1672578000000L, + initialSelectedDateMillis = 1_672_578_000_000L, ) AlertDialogContent( buttons = { /*TODO*/ }, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/TimelineEncryptedHistoryPostProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/TimelineEncryptedHistoryPostProcessorTest.kt index 91f0bc1883..3270f6048f 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/TimelineEncryptedHistoryPostProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/TimelineEncryptedHistoryPostProcessorTest.kt @@ -27,7 +27,7 @@ import java.util.Date class TimelineEncryptedHistoryPostProcessorTest { - private val defaultLastLoginTimestamp = Date(1689061264L) + private val defaultLastLoginTimestamp = Date(1_689_061_264L) @Test fun `given an unencrypted room, nothing is done`() { diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProviderTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProviderTest.kt index 57f28e72db..b9664ef577 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProviderTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProviderTest.kt @@ -25,7 +25,7 @@ class NotificationIdProviderTest { @Test fun `test notification id provider`() { val sut = NotificationIdProvider() - val offsetForASessionId = 305410 + val offsetForASessionId = 305_410 assertThat(sut.getSummaryNotificationId(A_SESSION_ID)).isEqualTo(offsetForASessionId + 0) assertThat(sut.getRoomMessagesNotificationId(A_SESSION_ID)).isEqualTo(offsetForASessionId + 1) assertThat(sut.getRoomEventNotificationId(A_SESSION_ID)).isEqualTo(offsetForASessionId + 2) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 388076639f..0675583bd8 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -56,6 +56,10 @@ style: active: true OptionalUnit: active: true + UnderscoresInNumericLiterals: + active: true + acceptableLength: 4 + allowNonStandardGrouping: false coroutines: GlobalCoroutineUsage: From 613cd4f863189101767fc4102f6a140fd0b35ba6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 11:50:58 +0200 Subject: [PATCH 18/37] Enable detekt rules `UseDataClass` and fix existing issues. --- .../android/libraries/designsystem/utils/LogCompositions.kt | 6 ++++-- tools/detekt/detekt.yml | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/LogCompositions.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/LogCompositions.kt index dcbef866fe..2618a5de82 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/LogCompositions.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/LogCompositions.kt @@ -28,10 +28,12 @@ import timber.log.Timber @Composable fun LogCompositions(tag: String, msg: String) { if (BuildConfig.DEBUG) { - val ref = remember { Ref(0) } + val ref = remember { Ref() } SideEffect { ref.value++ } Timber.tag(tag).d("Compositions: $msg ${ref.value}") } } -class Ref(var value: Int) +private class Ref { + var value: Int = 0 +} diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 0675583bd8..fbecf65073 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -60,6 +60,9 @@ style: active: true acceptableLength: 4 allowNonStandardGrouping: false + UseDataClass: + active: true + allowVars: false coroutines: GlobalCoroutineUsage: From b69e01a5f343917900fb73b3ffc28a941ef3f821 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 12:11:52 +0200 Subject: [PATCH 19/37] Enable detekt rules `UseLet` and fix existing issues. --- .../matrix/ui/room/MatrixRoomMembers.kt | 11 +++-------- .../push/impl/push/DefaultPushHandler.kt | 18 +++++++++--------- tools/detekt/detekt.yml | 2 ++ 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomMembers.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomMembers.kt index 7995672e92..668b963bf1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomMembers.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomMembers.kt @@ -57,14 +57,9 @@ fun MatrixRoom.getDirectRoomMember(roomMembersState: MatrixRoomMembersState): St val roomMembers = roomMembersState.roomMembers() return remember(roomMembersState) { derivedStateOf { - if (roomMembers == null) { - null - } else if (roomMembers.size == 2 && isDirect && isEncrypted) { - roomMembers.find { it.userId != this.sessionId } - } else { - null - } + roomMembers + ?.takeIf { it.size == 2 && isDirect && isEncrypted } + ?.find { it.userId != sessionId } } } } - diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt index aa1d0032e0..c3d68e52ac 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt @@ -100,15 +100,15 @@ class DefaultPushHandler @Inject constructor( } val clientSecret = pushData.clientSecret - val userId = if (clientSecret == null) { - // Should not happen. In this case, restore default session - null - } else { - // Get userId from client secret - pushClientSecret.getUserIdFromSecret(clientSecret) - } ?: run { - matrixAuthenticationService.getLatestSessionId() - } + // clientSecret should not be null. If this happens, restore default session + val userId = clientSecret + ?.let { + // Get userId from client secret + pushClientSecret.getUserIdFromSecret(clientSecret) + } + ?: run { + matrixAuthenticationService.getLatestSessionId() + } if (userId == null) { Timber.w("Unable to get a session") diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index fbecf65073..c7dc36ad74 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -63,6 +63,8 @@ style: UseDataClass: active: true allowVars: false + UseLet: + active: true coroutines: GlobalCoroutineUsage: From d22b005aa3e03f79b49c27dd340f8c5387d1faac Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Jul 2023 12:12:37 +0200 Subject: [PATCH 20/37] Enable more detekt rules. --- tools/detekt/detekt.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index c7dc36ad74..14193a1c70 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -56,15 +56,38 @@ style: active: true OptionalUnit: active: true + PreferToOverPairSyntax: + active: true + RedundantExplicitType: + active: true + TrailingWhitespace: + active: true + TrimMultilineRawString: + active: true + trimmingMethods: + - 'trimIndent' + - 'trimMargin' UnderscoresInNumericLiterals: active: true acceptableLength: 4 allowNonStandardGrouping: false + UnnecessaryAnnotationUseSiteTarget: + active: true + UnnecessaryBackticks: + active: true + UnnecessaryBracesAroundTrailingLambda: + active: true UseDataClass: active: true allowVars: false + UseEmptyCounterpart: + active: true + UseIfEmptyOrIfBlank: + active: true UseLet: active: true + UseSumOfInsteadOfFlatMapSize: + active: true coroutines: GlobalCoroutineUsage: From 1bfbef1ab5c2029e42b00763774a5ee3f55a2fad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 12:59:16 +0200 Subject: [PATCH 21/37] Previous code was `throw IllegalStateException()`, so keep the existing error, even if it should never happen, being compliant with `UseCheckOrError` detekt rule. --- .../io/element/android/libraries/maplibre/compose/MapboxMap.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt index 82b5e1c237..5af79e7524 100644 --- a/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt +++ b/libraries/maplibre-compose/src/main/kotlin/io/element/android/libraries/maplibre/compose/MapboxMap.kt @@ -236,7 +236,7 @@ private fun MapView.lifecycleObserver(previousState: MutableState { //handled in onDispose } - Lifecycle.Event.ON_ANY -> Unit + Lifecycle.Event.ON_ANY -> error("ON_ANY should never be used") } previousState.value = event } From 006ecd51eefa473ab65394e2f121cd3a18727c39 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 15:04:32 +0200 Subject: [PATCH 22/37] Improve rendering of offline banner regarding fontScale. --- .../networkmonitor/api/ui/ConnectivityIndicatorView.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt b/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt index bf05dbc5f5..855bf067dd 100644 --- a/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt +++ b/features/networkmonitor/api/src/main/kotlin/io/element/android/features/networkmonitor/api/ui/ConnectivityIndicatorView.kt @@ -44,8 +44,10 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.text.toDp import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings @@ -85,14 +87,14 @@ private fun Indicator(modifier: Modifier = Modifier) { .statusBarsPadding() .padding(vertical = 6.dp), horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.Bottom, + verticalAlignment = Alignment.CenterVertically, ) { val tint = MaterialTheme.colorScheme.primary Image( imageVector = Icons.Outlined.WifiOff, contentDescription = null, colorFilter = ColorFilter.tint(tint), - modifier = Modifier.size(16.dp), + modifier = Modifier.size(16.sp.toDp()), ) Spacer(modifier = Modifier.width(8.dp)) Text( From fb870a0903622eb03e580b1318aa5f3cb7d740b0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 15:29:58 +0200 Subject: [PATCH 23/37] Set expicit `fontSize` parameter (to default value 1f), to test different fontScale more easily. --- .../designsystem/preview/DayNightPreviews.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/DayNightPreviews.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/DayNightPreviews.kt index 201d6f7151..b91e6a1024 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/DayNightPreviews.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/DayNightPreviews.kt @@ -42,6 +42,13 @@ const val DAY_MODE_NAME = "D" * * NB: Content should be wrapped into [ElementPreview] to apply proper theming. */ -@Preview(name = DAY_MODE_NAME) -@Preview(name = NIGHT_MODE_NAME, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Preview( + name = DAY_MODE_NAME, + fontScale = 1f, +) +@Preview( + name = NIGHT_MODE_NAME, + uiMode = Configuration.UI_MODE_NIGHT_YES, + fontScale = 1f, +) annotation class DayNightPreviews From 96b7923979e5e424637a246d55588d17dc77e876 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 15:42:47 +0200 Subject: [PATCH 24/37] Improve rendering of "All chats" regarding fontScale. (#984) --- .../features/roomlist/impl/components/RoomListTopBar.kt | 8 +++++++- .../android/libraries/designsystem/text/UnitConverters.kt | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index db0ea8c11d..0c8522e7be 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -43,6 +43,8 @@ import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.text.scaleMax +import io.element.android.libraries.designsystem.text.toSp import io.element.android.libraries.designsystem.theme.aliasScreenTitle import io.element.android.libraries.designsystem.theme.components.DropdownMenu import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem @@ -114,7 +116,11 @@ private fun DefaultRoomListTopBar( val fontStyle = if (scrollBehavior.state.collapsedFraction > 0.5) ElementTheme.typography.aliasScreenTitle else - ElementTheme.typography.fontHeadingLgBold + ElementTheme.typography.fontHeadingLgBold.copy( + // Due to a limitation of MediumTopAppBar, and to avoid the text to be truncated, + // limit the size to 28.dp instead of 28.sp + fontSize = 28.dp.scaleMax().toSp() + ) Text( style = fontStyle, text = stringResource(id = R.string.screen_roomlist_main_space_title) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt index 1ee7d0d603..2e32e32987 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt @@ -52,3 +52,11 @@ fun Dp.toPx(): Float = with(LocalDensity.current) { toPx() } */ @Composable fun Dp.roundToPx(): Int = with(LocalDensity.current) { roundToPx() } + +/** + * Return the maximum value between the receiver value and the value with fonScale applied. + */ +@Composable +fun Dp.scaleMax(): Dp = with(LocalDensity.current) { + return this@scaleMax * fontScale.coerceAtMost(1f) +} From 1d89584daffa66dc262fd4abb6c3ff4f1e72c1ce Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 15:44:49 +0200 Subject: [PATCH 25/37] Improve rendering of Text composer regarding fontScale. (#984) --- .../designsystem/text/UnitConverters.kt | 8 +++++ .../libraries/textcomposer/TextComposer.kt | 30 +++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt index 2e32e32987..e3a96c2db3 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt @@ -60,3 +60,11 @@ fun Dp.roundToPx(): Int = with(LocalDensity.current) { roundToPx() } fun Dp.scaleMax(): Dp = with(LocalDensity.current) { return this@scaleMax * fontScale.coerceAtMost(1f) } + +/** + * Return the minimum value between the receiver value and the value with fonScale applied. + */ +@Composable +fun Dp.scaleMin(): Dp = with(LocalDensity.current) { + return this@scaleMin * fontScale.coerceAtLeast(1f) +} diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 8c4c361707..ecf721ac1d 100644 --- a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -73,6 +73,7 @@ import io.element.android.libraries.designsystem.VectorIcons import io.element.android.libraries.designsystem.modifiers.applyIf import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.text.scaleMin import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Surface import io.element.android.libraries.designsystem.theme.components.Text @@ -109,12 +110,15 @@ fun TextComposer( ) { AttachmentButton(onClick = onAddAttachment, modifier = Modifier.padding(vertical = 6.dp)) Spacer(modifier = Modifier.width(12.dp)) + val roundCornerSmall = 20.dp.scaleMin() + val roundCornerLarge = 28.dp.scaleMin() + var lineCount by remember { mutableStateOf(0) } val roundedCornerSize = remember(lineCount, composerMode) { if (lineCount > 1 || composerMode is MessageComposerMode.Special) { - 20.dp + roundCornerSmall } else { - 28.dp + roundCornerLarge } } val roundedCornerSizeState = animateDpAsState( @@ -124,7 +128,7 @@ fun TextComposer( ) ) val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value) - val minHeight = 42.dp + val minHeight = 42.dp.scaleMin() val bgColor = ElementTheme.colors.bgSubtleSecondary // Change border color depending on focus var hasFocus by remember { mutableStateOf(false) } @@ -165,7 +169,7 @@ fun TextComposer( singleLine = false, visualTransformation = VisualTransformation.None, shape = roundedCorners, - contentPadding = PaddingValues(top = 10.dp, bottom = 10.dp, start = 12.dp, end = 42.dp), + contentPadding = PaddingValues(top = 10.dp.scaleMin(), bottom = 10.dp.scaleMin(), start = 12.dp.scaleMin(), end = 42.dp.scaleMin()), interactionSource = remember { MutableInteractionSource() }, placeholder = { Text(stringResource(CommonStrings.common_message), style = defaultTypography) @@ -193,7 +197,7 @@ fun TextComposer( canSendMessage = composerCanSendMessage, onSendMessage = onSendMessage, composerMode = composerMode, - modifier = Modifier.padding(end = 6.dp, bottom = 6.dp) + modifier = Modifier.padding(end = 6.dp.scaleMin(), bottom = 6.dp.scaleMin()) ) } } @@ -253,7 +257,7 @@ private fun EditingModeView( tint = ElementTheme.materialColors.secondary, modifier = Modifier .padding(vertical = 8.dp) - .size(16.dp), + .size(16.dp.scaleMin()), ) Text( stringResource(CommonStrings.common_editing), @@ -270,7 +274,7 @@ private fun EditingModeView( tint = ElementTheme.materialColors.secondary, modifier = Modifier .padding(top = 8.dp, bottom = 8.dp, start = 16.dp, end = 12.dp) - .size(16.dp) + .size(16.dp.scaleMin()) .clickable( enabled = true, onClick = onResetComposerMode, @@ -333,7 +337,7 @@ private fun ReplyToModeView( tint = MaterialTheme.colorScheme.secondary, modifier = Modifier .padding(end = 4.dp, top = 4.dp, start = 16.dp, bottom = 16.dp) - .size(16.dp) + .size(16.dp.scaleMin()) .clickable( enabled = true, onClick = onResetComposerMode, @@ -351,13 +355,13 @@ private fun AttachmentButton( ) { Surface( modifier - .size(30.dp) + .size(30.dp.scaleMin()) .clickable(onClick = onClick), shape = CircleShape, color = ElementTheme.colors.iconPrimary ) { Image( - modifier = Modifier.size(12.5f.dp), + modifier = Modifier.size(12.5f.dp.scaleMin()), painter = painterResource(R.drawable.ic_add_attachment), contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment), contentScale = ContentScale.Inside, @@ -381,10 +385,10 @@ private fun BoxScope.SendButton( modifier = modifier .clip(CircleShape) .background(if (canSendMessage) ElementTheme.colors.iconAccentTertiary else Color.Transparent) - .size(30.dp) + .size(30.dp.scaleMin()) .align(Alignment.BottomEnd) .applyIf(composerMode !is MessageComposerMode.Edit, ifTrue = { - padding(start = 1.dp) // Center the arrow in the circle + padding(start = 1.dp.scaleMin()) // Center the arrow in the circle }) .clickable( enabled = canSendMessage, @@ -404,7 +408,7 @@ private fun BoxScope.SendButton( else -> stringResource(CommonStrings.action_send) } Icon( - modifier = Modifier.size(16.dp), + modifier = Modifier.size(16.dp.scaleMin()), resourceId = iconId, contentDescription = contentDescription, // Exception here, we use Color.White instead of ElementTheme.colors.iconOnSolidPrimary From cc2a01f483dc224e2eca52a00e121b4a038efb85 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 15:53:20 +0200 Subject: [PATCH 26/37] Ensure room name have horizontal padding and is centered if displayed on several lines, and remove unnecessary Box around the Avatar. --- .../roomdetails/impl/RoomDetailsView.kt | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 1e5d1a8ebb..d1de0babe8 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -17,13 +17,11 @@ package io.element.android.features.roomdetails.impl import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -226,22 +224,28 @@ internal fun RoomHeaderSection( roomAlias: String?, modifier: Modifier = Modifier ) { - Column(modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - Box(modifier = Modifier.size(70.dp)) { - Avatar( - avatarData = AvatarData(roomId, roomName, avatarUrl, AvatarSize.RoomHeader), - modifier = Modifier.fillMaxSize() - ) - } + Column( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Avatar( + avatarData = AvatarData(roomId, roomName, avatarUrl, AvatarSize.RoomHeader), + modifier = Modifier.size(70.dp) + ) Spacer(modifier = Modifier.height(24.dp)) - Text(roomName, style = ElementTheme.typography.fontHeadingLgBold) + Text( + text = roomName, + style = ElementTheme.typography.fontHeadingLgBold, + textAlign = TextAlign.Center, + ) if (roomAlias != null) { Spacer(modifier = Modifier.height(6.dp)) Text( text = roomAlias, style = ElementTheme.typography.fontBodyLgRegular, color = MaterialTheme.colorScheme.secondary, - modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), textAlign = TextAlign.Center, ) } From 8c363602c04b337c3ae7355441f6edad9c9e3aaf Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 27 Jul 2023 14:33:34 +0000 Subject: [PATCH 27/37] Update screenshots --- ...oadingRoomNodeViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...oadingRoomNodeViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...adingRoomNodeViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...adingRoomNodeViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...Group_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...roup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ewDarkConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...wLightConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...Group_RoomListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...roup_RoomListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 7870560dd4..500f0a57f7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da4188dc606f0735fd4093acad34897c866d8c4d20b3e0ec0618685f7302cbf5 -size 9288 +oid sha256:3f18e74bfbebd69109f36a7154b20d3ee61071bff0d8ebf28f4b3b35c58e2938 +size 9256 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 7edd6f9ee7..17ed1eee99 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e27b1ea7bfa4eb97af3c2d433fbe3f5ca21458e4458d91b39c9c2bb3d7b02abc -size 11306 +oid sha256:eea203b9527f7c3dc3692e7db3e9d5cee20ca08fddf04977c948933dc2784022 +size 11274 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index c87156e8c6..3bbf79781a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2bbeb21faf320226f42aad179b955952ad8e4b5d5645c45bfbbc02166baf0662 -size 9641 +oid sha256:b5c69ae7d27eb7024e9a2f9c7100b308562ef2fc702e28604098180cb02a3813 +size 9645 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 6391f1dec0..1b135effbf 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.appnav.room_null_DefaultGroup_LoadingRoomNodeViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:499e17b52d57f8b0d8984e32457b3922c0647be5b835c02a01ed927fe004ec4d -size 11610 +oid sha256:62149a4d9b0dd62ddb56e1cdb24fe401f189fda05d17dd16f8c0bc511eab6561 +size 11616 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 482ab3b775..3dc03be3ae 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d368f7cc84b5a8850577fac658aaeb89a1c83a2890b7fd393577c9cde919069 -size 53689 +oid sha256:613d55031bc30060bdd84596fb78de043ead483ac59fd42e48b15f0e56947a36 +size 53660 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index ad548c2fbe..26d1cd82c3 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89520fd2999582229ace8fd9304644fc74ce01230a4024b90b47ce1cd61eb564 -size 55678 +oid sha256:632dfa6edc34b7283654e43c3b7d9eb0334507644e50bc5fc7bdf8b5c45ed874 +size 55686 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewDarkConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewDarkConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png index fd00dfae33..41503c31be 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewDarkConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewDarkConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e0c73b8d86c064ce46ade6477cc91803d543199657e597a15a7e21bdacab7be -size 6541 +oid sha256:774ece5436ab5a025a6a7134120069922276329bf87408a90263bb8c425a0568 +size 6510 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewLightConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewLightConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png index 820b688066..b41bc75694 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewLightConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.networkmonitor.api.ui_null_DefaultGroup_PreviewLightConnectivityIndicatorView_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3af4d7ce438da56851aa3041138558d8e57ac181775476b983646039a1cb62ae -size 6602 +oid sha256:55aff072541c752abd0a8fe48c73b38b42ea47ab4779a2a3ae37a449f88ffd24 +size 6606 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 6ef66d5ddf..a613701e1a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8aa48154bf2cf3a6ec6da96e24a86c6a3f1e6eb11865c2301a4f2638e471bd34 -size 37408 +oid sha256:9c6477d7476baccee037e491930d99f7ea00e313d1285fdd882be3de99f705b0 +size 37376 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 75268923f9..de27672e6f 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8f155381ccc3f8833b58e076e797034dfa528bd55bafd982c34fb997e4db491 -size 39830 +oid sha256:5b589817850bc30e336e9d5e443b2153133991aa5ea919838bddef26d2b1df9e +size 39840 From 09e30bcac67952610372b96d8b55ea4d097e75a9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 17:29:03 +0200 Subject: [PATCH 28/37] Prevent reaction on state events and deleted events (#971) --- .../impl/actionlist/ActionListPresenter.kt | 6 +++++- .../model/event/TimelineItemEventContent.kt | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 2d18018746..7c7e43e02b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -28,6 +28,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent import io.element.android.features.messages.impl.timeline.model.event.canBeCopied +import io.element.android.features.messages.impl.timeline.model.event.canReact import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta import kotlinx.collections.immutable.toImmutableList @@ -48,7 +49,10 @@ class ActionListPresenter @Inject constructor( } val displayEmojiReactions by remember { - derivedStateOf { (target.value as? ActionListState.Target.Success)?.event?.isRemote == true } + derivedStateOf { + val event = (target.value as? ActionListState.Target.Success)?.event + event?.isRemote == true && event.content.canReact() + } } fun handleEvents(event: ActionListEvents) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt index 0ff67e481f..e0de57c5a5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt @@ -33,3 +33,20 @@ fun TimelineItemEventContent.canBeCopied(): Boolean = is TimelineItemRedactedContent -> true else -> false } + +/** + * Return true if user can react (i.e. send a reaction) on the event content. + */ +fun TimelineItemEventContent.canReact(): Boolean = + when (this) { + is TimelineItemTextBasedContent, + is TimelineItemAudioContent, + is TimelineItemEncryptedContent, + is TimelineItemFileContent, + is TimelineItemImageContent, + is TimelineItemLocationContent, + is TimelineItemVideoContent -> true + is TimelineItemStateContent, + is TimelineItemRedactedContent, + TimelineItemUnknownContent -> false + } From b2d3368f638f8381f63c725abefebf096e07e083 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Jul 2023 17:53:28 +0200 Subject: [PATCH 29/37] Allow user with enough power level to redact other's messages (#969) --- .../messages/impl/MessagesPresenter.kt | 3 ++ .../features/messages/impl/MessagesState.kt | 1 + .../messages/impl/MessagesStateProvider.kt | 1 + .../features/messages/impl/MessagesView.kt | 2 +- .../impl/actionlist/ActionListEvents.kt | 2 +- .../impl/actionlist/ActionListPresenter.kt | 14 +++-- .../messages/MessagesPresenterTest.kt | 26 ++++++++- .../actionlist/ActionListPresenterTest.kt | 53 +++++++++++++++---- .../libraries/matrix/api/room/MatrixRoom.kt | 2 + .../room/powerlevels/MatrixRoomPowerLevels.kt | 6 +++ .../matrix/impl/room/RustMatrixRoom.kt | 6 +++ .../matrix/test/room/FakeMatrixRoom.kt | 6 +++ .../matrix/ui/room/MatrixRoomState.kt | 8 +++ 13 files changed, 112 insertions(+), 18 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index acaaf54c9e..8818cc6476 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -71,6 +71,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType +import io.element.android.libraries.matrix.ui.room.canRedactAsState import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.textcomposer.MessageComposerMode import kotlinx.coroutines.CoroutineScope @@ -109,6 +110,7 @@ class MessagesPresenter @AssistedInject constructor( val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.ROOM_MESSAGE, updateKey = syncUpdateFlow.value) + val userHasPermissionToRedact by room.canRedactAsState(updateKey = syncUpdateFlow.value) var roomName: Async by remember { mutableStateOf(Async.Uninitialized) } var roomAvatar: Async by remember { mutableStateOf(Async.Uninitialized) } LaunchedEffect(syncUpdateFlow.value) { @@ -165,6 +167,7 @@ class MessagesPresenter @AssistedInject constructor( roomName = roomName, roomAvatar = roomAvatar, userHasPermissionToSendMessage = userHasPermissionToSendMessage, + userHasPermissionToRedact = userHasPermissionToRedact, composerState = composerState, timelineState = timelineState, actionListState = actionListState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt index a042ec1ac4..50e952f237 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt @@ -33,6 +33,7 @@ data class MessagesState( val roomName: Async, val roomAvatar: Async, val userHasPermissionToSendMessage: Boolean, + val userHasPermissionToRedact: Boolean, val composerState: MessageComposerState, val timelineState: TimelineState, val actionListState: ActionListState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index ce50cc138b..bb0b61f620 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -50,6 +50,7 @@ fun aMessagesState() = MessagesState( roomName = Async.Success("Room name"), roomAvatar = Async.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)), userHasPermissionToSendMessage = true, + userHasPermissionToRedact = false, composerState = aMessageComposerState().copy( text = "Hello", isFullScreen = false, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index f909ac7f1a..facd7ceb24 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -115,7 +115,7 @@ fun MessagesView( fun onMessageLongClicked(event: TimelineItem.Event) { Timber.v("OnMessageLongClicked= ${event.id}") localView.hideKeyboard() - state.actionListState.eventSink(ActionListEvents.ComputeForMessage(event)) + state.actionListState.eventSink(ActionListEvents.ComputeForMessage(event, state.userHasPermissionToRedact)) } fun onActionSelected(action: TimelineItemAction, event: TimelineItem.Event) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt index a6244a72e3..3c796036e7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListEvents.kt @@ -20,5 +20,5 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem sealed interface ActionListEvents { object Clear : ActionListEvents - data class ComputeForMessage(val event: TimelineItem.Event) : ActionListEvents + data class ComputeForMessage(val event: TimelineItem.Event, val canRedact: Boolean) : ActionListEvents } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 2d18018746..1aadcc2094 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -54,7 +54,11 @@ class ActionListPresenter @Inject constructor( fun handleEvents(event: ActionListEvents) { when (event) { ActionListEvents.Clear -> target.value = ActionListState.Target.None - is ActionListEvents.ComputeForMessage -> localCoroutineScope.computeForMessage(event.event, target) + is ActionListEvents.ComputeForMessage -> localCoroutineScope.computeForMessage( + timelineItem = event.event, + userCanRedact = event.canRedact, + target = target, + ) } } @@ -65,7 +69,11 @@ class ActionListPresenter @Inject constructor( ) } - private fun CoroutineScope.computeForMessage(timelineItem: TimelineItem.Event, target: MutableState) = launch { + private fun CoroutineScope.computeForMessage( + timelineItem: TimelineItem.Event, + userCanRedact: Boolean, + target: MutableState + ) = launch { target.value = ActionListState.Target.Loading(timelineItem) val actions = when (timelineItem.content) { @@ -102,7 +110,7 @@ class ActionListPresenter @Inject constructor( if (!timelineItem.isMine) { add(TimelineItemAction.ReportContent) } - if (timelineItem.isMine) { + if (timelineItem.isMine || userCanRedact) { add(TimelineItemAction.Redact) } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index b47ac55d35..6ff003b735 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -44,8 +44,11 @@ import io.element.android.features.messages.media.FakeLocalMediaFactory import io.element.android.features.messages.utils.messagesummary.FakeMessageSummaryFormatter import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper +import io.element.android.libraries.architecture.Async import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.mimetype.MimeTypes +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.utils.SnackbarDispatcher import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.media.MediaSource @@ -83,9 +86,16 @@ class MessagesPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - skipItems(1) - val initialState = awaitItem() + val initialState = consumeItemsUntilTimeout().last() assertThat(initialState.roomId).isEqualTo(A_ROOM_ID) + assertThat(initialState.roomName).isEqualTo(Async.Success("")) + assertThat(initialState.roomAvatar).isEqualTo(Async.Success(AvatarData(id = A_ROOM_ID.value, name = "", size = AvatarSize.TimelineRoom))) + assertThat(initialState.userHasPermissionToSendMessage).isTrue() + assertThat(initialState.userHasPermissionToRedact).isFalse() + assertThat(initialState.hasNetworkConnection).isTrue() + assertThat(initialState.snackbarMessage).isNull() + assertThat(initialState.inviteProgress).isEqualTo(Async.Uninitialized) + assertThat(initialState.showReinvitePrompt).isFalse() } } @@ -531,6 +541,18 @@ class MessagesPresenterTest { } } + @Test + fun `present - permission to redact`() = runTest { + val matrixRoom = FakeMatrixRoom(canRedact = true) + val presenter = createMessagePresenter(matrixRoom = matrixRoom) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = consumeItemsUntilTimeout().last() + assertThat(initialState.userHasPermissionToRedact).isTrue() + } + } + private fun TestScope.createMessagePresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(), matrixRoom: MatrixRoom = FakeMatrixRoom(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt index a2baa9dff7..afef9f6730 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/actionlist/ActionListPresenterTest.kt @@ -56,7 +56,7 @@ class ActionListPresenterTest { }.test { val initialState = awaitItem() val messageEvent = aMessageEvent(isMine = true, content = TimelineItemRedactedContent) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -81,7 +81,7 @@ class ActionListPresenterTest { }.test { val initialState = awaitItem() val messageEvent = aMessageEvent(isMine = false, content = TimelineItemRedactedContent) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -109,7 +109,7 @@ class ActionListPresenterTest { isMine = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -130,6 +130,37 @@ class ActionListPresenterTest { } } + @Test + fun `present - compute for others message and can redact`() = runTest { + val presenter = anActionListPresenter(isBuildDebuggable = true) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = false, + content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) + ) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, true)) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + messageEvent, + persistentListOf( + TimelineItemAction.Reply, + TimelineItemAction.Forward, + TimelineItemAction.Copy, + TimelineItemAction.Developer, + TimelineItemAction.ReportContent, + TimelineItemAction.Redact, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + @Test fun `present - compute for my message`() = runTest { val presenter = anActionListPresenter(isBuildDebuggable = true) @@ -141,7 +172,7 @@ class ActionListPresenterTest { isMine = true, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -174,7 +205,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemImageContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -205,7 +236,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemStateEventContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -234,7 +265,7 @@ class ActionListPresenterTest { isMine = true, content = aTimelineItemStateEventContent(), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -262,7 +293,7 @@ class ActionListPresenterTest { isMine = true, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false) ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) // val loadingState = awaitItem() // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() @@ -299,10 +330,10 @@ class ActionListPresenterTest { content = TimelineItemRedactedContent, ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) assertThat(awaitItem().target).isInstanceOf(ActionListState.Target.Success::class.java) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent, false)) awaitItem().run { assertThat(target).isEqualTo(ActionListState.Target.None) assertThat(displayEmojiReactions).isFalse() @@ -323,7 +354,7 @@ class ActionListPresenterTest { content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false), ) - initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent)) + initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, false)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index 1445f85228..f8b9e6c2c3 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -105,6 +105,8 @@ interface MatrixRoom : Closeable { suspend fun canUserInvite(userId: UserId): Result + suspend fun canUserRedact(userId: UserId): Result + suspend fun canUserSendState(userId: UserId, type: StateEventType): Result suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt index 852401bffc..e0ba452efe 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt @@ -34,3 +34,9 @@ suspend fun MatrixRoom.canSendState(type: StateEventType): Result = can * Shortcut for calling [MatrixRoom.canUserSendMessage] with our own user. */ suspend fun MatrixRoom.canSendMessage(type: MessageEventType): Result = canUserSendMessage(sessionId, type) + +/** + * Shortcut for calling [MatrixRoom.canUserRedact] with our own user. + */ +suspend fun MatrixRoom.canRedact(): Result = canUserRedact(sessionId) + diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 8c2eecce8a..c2d3dfeb39 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -250,6 +250,12 @@ class RustMatrixRoom( } } + override suspend fun canUserRedact(userId: UserId): Result { + return runCatching { + innerRoom.canUserRedact(userId.value) + } + } + override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result { return runCatching { innerRoom.canUserSendState(userId.value, type.map()) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index 59f6ed57bd..ee735ae81b 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -56,6 +56,7 @@ class FakeMatrixRoom( override val joinedMemberCount: Long = 123L, override val activeMemberCount: Long = 234L, private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(), + canRedact: Boolean = false, ) : MatrixRoom { private var ignoreResult: Result = Result.success(Unit) @@ -66,6 +67,7 @@ class FakeMatrixRoom( private var joinRoomResult = Result.success(Unit) private var inviteUserResult = Result.success(Unit) private var canInviteResult = Result.success(true) + private var canRedactResult = Result.success(canRedact) private val canSendStateResults = mutableMapOf>() private val canSendEventResults = mutableMapOf>() private var sendMediaResult = Result.success(Unit) @@ -207,6 +209,10 @@ class FakeMatrixRoom( return canInviteResult } + override suspend fun canUserRedact(userId: UserId): Result { + return canRedactResult + } + override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result { return canSendStateResults[type] ?: Result.failure(IllegalStateException("No fake answer")) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt index 005a0ac747..f2a73545bf 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/MatrixRoomState.kt @@ -21,6 +21,7 @@ import androidx.compose.runtime.State import androidx.compose.runtime.produceState import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.powerlevels.canRedact import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage @Composable @@ -30,3 +31,10 @@ fun MatrixRoom.canSendMessageAsState(type: MessageEventType, updateKey: Long): S } } +@Composable +fun MatrixRoom.canRedactAsState(updateKey: Long): State { + return produceState(initialValue = false, key1 = updateKey) { + value = canRedact().getOrElse { false } + } +} + From bfb27db58bb8af5a901c1468b1f19508fa0a5548 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Jul 2023 10:01:22 +0200 Subject: [PATCH 30/37] Move extension to dedicated file. --- .../libraries/designsystem/text/FontSize.kt | 37 +++++++++++++++++++ .../designsystem/text/UnitConverters.kt | 16 -------- 2 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt new file mode 100644 index 0000000000..4dcc05ee29 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.text + +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp + +/** + * Return the maximum value between the receiver value and the value with fonScale applied. + */ +@Composable +fun Dp.scaleMax(): Dp = with(LocalDensity.current) { + return this@scaleMax * fontScale.coerceAtMost(1f) +} + +/** + * Return the minimum value between the receiver value and the value with fonScale applied. + */ +@Composable +fun Dp.scaleMin(): Dp = with(LocalDensity.current) { + return this@scaleMin * fontScale.coerceAtLeast(1f) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt index e3a96c2db3..1ee7d0d603 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/UnitConverters.kt @@ -52,19 +52,3 @@ fun Dp.toPx(): Float = with(LocalDensity.current) { toPx() } */ @Composable fun Dp.roundToPx(): Int = with(LocalDensity.current) { roundToPx() } - -/** - * Return the maximum value between the receiver value and the value with fonScale applied. - */ -@Composable -fun Dp.scaleMax(): Dp = with(LocalDensity.current) { - return this@scaleMax * fontScale.coerceAtMost(1f) -} - -/** - * Return the minimum value between the receiver value and the value with fonScale applied. - */ -@Composable -fun Dp.scaleMin(): Dp = with(LocalDensity.current) { - return this@scaleMin * fontScale.coerceAtLeast(1f) -} From 0b5a3c56d69b266b74e54a06c2ed34da44463f8d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Jul 2023 10:29:13 +0200 Subject: [PATCH 31/37] Update the API and add UI screenshots demoing it. --- .../impl/components/RoomListTopBar.kt | 6 +- .../libraries/designsystem/text/DpScale.kt | 119 ++++++++++++++++++ .../libraries/designsystem/text/FontSize.kt | 37 ------ .../libraries/textcomposer/TextComposer.kt | 28 ++--- 4 files changed, 136 insertions(+), 54 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt delete mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index 0c8522e7be..c144ef8671 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -43,7 +43,7 @@ import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight -import io.element.android.libraries.designsystem.text.scaleMax +import io.element.android.libraries.designsystem.text.applyScaleDown import io.element.android.libraries.designsystem.text.toSp import io.element.android.libraries.designsystem.theme.aliasScreenTitle import io.element.android.libraries.designsystem.theme.components.DropdownMenu @@ -118,8 +118,8 @@ private fun DefaultRoomListTopBar( else ElementTheme.typography.fontHeadingLgBold.copy( // Due to a limitation of MediumTopAppBar, and to avoid the text to be truncated, - // limit the size to 28.dp instead of 28.sp - fontSize = 28.dp.scaleMax().toSp() + // ensure that the font size will never be bigger than 28.dp. + fontSize = 28.dp.applyScaleDown().toSp() ) Text( style = fontStyle, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt new file mode 100644 index 0000000000..c4c524e804 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.text + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.theme.ElementTheme + +/** + * Return the maximum value between the receiver value and the value with fonScale applied. + * So if fontScale is >= 1f, the same value is returned, and if fontScale is < 1f, so returned value + * will be smaller. + */ +@Composable +fun Dp.applyScaleDown(): Dp = with(LocalDensity.current) { + return this@applyScaleDown * fontScale.coerceAtMost(1f) +} + +/** + * Return the minimum value between the receiver value and the value with fonScale applied. + * So if fontScale is <= 1f, the same value is returned, and if fontScale is > 1f, so returned value + * will be bigger. + */ +@Composable +fun Dp.applyScaleUp(): Dp = with(LocalDensity.current) { + return this@applyScaleUp * fontScale.coerceAtLeast(1f) +} + +@Preview(fontScale = 0.75f) +@Composable +fun DpScalePreview_0_75f() = ElementPreviewLight { + val fontSizeInDp = 16.dp + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + text = "A text should have a size of 16.sp", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) + ) + Text( + text = "A text should have the same size (applyScaleUp)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) + ) + Text( + text = "A text should be smaller (applyScaleDown)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) + ) + } +} + +@Preview(fontScale = 1.0f) +@Composable +fun DpScalePreview_1_0f() = ElementPreviewLight { + val fontSizeInDp = 16.dp + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + text = "A text with a size of 16.sp", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) + ) + Text( + text = "A text with the same size (applyScaleUp)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) + ) + Text( + text = "A text with the same size (applyScaleDown)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) + ) + } +} + +@Preview(fontScale = 1.5f) +@Composable +fun DpScalePreview_1_5f() = ElementPreviewLight { + val fontSizeInDp = 16.dp + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + text = "A text with a size of 16.sp", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) + ) + Text( + text = "A text with a bigger size (applyScaleUp)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) + ) + Text( + text = "A text with the same size (applyScaleDown)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) + ) + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt deleted file mode 100644 index 4dcc05ee29..0000000000 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/FontSize.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.libraries.designsystem.text - -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Dp - -/** - * Return the maximum value between the receiver value and the value with fonScale applied. - */ -@Composable -fun Dp.scaleMax(): Dp = with(LocalDensity.current) { - return this@scaleMax * fontScale.coerceAtMost(1f) -} - -/** - * Return the minimum value between the receiver value and the value with fonScale applied. - */ -@Composable -fun Dp.scaleMin(): Dp = with(LocalDensity.current) { - return this@scaleMin * fontScale.coerceAtLeast(1f) -} diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index ecf721ac1d..a802298624 100644 --- a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -73,7 +73,7 @@ import io.element.android.libraries.designsystem.VectorIcons import io.element.android.libraries.designsystem.modifiers.applyIf import io.element.android.libraries.designsystem.preview.DayNightPreviews import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.text.scaleMin +import io.element.android.libraries.designsystem.text.applyScaleUp import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Surface import io.element.android.libraries.designsystem.theme.components.Text @@ -110,8 +110,8 @@ fun TextComposer( ) { AttachmentButton(onClick = onAddAttachment, modifier = Modifier.padding(vertical = 6.dp)) Spacer(modifier = Modifier.width(12.dp)) - val roundCornerSmall = 20.dp.scaleMin() - val roundCornerLarge = 28.dp.scaleMin() + val roundCornerSmall = 20.dp.applyScaleUp() + val roundCornerLarge = 28.dp.applyScaleUp() var lineCount by remember { mutableStateOf(0) } val roundedCornerSize = remember(lineCount, composerMode) { @@ -128,7 +128,7 @@ fun TextComposer( ) ) val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value) - val minHeight = 42.dp.scaleMin() + val minHeight = 42.dp.applyScaleUp() val bgColor = ElementTheme.colors.bgSubtleSecondary // Change border color depending on focus var hasFocus by remember { mutableStateOf(false) } @@ -169,7 +169,7 @@ fun TextComposer( singleLine = false, visualTransformation = VisualTransformation.None, shape = roundedCorners, - contentPadding = PaddingValues(top = 10.dp.scaleMin(), bottom = 10.dp.scaleMin(), start = 12.dp.scaleMin(), end = 42.dp.scaleMin()), + contentPadding = PaddingValues(top = 10.dp.applyScaleUp(), bottom = 10.dp.applyScaleUp(), start = 12.dp.applyScaleUp(), end = 42.dp.applyScaleUp()), interactionSource = remember { MutableInteractionSource() }, placeholder = { Text(stringResource(CommonStrings.common_message), style = defaultTypography) @@ -197,7 +197,7 @@ fun TextComposer( canSendMessage = composerCanSendMessage, onSendMessage = onSendMessage, composerMode = composerMode, - modifier = Modifier.padding(end = 6.dp.scaleMin(), bottom = 6.dp.scaleMin()) + modifier = Modifier.padding(end = 6.dp.applyScaleUp(), bottom = 6.dp.applyScaleUp()) ) } } @@ -257,7 +257,7 @@ private fun EditingModeView( tint = ElementTheme.materialColors.secondary, modifier = Modifier .padding(vertical = 8.dp) - .size(16.dp.scaleMin()), + .size(16.dp.applyScaleUp()), ) Text( stringResource(CommonStrings.common_editing), @@ -274,7 +274,7 @@ private fun EditingModeView( tint = ElementTheme.materialColors.secondary, modifier = Modifier .padding(top = 8.dp, bottom = 8.dp, start = 16.dp, end = 12.dp) - .size(16.dp.scaleMin()) + .size(16.dp.applyScaleUp()) .clickable( enabled = true, onClick = onResetComposerMode, @@ -337,7 +337,7 @@ private fun ReplyToModeView( tint = MaterialTheme.colorScheme.secondary, modifier = Modifier .padding(end = 4.dp, top = 4.dp, start = 16.dp, bottom = 16.dp) - .size(16.dp.scaleMin()) + .size(16.dp.applyScaleUp()) .clickable( enabled = true, onClick = onResetComposerMode, @@ -355,13 +355,13 @@ private fun AttachmentButton( ) { Surface( modifier - .size(30.dp.scaleMin()) + .size(30.dp.applyScaleUp()) .clickable(onClick = onClick), shape = CircleShape, color = ElementTheme.colors.iconPrimary ) { Image( - modifier = Modifier.size(12.5f.dp.scaleMin()), + modifier = Modifier.size(12.5f.dp.applyScaleUp()), painter = painterResource(R.drawable.ic_add_attachment), contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment), contentScale = ContentScale.Inside, @@ -385,10 +385,10 @@ private fun BoxScope.SendButton( modifier = modifier .clip(CircleShape) .background(if (canSendMessage) ElementTheme.colors.iconAccentTertiary else Color.Transparent) - .size(30.dp.scaleMin()) + .size(30.dp.applyScaleUp()) .align(Alignment.BottomEnd) .applyIf(composerMode !is MessageComposerMode.Edit, ifTrue = { - padding(start = 1.dp.scaleMin()) // Center the arrow in the circle + padding(start = 1.dp.applyScaleUp()) // Center the arrow in the circle }) .clickable( enabled = canSendMessage, @@ -408,7 +408,7 @@ private fun BoxScope.SendButton( else -> stringResource(CommonStrings.action_send) } Icon( - modifier = Modifier.size(16.dp.scaleMin()), + modifier = Modifier.size(16.dp.applyScaleUp()), resourceId = iconId, contentDescription = contentDescription, // Exception here, we use Color.White instead of ElementTheme.colors.iconOnSolidPrimary From 157e761000a7ca4d7cabce0f0afbc155b17ea531 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Jul 2023 15:33:35 +0200 Subject: [PATCH 32/37] Rewrite the test, maybe the CI will be happier. --- .../element/android/features/messages/MessagesPresenterTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 6ff003b735..c19dbe7cdc 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -548,8 +548,9 @@ class MessagesPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = consumeItemsUntilTimeout().last() + val initialState = consumeItemsUntilPredicate { it.userHasPermissionToRedact }.last() assertThat(initialState.userHasPermissionToRedact).isTrue() + cancelAndIgnoreRemainingEvents() } } From aabb455ea4c5f85a5b741e7ed758b28f94735e7b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Jul 2023 11:59:49 +0200 Subject: [PATCH 33/37] Split long line. --- .../element/android/libraries/textcomposer/TextComposer.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index a802298624..7b54b02c16 100644 --- a/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -169,7 +169,12 @@ fun TextComposer( singleLine = false, visualTransformation = VisualTransformation.None, shape = roundedCorners, - contentPadding = PaddingValues(top = 10.dp.applyScaleUp(), bottom = 10.dp.applyScaleUp(), start = 12.dp.applyScaleUp(), end = 42.dp.applyScaleUp()), + contentPadding = PaddingValues( + top = 10.dp.applyScaleUp(), + bottom = 10.dp.applyScaleUp(), + start = 12.dp.applyScaleUp(), + end = 42.dp.applyScaleUp(), + ), interactionSource = remember { MutableInteractionSource() }, placeholder = { Text(stringResource(CommonStrings.common_message), style = defaultTypography) From 4d7307bae29461b34942e03463489ae360b387dc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Jul 2023 16:04:30 +0200 Subject: [PATCH 34/37] Showkase does not take into account the `fontScale` parameter of the Preview annotation, so alter the LocalDensity in the CompositionLocalProvider. --- .../designsystem/preview/WithFontScale.kt | 38 ++++++ .../libraries/designsystem/text/DpScale.kt | 121 +++++++++--------- 2 files changed, 102 insertions(+), 57 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/WithFontScale.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/WithFontScale.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/WithFontScale.kt new file mode 100644 index 0000000000..6d3ecfc82b --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/preview/WithFontScale.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.preview + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Density + +/** + * Showkase does not take into account the `fontScale` parameter of the Preview annotation, so alter the + * LocalDensity in the CompositionLocalProvider. + */ +@Composable +fun WithFontScale(fontScale: Float, content: @Composable () -> Unit) { + CompositionLocalProvider( + LocalDensity provides Density( + density = LocalDensity.current.density, + fontScale = fontScale + ) + ) { + content() + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt index c4c524e804..8576214351 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.preview.WithFontScale import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.theme.ElementTheme @@ -49,71 +50,77 @@ fun Dp.applyScaleUp(): Dp = with(LocalDensity.current) { return this@applyScaleUp * fontScale.coerceAtLeast(1f) } -@Preview(fontScale = 0.75f) +@Preview @Composable -fun DpScalePreview_0_75f() = ElementPreviewLight { - val fontSizeInDp = 16.dp - Column( - modifier = Modifier.padding(4.dp), - verticalArrangement = Arrangement.spacedBy(6.dp) - ) { - Text( - text = "A text should have a size of 16.sp", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) - ) - Text( - text = "A text should have the same size (applyScaleUp)", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) - ) - Text( - text = "A text should be smaller (applyScaleDown)", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) - ) +fun DpScalePreview_0_75f() = WithFontScale(0.75f) { + ElementPreviewLight { + val fontSizeInDp = 16.dp + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + text = "Text with size of 16.sp", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) + ) + Text( + text = "Text with the same size (applyScaleUp)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) + ) + Text( + text = "Text with a smaller size (applyScaleDown)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) + ) + } } } -@Preview(fontScale = 1.0f) +@Preview @Composable -fun DpScalePreview_1_0f() = ElementPreviewLight { - val fontSizeInDp = 16.dp - Column( - modifier = Modifier.padding(4.dp), - verticalArrangement = Arrangement.spacedBy(6.dp) - ) { - Text( - text = "A text with a size of 16.sp", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) - ) - Text( - text = "A text with the same size (applyScaleUp)", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) - ) - Text( - text = "A text with the same size (applyScaleDown)", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) - ) +fun DpScalePreview_1_0f() = WithFontScale(1f) { + ElementPreviewLight { + val fontSizeInDp = 16.dp + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + text = "Text with size of 16.sp", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) + ) + Text( + text = "Text with the same size (applyScaleUp)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) + ) + Text( + text = "Text with the same size (applyScaleDown)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) + ) + } } } -@Preview(fontScale = 1.5f) +@Preview @Composable -fun DpScalePreview_1_5f() = ElementPreviewLight { - val fontSizeInDp = 16.dp - Column( - modifier = Modifier.padding(4.dp), - verticalArrangement = Arrangement.spacedBy(6.dp) - ) { - Text( - text = "A text with a size of 16.sp", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) - ) - Text( - text = "A text with a bigger size (applyScaleUp)", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) - ) - Text( - text = "A text with the same size (applyScaleDown)", - style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) - ) +fun DpScalePreview_1_5f() = WithFontScale(1.5f) { + ElementPreviewLight { + val fontSizeInDp = 16.dp + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(6.dp) + ) { + Text( + text = "Text with size of 16.sp", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.toSp()) + ) + Text( + text = "Text with a bigger size (applyScaleUp)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleUp().toSp()) + ) + Text( + text = "Text with the same size (applyScaleDown)", + style = ElementTheme.typography.fontBodyLgRegular.copy(fontSize = fontSizeInDp.applyScaleDown().toSp()) + ) + } } } From cac4aa6f42e09a7e822f694505ad144e13c6f0c5 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 28 Jul 2023 14:24:03 +0000 Subject: [PATCH 35/37] Update screenshots --- ...efaultGroup_DpScalePreview_0_75f_0_null,NEXUS_5,1.0,en].png | 3 +++ ...DefaultGroup_DpScalePreview_1_0f_0_null,NEXUS_5,1.0,en].png | 3 +++ ...DefaultGroup_DpScalePreview_1_5f_0_null,NEXUS_5,1.0,en].png | 3 +++ 3 files changed, 9 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_0_75f_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_0f_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_5f_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_0_75f_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_0_75f_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..60a3b8f39e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_0_75f_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:373fcfdea163cd59d1b929adb1abf7163c0e1aaa203033292931fd22cd5c60d6 +size 22378 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_0f_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_0f_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9a02d72493 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_0f_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1e171c6295cd93af0fc0533b8c3099c75d5343132477709e231848c0c51b35f +size 24366 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_5f_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_5f_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9600daf12b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.text_null_DefaultGroup_DpScalePreview_1_5f_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45485288d1cd0552c371aa868600e1fd8c30232ea2d9cb26420ec36c539cdb6f +size 28228 From 8dd1aeabff062ac0ba023b8f50718f82d59e3e52 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 28 Jul 2023 16:15:34 +0200 Subject: [PATCH 36/37] fix typo --- .../io/element/android/libraries/designsystem/text/DpScale.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt index 8576214351..7a4f5dd172 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/text/DpScale.kt @@ -31,7 +31,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.theme.ElementTheme /** - * Return the maximum value between the receiver value and the value with fonScale applied. + * Return the maximum value between the receiver value and the value with fontScale applied. * So if fontScale is >= 1f, the same value is returned, and if fontScale is < 1f, so returned value * will be smaller. */ @@ -41,7 +41,7 @@ fun Dp.applyScaleDown(): Dp = with(LocalDensity.current) { } /** - * Return the minimum value between the receiver value and the value with fonScale applied. + * Return the minimum value between the receiver value and the value with fontScale applied. * So if fontScale is <= 1f, the same value is returned, and if fontScale is > 1f, so returned value * will be bigger. */ From 82d15422413801dfc8f1a39f5c30d14d7e457190 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Jul 2023 04:17:49 +0000 Subject: [PATCH 37/37] Update anvil to v2.4.7-1-8 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ff37e483d8..98767036ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -49,7 +49,7 @@ telephoto = "0.4.0" # DI dagger = "2.47" -anvil = "2.4.6" +anvil = "2.4.7-1-8" # Auto service autoservice = "1.1.1"