Skip to content

Commit 310d9df

Browse files
committed
Extracting some individual composables from HEConversation screen file
1 parent d1a9aaf commit 310d9df

File tree

3 files changed

+333
-273
lines changed

3 files changed

+333
-273
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package org.wordpress.android.support.he.ui
2+
3+
import android.content.res.Configuration.UI_MODE_NIGHT_YES
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.clickable
6+
import androidx.compose.foundation.gestures.detectTransformGestures
7+
import androidx.compose.foundation.layout.Arrangement
8+
import androidx.compose.foundation.layout.Box
9+
import androidx.compose.foundation.layout.Row
10+
import androidx.compose.foundation.layout.fillMaxSize
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.layout.size
13+
import androidx.compose.foundation.shape.RoundedCornerShape
14+
import androidx.compose.material.icons.Icons
15+
import androidx.compose.material.icons.filled.Close
16+
import androidx.compose.material3.CircularProgressIndicator
17+
import androidx.compose.material3.Icon
18+
import androidx.compose.material3.IconButton
19+
import androidx.compose.material3.Surface
20+
import androidx.compose.runtime.Composable
21+
import androidx.compose.runtime.getValue
22+
import androidx.compose.runtime.mutableFloatStateOf
23+
import androidx.compose.runtime.remember
24+
import androidx.compose.runtime.setValue
25+
import androidx.compose.ui.Alignment
26+
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.graphics.Color
28+
import androidx.compose.ui.graphics.graphicsLayer
29+
import androidx.compose.ui.input.pointer.pointerInput
30+
import androidx.compose.ui.layout.ContentScale
31+
import androidx.compose.ui.platform.LocalContext
32+
import androidx.compose.ui.res.painterResource
33+
import androidx.compose.ui.res.stringResource
34+
import androidx.compose.ui.semantics.contentDescription
35+
import androidx.compose.ui.semantics.semantics
36+
import androidx.compose.ui.tooling.preview.Preview
37+
import androidx.compose.ui.unit.dp
38+
import androidx.compose.ui.window.Dialog
39+
import androidx.compose.ui.window.DialogProperties
40+
import coil.compose.SubcomposeAsyncImage
41+
import coil.request.ImageRequest
42+
import org.wordpress.android.R
43+
import org.wordpress.android.ui.compose.theme.AppThemeM3
44+
45+
@Composable
46+
fun AttachmentFullscreenImagePreview(
47+
imageUrl: String,
48+
onDismiss: () -> Unit,
49+
onDownload: () -> Unit = {}
50+
) {
51+
var scale by remember { mutableFloatStateOf(1f) }
52+
var offsetX by remember { mutableFloatStateOf(0f) }
53+
var offsetY by remember { mutableFloatStateOf(0f) }
54+
55+
// Load semantics
56+
val loadingImageDescription = stringResource(R.string.he_support_loading_image)
57+
val attachmentImageDescription = stringResource(R.string.he_support_attachment_image)
58+
val failedToLoadImageDescription = stringResource(R.string.he_support_failed_to_load_image)
59+
60+
Dialog(
61+
onDismissRequest = onDismiss,
62+
properties = DialogProperties(
63+
usePlatformDefaultWidth = false,
64+
dismissOnBackPress = true,
65+
dismissOnClickOutside = false
66+
)
67+
) {
68+
Surface(
69+
modifier = Modifier
70+
.fillMaxSize()
71+
.clickable(onClick = onDismiss),
72+
color = Color.Black
73+
) {
74+
Box(
75+
modifier = Modifier.fillMaxSize()
76+
) {
77+
CircularProgressIndicator(
78+
modifier = Modifier
79+
.align(Alignment.Center)
80+
.semantics {
81+
contentDescription = loadingImageDescription
82+
}
83+
)
84+
// Zoomable image
85+
Box(
86+
modifier = Modifier.fillMaxSize(),
87+
contentAlignment = Alignment.Center
88+
) {
89+
SubcomposeAsyncImage(
90+
model = ImageRequest.Builder(LocalContext.current)
91+
.data(imageUrl)
92+
.crossfade(true)
93+
.build(),
94+
contentDescription = attachmentImageDescription,
95+
modifier = Modifier
96+
.fillMaxSize()
97+
.graphicsLayer(
98+
scaleX = scale,
99+
scaleY = scale,
100+
translationX = offsetX,
101+
translationY = offsetY
102+
)
103+
.pointerInput(Unit) {
104+
detectTransformGestures { _, pan, zoom, _ ->
105+
scale = (scale * zoom).coerceIn(1f, 5f)
106+
if (scale > 1f) {
107+
offsetX += pan.x
108+
offsetY += pan.y
109+
} else {
110+
offsetX = 0f
111+
offsetY = 0f
112+
}
113+
}
114+
},
115+
contentScale = ContentScale.Fit,
116+
error = {
117+
Icon(
118+
painter = painterResource(R.drawable.ic_image_white_24dp),
119+
contentDescription = failedToLoadImageDescription,
120+
tint = Color.White,
121+
modifier = Modifier.size(48.dp)
122+
)
123+
}
124+
)
125+
}
126+
127+
// Top bar with close button
128+
Row(
129+
modifier = Modifier
130+
.align(Alignment.TopEnd)
131+
.padding(16.dp)
132+
.background(
133+
color = Color.Black.copy(alpha = 0.5f),
134+
shape = RoundedCornerShape(24.dp)
135+
)
136+
.padding(4.dp),
137+
horizontalArrangement = Arrangement.spacedBy(4.dp)
138+
) {
139+
// Download button
140+
IconButton(
141+
onClick = {
142+
onDownload.invoke()
143+
onDismiss.invoke()
144+
}
145+
) {
146+
Icon(
147+
painter = painterResource(R.drawable.ic_get_app_white_24dp),
148+
contentDescription = stringResource(R.string.he_support_download_image),
149+
tint = Color.White,
150+
modifier = Modifier.size(24.dp)
151+
)
152+
}
153+
154+
// Close button
155+
IconButton(
156+
onClick = onDismiss
157+
) {
158+
Icon(
159+
imageVector = Icons.Filled.Close,
160+
contentDescription = stringResource(R.string.close),
161+
tint = Color.White,
162+
modifier = Modifier.size(24.dp)
163+
)
164+
}
165+
}
166+
}
167+
}
168+
}
169+
}
170+
171+
@Preview(showBackground = true, name = "Fullscreen Image Preview")
172+
@Composable
173+
private fun AttachmentFullscreenImagePreviewPreview() {
174+
AppThemeM3(isDarkTheme = false) {
175+
AttachmentFullscreenImagePreview(
176+
imageUrl = "https://via.placeholder.com/800x600",
177+
onDismiss = { },
178+
onDownload = { }
179+
)
180+
}
181+
}
182+
183+
@Preview(showBackground = true, name = "Fullscreen Image Preview - Dark", uiMode = UI_MODE_NIGHT_YES)
184+
@Composable
185+
private fun AttachmentFullscreenImagePreviewPreviewDark() {
186+
AppThemeM3(isDarkTheme = true) {
187+
AttachmentFullscreenImagePreview(
188+
imageUrl = "https://via.placeholder.com/800x600",
189+
onDismiss = { },
190+
onDownload = { }
191+
)
192+
}
193+
}

0 commit comments

Comments
 (0)