@@ -12,29 +12,26 @@ import androidx.compose.foundation.layout.Spacer
1212import androidx.compose.foundation.layout.aspectRatio
1313import androidx.compose.foundation.layout.fillMaxSize
1414import androidx.compose.foundation.layout.fillMaxWidth
15- import androidx.compose.foundation.layout.height
1615import androidx.compose.foundation.layout.padding
1716import androidx.compose.foundation.layout.size
1817import androidx.compose.foundation.layout.width
1918import androidx.compose.foundation.shape.CircleShape
2019import androidx.compose.material3.MaterialTheme
2120import androidx.compose.material3.Text
2221import androidx.compose.runtime.Composable
23- import androidx.compose.runtime.remember
2422import androidx.compose.ui.Alignment
2523import androidx.compose.ui.Modifier
2624import androidx.compose.ui.draw.clip
2725import androidx.compose.ui.graphics.Brush
2826import androidx.compose.ui.graphics.Color
2927import androidx.compose.ui.graphics.ColorFilter
3028import androidx.compose.ui.layout.ContentScale
31- import androidx.compose.ui.res.dimensionResource
29+ import androidx.compose.ui.platform.LocalContext
3230import androidx.compose.ui.res.painterResource
3331import androidx.compose.ui.text.style.TextAlign
3432import androidx.compose.ui.text.style.TextOverflow
3533import androidx.compose.ui.tooling.preview.Preview
3634import androidx.compose.ui.unit.Dp
37- import androidx.compose.ui.unit.dp
3835import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi
3936import com.bumptech.glide.integration.compose.GlideImage
4037import network.loki.messenger.R
@@ -43,8 +40,9 @@ import org.thoughtcrime.securesms.ui.theme.LocalColors
4340import org.thoughtcrime.securesms.ui.theme.LocalType
4441import org.thoughtcrime.securesms.util.MediaUtil
4542import kotlin.collections.filterNot
46- import kotlin.collections.indexOfFirst
4743import androidx.core.net.toUri
44+ import coil3.compose.AsyncImage
45+ import coil3.request.ImageRequest
4846import org.thoughtcrime.securesms.ui.theme.LocalDimensions
4947
5048@OptIn(ExperimentalGlideComposeApi ::class )
@@ -61,12 +59,15 @@ fun MediaFolderCell(
6159 .clickable(onClick = onClick)
6260 ) {
6361 Box (modifier = Modifier .aspectRatio(1f )) {
64- GlideImage (
65- model = thumbnailUri,
62+ AsyncImage (
63+ modifier = Modifier .fillMaxWidth(),
64+ contentScale = ContentScale .Crop ,
65+ model = ImageRequest .Builder (LocalContext .current)
66+ .data(thumbnailUri)
67+ .build(),
6668 contentDescription = null ,
67- modifier = Modifier .fillMaxSize(),
68- contentScale = ContentScale .Crop
6969 )
70+
7071 // Bottom shade overlay
7172 Box (
7273 modifier = Modifier
@@ -125,34 +126,16 @@ fun MediaFolderCell(
125126@Composable
126127fun MediaPickerItemCell (
127128 media : Media ,
128- selected : List < Media > ,
129- forcedMultiSelect : Boolean ,
130- maxSelection : Int ,
129+ isSelected : Boolean = false ,
130+ selectedIndex : Int = 1 ,
131+ isMultiSelect : Boolean ,
131132 onMediaChosen : (Media ) -> Unit ,
132133 onSelectionStarted : () -> Unit ,
133- onSelectionChanged : (List <Media >) -> Unit ,
134- onSelectionOverflow : (Int ) -> Unit ,
134+ onSelectionChanged : (selectedMedia: Media ) -> Unit ,
135135 modifier : Modifier = Modifier ,
136+ showSelectionOn : Boolean = false,
137+ canLongPress : Boolean = true
136138) {
137- val isSelected = selected.any { it.uri == media.uri }
138- val selectedIndex = remember(selected, media) {
139- selected.indexOfFirst { it.uri == media.uri }
140- }
141-
142- // Matches adapter rules:
143- val inSelectionUi = ! (selected.isEmpty() && ! forcedMultiSelect)
144- val showSelectOff = inSelectionUi
145- val showSelectOn = inSelectionUi && isSelected
146- val showSelectOverlay = isSelected
147-
148- val canStartSelectionByLongPress = maxSelection > 1 && selected.isEmpty() && ! forcedMultiSelect
149-
150- fun removeFromSelection (): List <Media > =
151- selected.filterNot { it.uri == media.uri }
152-
153- fun addToSelection (): List <Media > =
154- selected + media
155-
156139 Box (
157140 modifier = modifier
158141 .aspectRatio(1f )
@@ -162,36 +145,29 @@ fun MediaPickerItemCell(
162145 )
163146 .combinedClickable(
164147 onClick = {
165- if (selected.isEmpty() && ! forcedMultiSelect) {
166- // adapter: direct choose
167- onMediaChosen(media)
168- } else if (isSelected) {
169- // adapter: remove
170- onSelectionChanged(removeFromSelection())
148+ if (! isMultiSelect) {
149+ onMediaChosen(media) // Choosing a single media
171150 } else {
172- // adapter: add if room else overflow
173- if (selected.size < maxSelection) {
174- onSelectionChanged(addToSelection())
175- } else {
176- onSelectionOverflow(maxSelection)
177- }
151+ onSelectionChanged(media) // Selecting/unselecting media
178152 }
179153 },
180- onLongClick = if (canStartSelectionByLongPress ) {
154+ onLongClick = if (canLongPress ) {
181155 {
182- // adapter: long press starts selection, adds this item
183- onSelectionChanged(listOf ( media) )
156+ // long press starts selection, adds this item
157+ onSelectionChanged(media)
184158 onSelectionStarted()
185159 }
186160 } else null
187161 )
188162 ) {
189163 // Thumbnail
190- GlideImage (
191- model = media.uri,
192- contentDescription = null ,
164+ AsyncImage (
193165 modifier = Modifier .fillMaxSize(),
194- contentScale = ContentScale .Crop
166+ contentScale = ContentScale .Crop ,
167+ model = ImageRequest .Builder (LocalContext .current)
168+ .data(media.uri)
169+ .build(),
170+ contentDescription = null ,
195171 )
196172
197173 // Play overlay (center) for video
@@ -214,41 +190,41 @@ fun MediaPickerItemCell(
214190 }
215191
216192 // Selection overlay
217- if (showSelectOverlay ) {
193+ if (isSelected ) {
218194 Box (
219195 Modifier
220196 .matchParentSize()
221197 .background(Color .Black .copy(alpha = 0.80f ))
222198 )
223199 }
224200
225- // Select OFF badge (top-end)
226- if (showSelectOff) {
227- Box (
228- modifier = Modifier
229- .align(Alignment .TopEnd )
230- .padding(LocalDimensions .current.xxsSpacing)
231- ) {
232- IndicatorOff (size = LocalDimensions .current.smallRadius)
233- }
234- }
235-
236- // Select ON badge + order number (top-end)
237- if (showSelectOn) {
238- Box (
239- modifier = Modifier
240- .align(Alignment .TopEnd )
241- .padding(LocalDimensions .current.xxsSpacing),
242- contentAlignment = Alignment .Center
243- ) {
244- IndicatorOn (size = LocalDimensions .current.smallRadius)
201+ if (isMultiSelect) {
202+ // Select ON badge + order number (top-end)
203+ if (showSelectionOn) {
204+ Box (
205+ modifier = Modifier
206+ .align(Alignment .TopEnd )
207+ .padding(LocalDimensions .current.xxsSpacing),
208+ contentAlignment = Alignment .Center
209+ ) {
210+ IndicatorOn (size = LocalDimensions .current.smallRadius)
245211
246- Text (
247- text = (selectedIndex + 1 ).toString(),
248- color = LocalColors .current.onInvertedBackgroundAccent,
249- style = LocalType .current.base,
250- textAlign = TextAlign .Center
251- )
212+ Text (
213+ text = (selectedIndex + 1 ).toString(),
214+ color = LocalColors .current.onInvertedBackgroundAccent,
215+ style = LocalType .current.base,
216+ textAlign = TextAlign .Center
217+ )
218+ }
219+ } else {
220+ // Select OFF badge
221+ Box (
222+ modifier = Modifier
223+ .align(Alignment .TopEnd )
224+ .padding(LocalDimensions .current.xxsSpacing)
225+ ) {
226+ IndicatorOff (size = LocalDimensions .current.smallRadius)
227+ }
252228 }
253229 }
254230 }
@@ -298,13 +274,11 @@ private fun Preview_MediaPickerItemCell_NotSelected() {
298274
299275 MediaPickerItemCell (
300276 media = media,
301- selected = emptyList(),
302- forcedMultiSelect = false ,
303- maxSelection = 32 ,
277+ isMultiSelect = false ,
278+ canLongPress = true ,
304279 onMediaChosen = {},
305280 onSelectionStarted = {},
306281 onSelectionChanged = {},
307- onSelectionOverflow = {},
308282 )
309283}
310284
@@ -315,13 +289,11 @@ private fun Preview_MediaPickerItemCell_Selected() {
315289
316290 MediaPickerItemCell (
317291 media = media,
318- selected = listOf (media), // selectedIndex = 0 -> shows "1"
319- forcedMultiSelect = true ,
320- maxSelection = 32 ,
292+ isMultiSelect = true ,
293+ canLongPress = true ,
321294 onMediaChosen = {},
322295 onSelectionStarted = {},
323296 onSelectionChanged = {},
324- onSelectionOverflow = {},
325297 )
326298}
327299
0 commit comments