Skip to content

Commit 71c0eb1

Browse files
authored
Merge pull request #3537 from element-hq/feature/fga/fix_image_viewer_glitch
Fix image viewer glitch
2 parents ff872af + acae30b commit 71c0eb1

File tree

3 files changed

+19
-28
lines changed

3 files changed

+19
-28
lines changed

features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ import io.element.android.features.roomdetails.impl.notificationsettings.RoomNot
3333
import io.element.android.features.roomdetails.impl.rolesandpermissions.RolesAndPermissionsFlowNode
3434
import io.element.android.features.userprofile.shared.UserProfileNodeHelper
3535
import io.element.android.features.userprofile.shared.avatar.AvatarPreviewNode
36-
import io.element.android.libraries.architecture.BackstackView
36+
import io.element.android.libraries.architecture.BackstackWithOverlayBox
3737
import io.element.android.libraries.architecture.BaseFlowNode
3838
import io.element.android.libraries.architecture.createNode
39+
import io.element.android.libraries.architecture.overlay.operation.show
3940
import io.element.android.libraries.core.mimetype.MimeTypes
4041
import io.element.android.libraries.di.RoomScope
4142
import io.element.android.libraries.matrix.api.core.RoomId
@@ -125,7 +126,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
125126
}
126127

127128
override fun openAvatarPreview(name: String, url: String) {
128-
backstack.push(NavTarget.AvatarPreview(name, url))
129+
overlay.show(NavTarget.AvatarPreview(name, url))
129130
}
130131

