Update: Break Header into a TopBar and an AppInfo block

This commit is contained in:
machiav3lli 2022-05-29 03:27:10 +02:00
parent 9b725c32a9
commit b235265219

View File

@ -1,97 +1,130 @@
package com.looker.droidify.ui.compose.pages.app_detail.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.looker.droidify.R
import com.looker.droidify.ui.compose.components.InstallButton
import com.looker.droidify.ui.compose.utils.*
import com.looker.droidify.entity.Cancelable
import com.looker.droidify.entity.Install
import com.looker.droidify.entity.PackageState
import com.looker.droidify.ui.compose.components.MainActionButton
import com.looker.droidify.ui.compose.components.SecondaryActionButton
import com.looker.droidify.ui.compose.utils.NetworkImage
import com.looker.droidify.utility.extension.text.formatSize
@Composable
fun Header(
fun AppInfoHeader(
modifier: Modifier = Modifier,
icon: String?,
appName: String,
packageName: String,
versionCode: String,
appSize: String,
appDev: String
appDev: String,
state: PackageState? = Install,
secondaryAction: PackageState? = null,
onSource: () -> Unit = { },
onSourceLong: () -> Unit = { },
onAction: () -> Unit = { },
onSecondaryAction: () -> Unit = { }
) {
Surface(
modifier = modifier.fillMaxWidth(),
shape = MaterialTheme.shapes.large
) {
Column(
modifier = Modifier.padding(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
HeaderTitle(
modifier = Modifier.fillMaxWidth(),
icon = icon,
appName = appName,
packageName = packageName
)
HeaderExtra(
versionCode = versionCode,
appSize = appSize,
appDev = appDev
appDev = appDev,
onSource = onSource,
onSourceLong = onSourceLong
)
var buttonState by remember { mutableStateOf<ButtonStates>(Connecting) }
AnimatedVisibility(visible = buttonState is Cancelable) {
DownloadProgress(modifier = Modifier.padding(horizontal = 12.dp), totalSize = 69420)
}
InstallButton(buttonState = buttonState) {
buttonState = when (it) {
Connecting -> Download
Download -> Downloading
Downloading -> Install
Install -> Installing
Installing -> Launch
Launch -> Connecting
}
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
SecondaryActionButton(packageState = secondaryAction, onClick = {
onSecondaryAction()
})
MainActionButton(
modifier = Modifier.weight(1f),
packageState = state ?: Install,
onClick = {
onAction()
})
}
}
}
}
@Composable
fun HeaderTitle(
fun TopBarHeader(
modifier: Modifier = Modifier,
icon: String? = null,
appName: String,
packageName: String,
state: PackageState? = Install,
actions: @Composable () -> Unit = {}
) {
Row(
modifier = modifier.padding(16.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
Surface(
modifier = modifier
.padding(start = 8.dp, top = 8.dp, end = 8.dp, bottom = 0.dp)
.fillMaxWidth(),
shape = MaterialTheme.shapes.large
) {
NetworkImage(
modifier = Modifier.size(56.dp),
data = icon
)
Spacer(modifier = Modifier.width(16.dp))
Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.SpaceAround
) {
Text(text = appName, style = MaterialTheme.typography.titleLarge)
Text(text = packageName, style = MaterialTheme.typography.bodyMedium)
Column {
Row(
modifier = modifier.padding(16.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
NetworkImage(
modifier = Modifier.size(56.dp),
data = icon
)
Spacer(modifier = Modifier.width(16.dp))
Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.SpaceAround
) {
Text(text = appName, style = MaterialTheme.typography.titleLarge)
Text(text = packageName, style = MaterialTheme.typography.bodyMedium)
}
Box { actions() }
}
AnimatedVisibility(visible = state is Cancelable) {
DownloadProgress(
modifier = Modifier.padding(horizontal = 12.dp),
totalSize = 69420,
isIndeterminate = if (state is Cancelable) state.isIndeterminate else true
)
}
}
Box { actions() }
}
}
@ -100,12 +133,15 @@ fun HeaderExtra(
modifier: Modifier = Modifier,
versionCode: String,
appSize: String,
appDev: String
appDev: String,
onSource: () -> Unit,
onSourceLong: () -> Unit
) {
Row(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight()
.wrapContentHeight(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
HeaderExtrasCard(
modifier = Modifier.weight(1f),
@ -120,32 +156,36 @@ fun HeaderExtra(
HeaderExtrasCard(
modifier = Modifier.weight(1f),
title = stringResource(id = R.string.source_code),
text = appDev
text = appDev,
onClick = onSource,
onLongClick = onSourceLong
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HeaderExtrasCard(
modifier: Modifier = Modifier,
extra: @Composable () -> Unit = {},
title: String,
text: String,
onClick: () -> Unit = {}
onClick: () -> Unit = {},
onLongClick: () -> Unit = {}
) {
Surface(
modifier = modifier
.clip(RoundedCornerShape(50))
.clickable { onClick() }
.padding(16.dp)
.clip(MaterialTheme.shapes.medium)
.combinedClickable(onClick = onClick, onLongClick = onLongClick)
.padding(12.dp)
) {
Column(
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally
) {
extra()
Text(text = title, style = MaterialTheme.typography.labelLarge)
Text(text = text, style = MaterialTheme.typography.bodyMedium)
Text(text = title, style = MaterialTheme.typography.labelLarge, maxLines = 1)
Text(text = text, style = MaterialTheme.typography.bodyMedium, maxLines = 1)
}
}
}
@ -154,21 +194,31 @@ fun HeaderExtrasCard(
fun DownloadProgress(
modifier: Modifier = Modifier,
downloading: Float = 0f,
totalSize: Long
totalSize: Long,
isIndeterminate: Boolean
) {
Column(
modifier = modifier.fillMaxWidth(),
horizontalAlignment = Alignment.Start
) {
Text(
text = totalSize.times(downloading).toLong().formatSize() + "/" + totalSize.formatSize()
)
Spacer(modifier = Modifier.height(8.dp))
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.clip(Shapes.Full),
progress = downloading
)
if (isIndeterminate) {
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.clip(Shapes.Full),
)
} else {
Text(
text = totalSize.times(downloading).toLong()
.formatSize() + "/" + totalSize.formatSize()
)
Spacer(modifier = Modifier.height(8.dp))
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.clip(Shapes.Full),
progress = downloading
)
}
}
}