|
|
|
@ -8,6 +8,7 @@ import android.annotation.SuppressLint
|
|
|
|
|
import android.graphics.Bitmap
|
|
|
|
|
import androidx.compose.foundation.BorderStroke
|
|
|
|
|
import androidx.compose.foundation.Image
|
|
|
|
|
import androidx.compose.foundation.background
|
|
|
|
|
import androidx.compose.foundation.border
|
|
|
|
|
import androidx.compose.foundation.clickable
|
|
|
|
|
import androidx.compose.foundation.layout.Box
|
|
|
|
@ -17,37 +18,28 @@ import androidx.compose.foundation.layout.Spacer
|
|
|
|
|
import androidx.compose.foundation.layout.aspectRatio
|
|
|
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
|
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
|
|
|
import androidx.compose.foundation.layout.heightIn
|
|
|
|
|
import androidx.compose.foundation.layout.padding
|
|
|
|
|
import androidx.compose.foundation.layout.size
|
|
|
|
|
import androidx.compose.foundation.rememberScrollState
|
|
|
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
|
|
|
import androidx.compose.foundation.verticalScroll
|
|
|
|
|
import androidx.compose.material.Scaffold
|
|
|
|
|
import androidx.compose.material.Snackbar
|
|
|
|
|
import androidx.compose.material.SnackbarDuration
|
|
|
|
|
import androidx.compose.material.SnackbarHost
|
|
|
|
|
import androidx.compose.material.CircularProgressIndicator
|
|
|
|
|
import androidx.compose.material.Surface
|
|
|
|
|
import androidx.compose.material.Text
|
|
|
|
|
import androidx.compose.material.rememberScaffoldState
|
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
|
import androidx.compose.runtime.mutableStateOf
|
|
|
|
|
import androidx.compose.runtime.remember
|
|
|
|
|
import androidx.compose.runtime.rememberCoroutineScope
|
|
|
|
|
import androidx.compose.runtime.setValue
|
|
|
|
|
import androidx.compose.ui.Alignment
|
|
|
|
|
import androidx.compose.ui.Modifier
|
|
|
|
|
import androidx.compose.ui.graphics.asImageBitmap
|
|
|
|
|
import androidx.compose.ui.layout.ContentScale
|
|
|
|
|
import androidx.compose.ui.platform.LocalConfiguration
|
|
|
|
|
import androidx.compose.ui.res.stringResource
|
|
|
|
|
import androidx.compose.ui.text.style.TextAlign
|
|
|
|
|
import androidx.compose.ui.text.style.TextOverflow
|
|
|
|
|
import androidx.compose.ui.tooling.preview.Preview
|
|
|
|
|
import androidx.compose.ui.unit.dp
|
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
|
import org.mozilla.fenix.R
|
|
|
|
|
import org.mozilla.fenix.compose.button.TextButton
|
|
|
|
|
import org.mozilla.fenix.theme.FirefoxTheme
|
|
|
|
|
import org.mozilla.fenix.theme.Theme
|
|
|
|
|
import org.mozilla.fenix.wallpapers.Wallpaper
|
|
|
|
@ -58,10 +50,9 @@ import org.mozilla.fenix.wallpapers.Wallpaper
|
|
|
|
|
*
|
|
|
|
|
* @param wallpapers Wallpapers to add to grid.
|
|
|
|
|
* @param selectedWallpaper The currently selected wallpaper.
|
|
|
|
|
* @param defaultWallpaper The default wallpaper
|
|
|
|
|
* @param defaultWallpaper The default wallpaper.
|
|
|
|
|
* @param loadWallpaperResource Callback to handle loading a wallpaper bitmap. Only optional in the default case.
|
|
|
|
|
* @param onSelectWallpaper Callback for when a new wallpaper is selected.
|
|
|
|
|
* @param onViewWallpaper Callback for when the view action is clicked from snackbar.
|
|
|
|
|
*/
|
|
|
|
|
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
|
|
|
|
|
@Composable
|
|
|
|
@ -72,76 +63,27 @@ fun WallpaperSettings(
|
|
|
|
|
loadWallpaperResource: suspend (Wallpaper) -> Bitmap?,
|
|
|
|
|
selectedWallpaper: Wallpaper,
|
|
|
|
|
onSelectWallpaper: (Wallpaper) -> Unit,
|
|
|
|
|
onViewWallpaper: () -> Unit,
|
|
|
|
|
) {
|
|
|
|
|
val coroutineScope = rememberCoroutineScope()
|
|
|
|
|
val scaffoldState = rememberScaffoldState()
|
|
|
|
|
|
|
|
|
|
Scaffold(
|
|
|
|
|
backgroundColor = FirefoxTheme.colors.layer1,
|
|
|
|
|
scaffoldState = scaffoldState,
|
|
|
|
|
snackbarHost = { hostState ->
|
|
|
|
|
SnackbarHost(hostState = hostState) {
|
|
|
|
|
WallpaperSnackbar(onViewWallpaper)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Column(
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.verticalScroll(rememberScrollState())
|
|
|
|
|
.background(color = FirefoxTheme.colors.layer1),
|
|
|
|
|
) {
|
|
|
|
|
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
|
|
|
|
WallpaperThumbnails(
|
|
|
|
|
wallpapers = wallpapers,
|
|
|
|
|
defaultWallpaper = defaultWallpaper,
|
|
|
|
|
selectedWallpaper = selectedWallpaper,
|
|
|
|
|
loadWallpaperResource = loadWallpaperResource,
|
|
|
|
|
onSelectWallpaper = { updatedWallpaper ->
|
|
|
|
|
coroutineScope.launch {
|
|
|
|
|
scaffoldState.snackbarHostState.showSnackbar(
|
|
|
|
|
message = "", // overwritten by WallpaperSnackbar
|
|
|
|
|
duration = SnackbarDuration.Short,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
onSelectWallpaper(updatedWallpaper)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
WallpaperThumbnails(
|
|
|
|
|
wallpapers = wallpapers,
|
|
|
|
|
defaultWallpaper = defaultWallpaper,
|
|
|
|
|
loadWallpaperResource = loadWallpaperResource,
|
|
|
|
|
selectedWallpaper = selectedWallpaper,
|
|
|
|
|
onSelectWallpaper = { updatedWallpaper -> onSelectWallpaper(updatedWallpaper) },
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
|
private fun WallpaperSnackbar(
|
|
|
|
|
onViewWallpaper: () -> Unit,
|
|
|
|
|
) {
|
|
|
|
|
Snackbar(
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.padding(8.dp)
|
|
|
|
|
.heightIn(min = 48.dp),
|
|
|
|
|
backgroundColor = FirefoxTheme.colors.actionPrimary,
|
|
|
|
|
content = {
|
|
|
|
|
Text(
|
|
|
|
|
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp),
|
|
|
|
|
text = stringResource(R.string.wallpaper_updated_snackbar_message),
|
|
|
|
|
textAlign = TextAlign.Start,
|
|
|
|
|
color = FirefoxTheme.colors.textOnColorPrimary,
|
|
|
|
|
overflow = TextOverflow.Ellipsis,
|
|
|
|
|
maxLines = 2,
|
|
|
|
|
style = FirefoxTheme.typography.headline7,
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
action = {
|
|
|
|
|
TextButton(
|
|
|
|
|
text = stringResource(R.string.wallpaper_updated_snackbar_action),
|
|
|
|
|
onClick = onViewWallpaper,
|
|
|
|
|
modifier = Modifier.padding(all = 8.dp),
|
|
|
|
|
textColor = FirefoxTheme.colors.textOnColorPrimary,
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A grid of selectable wallpaper thumbnails.
|
|
|
|
|
*
|
|
|
|
|
* @param wallpapers Wallpapers to add to grid.
|
|
|
|
|
* @param defaultWallpaper The default wallpaper
|
|
|
|
|
* @param defaultWallpaper The default wallpaper.
|
|
|
|
|
* @param loadWallpaperResource Callback to handle loading a wallpaper bitmap. Only optional in the default case.
|
|
|
|
|
* @param selectedWallpaper The currently selected wallpaper.
|
|
|
|
|
* @param numColumns The number of columns that will occupy the grid.
|
|
|
|
@ -173,16 +115,18 @@ fun WallpaperThumbnails(
|
|
|
|
|
for (columnIndex in 0 until numColumns) {
|
|
|
|
|
val itemIndex = rowIndex * numColumns + columnIndex
|
|
|
|
|
if (itemIndex < wallpapers.size) {
|
|
|
|
|
val wallpaper = wallpapers[itemIndex]
|
|
|
|
|
Box(
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.weight(1f, fill = true)
|
|
|
|
|
.padding(4.dp),
|
|
|
|
|
) {
|
|
|
|
|
WallpaperThumbnailItem(
|
|
|
|
|
wallpaper = wallpapers[itemIndex],
|
|
|
|
|
wallpaper = wallpaper,
|
|
|
|
|
defaultWallpaper = defaultWallpaper,
|
|
|
|
|
loadWallpaperResource = loadWallpaperResource,
|
|
|
|
|
isSelected = selectedWallpaper == wallpapers[itemIndex],
|
|
|
|
|
isSelected = selectedWallpaper.name == wallpaper.name,
|
|
|
|
|
isLoading = wallpaper.assetsFileState == Wallpaper.ImageFileState.Downloading,
|
|
|
|
|
onSelect = onSelectWallpaper,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
@ -199,9 +143,14 @@ fun WallpaperThumbnails(
|
|
|
|
|
* A single wallpaper thumbnail.
|
|
|
|
|
*
|
|
|
|
|
* @param wallpaper The wallpaper to display.
|
|
|
|
|
* @param defaultWallpaper The default wallpaper.
|
|
|
|
|
* @param loadWallpaperResource Callback to handle loading a wallpaper bitmap.
|
|
|
|
|
* @param isSelected Whether the wallpaper is currently selected.
|
|
|
|
|
* @param isLoading Whether the wallpaper is currently downloading.
|
|
|
|
|
* @param aspectRatio The ratio of height to width of the thumbnail.
|
|
|
|
|
* @param onSelect Action to take when this wallpaper is selected.
|
|
|
|
|
* @param loadingOpacity Opacity of the currently downloading wallpaper.
|
|
|
|
|
* @param onSelect Action to take when a new wallpaper is selected.
|
|
|
|
|
*/
|
|
|
|
|
@Composable
|
|
|
|
|
@Suppress("LongParameterList")
|
|
|
|
@ -210,7 +159,9 @@ private fun WallpaperThumbnailItem(
|
|
|
|
|
defaultWallpaper: Wallpaper,
|
|
|
|
|
loadWallpaperResource: suspend (Wallpaper) -> Bitmap?,
|
|
|
|
|
isSelected: Boolean,
|
|
|
|
|
isLoading: Boolean,
|
|
|
|
|
aspectRatio: Float = 1.1f,
|
|
|
|
|
loadingOpacity: Float = 0.5f,
|
|
|
|
|
onSelect: (Wallpaper) -> Unit,
|
|
|
|
|
) {
|
|
|
|
|
var bitmap: Bitmap? by remember { mutableStateOf(null) }
|
|
|
|
@ -220,7 +171,12 @@ private fun WallpaperThumbnailItem(
|
|
|
|
|
val thumbnailShape = RoundedCornerShape(8.dp)
|
|
|
|
|
val border = if (isSelected) {
|
|
|
|
|
Modifier.border(
|
|
|
|
|
BorderStroke(width = 2.dp, color = FirefoxTheme.colors.borderAccent),
|
|
|
|
|
BorderStroke(width = 3.dp, color = FirefoxTheme.colors.borderAccent),
|
|
|
|
|
thumbnailShape,
|
|
|
|
|
)
|
|
|
|
|
} else if (wallpaper.name == Wallpaper.defaultName) {
|
|
|
|
|
Modifier.border(
|
|
|
|
|
BorderStroke(width = 1.dp, color = FirefoxTheme.colors.borderPrimary),
|
|
|
|
|
thumbnailShape,
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
@ -249,8 +205,20 @@ private fun WallpaperThumbnailItem(
|
|
|
|
|
wallpaper.name,
|
|
|
|
|
),
|
|
|
|
|
modifier = Modifier.fillMaxSize(),
|
|
|
|
|
alpha = if (isLoading) loadingOpacity else 1.0f,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
Box(
|
|
|
|
|
contentAlignment = Alignment.Center,
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.size(24.dp),
|
|
|
|
|
) {
|
|
|
|
|
CircularProgressIndicator(
|
|
|
|
|
color = FirefoxTheme.colors.borderAccent,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -264,17 +232,6 @@ private fun WallpaperThumbnailsPreview() {
|
|
|
|
|
wallpapers = listOf(Wallpaper.Default),
|
|
|
|
|
selectedWallpaper = Wallpaper.Default,
|
|
|
|
|
onSelectWallpaper = {},
|
|
|
|
|
onViewWallpaper = {},
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Preview
|
|
|
|
|
@Composable
|
|
|
|
|
private fun WallpaperSnackbarPreview() {
|
|
|
|
|
FirefoxTheme(theme = Theme.getTheme()) {
|
|
|
|
|
WallpaperSnackbar(
|
|
|
|
|
onViewWallpaper = {},
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|