131132
override fun openPollHistory() {
@@ -186,7 +187,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
186187
is NavTarget.RoomMemberDetails -> {
187188
val callback = object : UserProfileNodeHelper.Callback {
188189
override fun openAvatarPreview(username: String, avatarUrl: String) {
189-
backstack.push(NavTarget.AvatarPreview(username, avatarUrl))
190+
overlay.show(NavTarget.AvatarPreview(username, avatarUrl))
190191
}
191192

192193
override fun onStartDM(roomId: RoomId) {
@@ -252,6 +253,6 @@ class RoomDetailsFlowNode @AssistedInject constructor(
252253

253254
@Composable
254255
override fun View(modifier: Modifier) {
255-
BackstackView()
256+
BackstackWithOverlayBox(modifier)
256257
}
257258
}

libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerView.kt

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import androidx.compose.ui.res.stringResource
4040
import androidx.compose.ui.tooling.preview.Preview
4141
import androidx.compose.ui.tooling.preview.PreviewParameter
4242
import androidx.compose.ui.unit.dp
43+
import coil.compose.AsyncImage
4344
import io.element.android.compound.tokens.generated.CompoundIcons
4445
import io.element.android.libraries.architecture.AsyncData
4546
import io.element.android.libraries.core.mimetype.MimeTypes
@@ -66,9 +67,6 @@ import me.saket.telephoto.flick.FlickToDismiss
6667
import me.saket.telephoto.flick.FlickToDismissState
6768
import me.saket.telephoto.flick.rememberFlickToDismissState
6869
import me.saket.telephoto.zoomable.ZoomSpec
69-
import me.saket.telephoto.zoomable.ZoomableState
70-
import me.saket.telephoto.zoomable.coil.ZoomableAsyncImage
71-
import me.saket.telephoto.zoomable.rememberZoomableImageState
7270
import me.saket.telephoto.zoomable.rememberZoomableState
7371
import kotlin.time.Duration
7472

@@ -181,7 +179,6 @@ private fun MediaViewerPage(
181179
mediaInfo = state.mediaInfo,
182180
thumbnailSource = state.thumbnailSource,
183181
isVisible = showThumbnail,
184-
zoomableState = zoomableState
185182
)
186183
if (showError) {
187184
ErrorView(
@@ -316,24 +313,18 @@ private fun ThumbnailView(
316313
thumbnailSource: MediaSource?,
317314
isVisible: Boolean,
318315
mediaInfo: MediaInfo,
319-
zoomableState: ZoomableState,
320316
modifier: Modifier = Modifier,
321317
) {
322-
AnimatedVisibility(
323-
visible = isVisible,
324-
enter = fadeIn(),
325-
exit = fadeOut()
318+
Box(
319+
modifier = modifier.fillMaxSize(),
320+
contentAlignment = Alignment.Center
326321
) {
327-
Box(
328-
modifier = modifier.fillMaxSize(),
329-
contentAlignment = Alignment.Center
330-
) {
322+
if (isVisible) {
331323
val mediaRequestData = MediaRequestData(
332324
source = thumbnailSource,
333325
kind = MediaRequestData.Kind.File(mediaInfo.name, mediaInfo.mimeType)
334326
)
335-
ZoomableAsyncImage(
336-
state = rememberZoomableImageState(zoomableState),
327+
AsyncImage(
337328
modifier = Modifier.fillMaxSize(),
338329
model = mediaRequestData,
339330
contentScale = ContentScale.Fit,

libraries/mediaviewer/api/src/test/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerViewTest.kt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import io.element.android.tests.testutils.EventsRecorder
2626
import io.element.android.tests.testutils.clickOn
2727
import io.element.android.tests.testutils.ensureCalledOnce
2828
import io.element.android.tests.testutils.pressBack
29-
import org.junit.Ignore
3029
import org.junit.Rule
3130
import org.junit.Test
3231
import org.junit.rules.TestRule
@@ -81,7 +80,6 @@ class MediaViewerViewTest {
8180
eventsRecorder.assertSingle(expectedEvent)
8281
}
8382

84-
@Ignore("This test is not passing yet, maybe due to interaction with ZoomableAsyncImage?")
8583
@Test
8684
fun `clicking on image hides the overlay`() {
8785
val eventsRecorder = EventsRecorder<MediaViewerEvents>(expectEvents = false)
@@ -96,16 +94,17 @@ class MediaViewerViewTest {
9694
)
9795
// Ensure that the action are visible
9896
val contentDescription = rule.activity.getString(CommonStrings.action_open_with)
99-
rule.onNodeWithContentDescription(contentDescription).assertHasClickAction()
97+
rule.onNodeWithContentDescription(contentDescription)
98+
.assertExists()
99+
.assertHasClickAction()
100100
val imageContentDescription = rule.activity.getString(CommonStrings.common_image)
101101
rule.onNodeWithContentDescription(imageContentDescription).performClick()
102-
// assertHasNoClickAction does not work as expected (?)
103-
// rule.onNodeWithContentDescription(contentDescription).assertHasNoClickAction()
104-
rule.onNodeWithContentDescription(contentDescription).performClick()
105-
// No emitted event
102+
// Give time for the animation (? since even by removing AnimatedVisibility it still fails)
103+
rule.mainClock.advanceTimeBy(1_000)
104+
rule.onNodeWithContentDescription(contentDescription)
105+
.assertDoesNotExist()
106106
}
107107

108-
@Ignore("This test is not passing yet, maybe due to interaction with ZoomableAsyncImage?")
109108
@Test
110109
fun `clicking swipe on the image invokes the expected callback`() {
111110
val eventsRecorder = EventsRecorder<MediaViewerEvents>(expectEvents = false)
@@ -121,7 +120,7 @@ class MediaViewerViewTest {
121120
onBackClick = callback,
122121
)
123122
val imageContentDescription = rule.activity.getString(CommonStrings.common_image)
124-
rule.onNodeWithContentDescription(imageContentDescription).performTouchInput { swipeDown() }
123+
rule.onNodeWithContentDescription(imageContentDescription).performTouchInput { swipeDown(startY = centerY) }
125124
rule.mainClock.advanceTimeBy(1_000)
126125
}
127126
}

0 commit comments

Comments
 (0)