From 5d4b2839fae0b7806fa03536340fcc5aa3301440 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 16:22:13 +0100 Subject: [PATCH 1/4] Protected Content: ensure that user cannot open fullscreen unless the content has first been revealed in the timeline. --- .../impl/timeline/components/TimelineItemEventRow.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index c358dcdd0a..fa14877c6d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -72,6 +72,7 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState +import io.element.android.features.messages.impl.timeline.protection.mustBeProtected import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar @@ -146,6 +147,13 @@ fun TimelineItemEventRow( val coroutineScope = rememberCoroutineScope() val interactionSource = remember { MutableInteractionSource() } + val onContentClick = if (event.mustBeProtected()) { + // In this case, let the content handle the click + {} + } else { + onEventClick + } + fun onUserDataClick() { onUserDataClick(event.senderId) } @@ -178,7 +186,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onContentClick = onEventClick, + onContentClick = onContentClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, @@ -212,7 +220,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onContentClick = onEventClick, + onContentClick = onContentClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, From c7e52a8d99585648e327f6c68f8c7c65483504c9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 18:17:29 +0100 Subject: [PATCH 2/4] Protected Content: ensure that the ratio is not too extreme so that the "Show" button is always visible. --- .../components/event/TimelineItemImageView.kt | 3 ++- .../event/TimelineItemStickerView.kt | 3 ++- .../components/event/TimelineItemVideoView.kt | 3 ++- .../protection/AspectRatioPreviewProvider.kt | 19 +++++++++++++++++++ .../impl/timeline/protection/ProtectedView.kt | 14 ++++++++------ .../impl/timeline/protection/RatioHelper.kt | 19 +++++++++++++++++++ 6 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt index 84b7026142..651f361d6c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt @@ -49,6 +49,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContentProvider import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.protection.ProtectedView +import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -79,7 +80,7 @@ fun TimelineItemImageView( } TimelineItemAspectRatioBox( modifier = containerModifier.blurHashBackground(content.blurhash, alpha = 0.9f), - aspectRatio = content.aspectRatio, + aspectRatio = coerceRatioWhenHidingContent(content.aspectRatio, hideMediaContent), ) { ProtectedView( hideContent = hideMediaContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt index 9037d0dffa..fd78699ac1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt @@ -30,6 +30,7 @@ import coil.compose.AsyncImagePainter import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContentProvider import io.element.android.features.messages.impl.timeline.protection.ProtectedView +import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -54,7 +55,7 @@ fun TimelineItemStickerView( ) { TimelineItemAspectRatioBox( modifier = Modifier.blurHashBackground(content.blurhash, alpha = 0.9f), - aspectRatio = content.aspectRatio, + aspectRatio = coerceRatioWhenHidingContent(content.aspectRatio, hideMediaContent), minHeight = STICKER_SIZE_IN_DP, maxHeight = STICKER_SIZE_IN_DP, ) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt index afd45b171a..eadd84d130 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt @@ -54,6 +54,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContentProvider import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVideoContent import io.element.android.features.messages.impl.timeline.protection.ProtectedView +import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.modifiers.roundedBackground import io.element.android.libraries.designsystem.preview.ElementPreview @@ -90,7 +91,7 @@ fun TimelineItemVideoView( } TimelineItemAspectRatioBox( modifier = containerModifier.blurHashBackground(content.blurHash, alpha = 0.9f), - aspectRatio = content.aspectRatio, + aspectRatio = coerceRatioWhenHidingContent(content.aspectRatio, hideMediaContent), contentAlignment = Alignment.Center, ) { ProtectedView( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt new file mode 100644 index 0000000000..fb296ef7bf --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.protection + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +class AspectRatioPreviewProvider : PreviewParameterProvider { + override val values: Sequence = sequenceOf( + null, + 0.05f, + 1f, + 20f, + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt index 0387572388..631967b6c2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable @@ -23,8 +22,10 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme +import io.element.android.features.messages.impl.timeline.components.event.TimelineItemAspectRatioBox import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -79,11 +80,12 @@ fun ProtectedView( @PreviewsDayNight @Composable -internal fun ProtectedViewPreview() = ElementPreview { - Box( - modifier = Modifier - .size(160.dp) - .blurHashBackground(A_BLUR_HASH) +internal fun ProtectedViewPreview( + @PreviewParameter(AspectRatioPreviewProvider::class) aspectRatio: Float?, +) = ElementPreview { + TimelineItemAspectRatioBox( + modifier = Modifier.blurHashBackground(A_BLUR_HASH, alpha = 0.9f), + aspectRatio = coerceRatioWhenHidingContent(aspectRatio, true), ) { ProtectedView( hideContent = true, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt new file mode 100644 index 0000000000..2386dff5f4 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.protection + +fun coerceRatioWhenHidingContent(aspectRatio: Float?, hideContent: Boolean): Float? { + return if (hideContent) { + aspectRatio?.coerceIn( + minimumValue = 0.5f, + maximumValue = 3f + ) + } else { + aspectRatio + } +} From 5ff8876fb4ff24c0f7c22036f636691270e339fe Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 21 Nov 2024 08:19:57 +0000 Subject: [PATCH 3/4] Update screenshots --- ...ssages.impl.timeline.protection_ProtectedView_Day_0_en.png | 4 ++-- ...ssages.impl.timeline.protection_ProtectedView_Day_1_en.png | 3 +++ ...ssages.impl.timeline.protection_ProtectedView_Day_2_en.png | 3 +++ ...ssages.impl.timeline.protection_ProtectedView_Day_3_en.png | 3 +++ ...ages.impl.timeline.protection_ProtectedView_Night_0_en.png | 4 ++-- ...ages.impl.timeline.protection_ProtectedView_Night_1_en.png | 3 +++ ...ages.impl.timeline.protection_ProtectedView_Night_2_en.png | 3 +++ ...ages.impl.timeline.protection_ProtectedView_Night_3_en.png | 3 +++ 8 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png index 6dd8676eee..b08546ebae 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db067468af10a72fbaa437a00937afddba100f5345317b9c23b03c8920d5cffa -size 33401 +oid sha256:f40c56aa3b794ce62db9688bf481561d5229a459921e54f55885a6db8f74fe21 +size 64604 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png new file mode 100644 index 0000000000..0103ed2548 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78ea6cbfcf12e405eca8b953b3d847e73f80121ad47beb6346563a2e9b5d567b +size 56342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png new file mode 100644 index 0000000000..17cfaf70ee --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07ab4fb940d9cae7dcd82d1d6e7235091154414bbb1a6f3a7f557775f8730497 +size 79880 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png new file mode 100644 index 0000000000..6293147f11 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4bafcbc5bc5a62e686adc7194f72a7394b462ad4d99afb0a35380c2f8e1fbeb +size 37409 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png index 3c4052880c..119082c561 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0fc9f20bae5c54d807f5917844669bb8909514483d2ad29b348ef18f8f986a6 -size 33356 +oid sha256:2e3dfc75223f91ecd21c59980a393244be7dfb93a0ebee0885d75fdf5d33d53a +size 64347 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png new file mode 100644 index 0000000000..9e571c9b94 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:047da66e7f7e78478b1d8442028224073e3d31493b5facf926472fc526532be1 +size 56473 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png new file mode 100644 index 0000000000..b38384d81f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d16153ecf852fc504cabc60722eccbe484c992c1bced50f067fb58c46dfd4f7 +size 79088 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png new file mode 100644 index 0000000000..c43a15f287 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2aa2e5da25b8a83db35d9b065f0b89cc745cfbda3f6a81d31e445fa31bf4431a +size 37381 From aa1948ac44ab716aa776176b6c576e960c12c967 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 15:18:56 +0100 Subject: [PATCH 4/4] Fix test and rename class to follow naming convention for PreviewParameterProvider. --- .../{AspectRatioPreviewProvider.kt => AspectRatioProvider.kt} | 2 +- .../messages/impl/timeline/protection/ProtectedView.kt | 2 +- .../io/element/android/tests/konsist/KonsistClassNameTest.kt | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) rename features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/{AspectRatioPreviewProvider.kt => AspectRatioProvider.kt} (85%) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioProvider.kt similarity index 85% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt rename to features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioProvider.kt index fb296ef7bf..99cfff5625 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioProvider.kt @@ -9,7 +9,7 @@ package io.element.android.features.messages.impl.timeline.protection import androidx.compose.ui.tooling.preview.PreviewParameterProvider -class AspectRatioPreviewProvider : PreviewParameterProvider { +class AspectRatioProvider : PreviewParameterProvider { override val values: Sequence = sequenceOf( null, 0.05f, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt index 631967b6c2..b52084233b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt @@ -81,7 +81,7 @@ fun ProtectedView( @PreviewsDayNight @Composable internal fun ProtectedViewPreview( - @PreviewParameter(AspectRatioPreviewProvider::class) aspectRatio: Float?, + @PreviewParameter(AspectRatioProvider::class) aspectRatio: Float?, ) = ElementPreview { TimelineItemAspectRatioBox( modifier = Modifier.blurHashBackground(A_BLUR_HASH, alpha = 0.9f), diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt index 8f7d446d67..adc2b9ceb7 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt @@ -48,6 +48,9 @@ class KonsistClassNameTest { Konsist.scopeFromProduction() .classes() .withAllParentsOf(PreviewParameterProvider::class) + .withoutName( + "AspectRatioProvider", + ) .also { // Check that classes are actually found assertThat(it.size).isGreaterThan(100)