Require opt-in to screenshot loading on mobile data

This commit is contained in:
Torsten Grote
2025-12-16 11:49:12 -03:00
parent dd73012a9b
commit de2c77a647
4 changed files with 59 additions and 3 deletions

View File

@@ -199,7 +199,7 @@ fun AppDetails(
}
// Screenshots
if (item.phoneScreenshots.isNotEmpty()) {
Screenshots(item.phoneScreenshots)
Screenshots(item.networkState.isMetered, item.phoneScreenshots)
}
// Donate card
if (item.showDonate) ElevatedCard(

View File

@@ -1,6 +1,8 @@
package org.fdroid.ui.details
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -12,10 +14,13 @@ import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Error
import androidx.compose.material.icons.filled.Image
import androidx.compose.material3.ElevatedButton
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.ModalBottomSheetProperties
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.carousel.HorizontalUncontainedCarousel
import androidx.compose.material3.carousel.rememberCarouselState
import androidx.compose.material3.rememberModalBottomSheetState
@@ -24,18 +29,60 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment.Companion.Center
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.hideFromAccessibility
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.fdroid.R
import org.fdroid.ui.FDroidContent
import org.fdroid.ui.utils.AsyncShimmerImage
import org.fdroid.ui.utils.testApp
@Composable
fun Screenshots(isMetered: Boolean, phoneScreenshots: List<Any>) {
var showEvenWhenMetered by remember { mutableStateOf(false) }
if (isMetered && !showEvenWhenMetered) Box(
contentAlignment = Center,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
.padding(horizontal = 16.dp)
.clickable { showEvenWhenMetered = true }
) {
Image(
painterResource(R.drawable.screenshots_placeholder),
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
.clip(MaterialTheme.shapes.large)
.semantics { hideFromAccessibility() }
)
ElevatedButton(
onClick = { showEvenWhenMetered = true },
modifier = Modifier.padding(horizontal = 16.dp)
) {
Text(
text = stringResource(R.string.screenshots_metered),
textAlign = TextAlign.Center,
)
}
} else {
Screenshots(phoneScreenshots)
}
}
@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun Screenshots(phoneScreenshots: List<Any>) {
private fun Screenshots(phoneScreenshots: List<Any>) {
val carouselState = rememberCarouselState { phoneScreenshots.size }
var showScreenshot by remember { mutableStateOf<Int?>(null) }
val screenshotIndex = showScreenshot
@@ -91,6 +138,14 @@ fun Screenshots(phoneScreenshots: List<Any>) {
@Composable
private fun Preview() {
FDroidContent {
Screenshots(testApp.phoneScreenshots)
Screenshots(false, testApp.phoneScreenshots)
}
}
@Preview(widthDp = 300)
@Composable
private fun PreviewMetered() {
FDroidContent {
Screenshots(true, testApp.phoneScreenshots)
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

@@ -46,6 +46,7 @@
<string name="dialog_metered_text">You are currently on a metered internet connection. Do you want to continue downloading %1$s?</string>
<string name="dialog_metered_text_no_size">You are currently on a metered internet connection. Do you want to continue downloading?</string>
<string name="dialog_metered_button">Download</string>
<string name="screenshots_metered">Tap to load screenshots via mobile data</string>
<string name="category_group_productivity">Productivity</string>
<string name="category_group_tools">Tools</string>