2022-07-18 08:17:40 +06:00
|
|
|
package eu.kanade.presentation.components
|
|
|
|
|
2022-10-30 15:50:09 -04:00
|
|
|
import androidx.annotation.StringRes
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.animation.AnimatedVisibility
|
|
|
|
import androidx.compose.animation.expandVertically
|
|
|
|
import androidx.compose.animation.shrinkVertically
|
2022-07-18 08:17:40 +06:00
|
|
|
import androidx.compose.foundation.background
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
|
|
import androidx.compose.foundation.layout.Row
|
|
|
|
import androidx.compose.foundation.layout.Spacer
|
2022-12-09 23:20:13 +07:00
|
|
|
import androidx.compose.foundation.layout.WindowInsets
|
2022-07-18 08:17:40 +06:00
|
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
|
|
import androidx.compose.foundation.layout.padding
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.foundation.layout.requiredSize
|
|
|
|
import androidx.compose.foundation.layout.statusBars
|
|
|
|
import androidx.compose.foundation.layout.width
|
2022-12-09 23:20:13 +07:00
|
|
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.material3.CircularProgressIndicator
|
2022-07-18 08:17:40 +06:00
|
|
|
import androidx.compose.material3.MaterialTheme
|
|
|
|
import androidx.compose.material3.Text
|
|
|
|
import androidx.compose.runtime.Composable
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
import androidx.compose.runtime.mutableStateOf
|
|
|
|
import androidx.compose.runtime.remember
|
|
|
|
import androidx.compose.runtime.setValue
|
2022-07-18 08:17:40 +06:00
|
|
|
import androidx.compose.ui.Modifier
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.ui.layout.SubcomposeLayout
|
|
|
|
import androidx.compose.ui.platform.LocalDensity
|
2022-07-18 08:17:40 +06:00
|
|
|
import androidx.compose.ui.res.stringResource
|
|
|
|
import androidx.compose.ui.text.style.TextAlign
|
|
|
|
import androidx.compose.ui.unit.dp
|
2022-12-17 10:18:17 +07:00
|
|
|
import androidx.compose.ui.util.fastForEach
|
|
|
|
import androidx.compose.ui.util.fastMap
|
|
|
|
import androidx.compose.ui.util.fastMaxBy
|
2022-07-18 08:17:40 +06:00
|
|
|
import eu.kanade.tachiyomi.R
|
|
|
|
|
2022-12-14 22:54:34 -05:00
|
|
|
val DownloadedOnlyBannerBackgroundColor
|
|
|
|
@Composable get() = MaterialTheme.colorScheme.tertiary
|
|
|
|
val IncognitoModeBannerBackgroundColor
|
|
|
|
@Composable get() = MaterialTheme.colorScheme.primary
|
2022-12-17 10:18:17 +07:00
|
|
|
val IndexingBannerBackgroundColor
|
|
|
|
@Composable get() = MaterialTheme.colorScheme.secondary
|
2022-12-14 22:54:34 -05:00
|
|
|
|
2022-10-30 15:50:09 -04:00
|
|
|
@Composable
|
|
|
|
fun WarningBanner(
|
|
|
|
@StringRes textRes: Int,
|
|
|
|
modifier: Modifier = Modifier,
|
|
|
|
) {
|
|
|
|
Text(
|
|
|
|
text = stringResource(textRes),
|
|
|
|
modifier = modifier
|
|
|
|
.fillMaxWidth()
|
|
|
|
.background(MaterialTheme.colorScheme.error)
|
|
|
|
.padding(16.dp),
|
|
|
|
color = MaterialTheme.colorScheme.onError,
|
|
|
|
style = MaterialTheme.typography.bodyMedium,
|
|
|
|
textAlign = TextAlign.Center,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-18 08:17:40 +06:00
|
|
|
@Composable
|
2022-10-08 21:24:50 +07:00
|
|
|
fun AppStateBanners(
|
2022-09-18 16:08:50 -04:00
|
|
|
downloadedOnlyMode: Boolean,
|
|
|
|
incognitoMode: Boolean,
|
2022-12-17 10:18:17 +07:00
|
|
|
indexing: Boolean,
|
2022-10-08 21:24:50 +07:00
|
|
|
modifier: Modifier = Modifier,
|
2022-09-18 16:08:50 -04:00
|
|
|
) {
|
2022-12-17 10:18:17 +07:00
|
|
|
val density = LocalDensity.current
|
|
|
|
val mainInsets = WindowInsets.statusBars
|
|
|
|
val mainInsetsTop = mainInsets.getTop(density)
|
|
|
|
SubcomposeLayout(modifier = modifier) { constraints ->
|
|
|
|
val indexingPlaceable = subcompose(0) {
|
|
|
|
AnimatedVisibility(
|
|
|
|
visible = indexing,
|
|
|
|
enter = expandVertically(),
|
|
|
|
exit = shrinkVertically(),
|
|
|
|
) {
|
|
|
|
IndexingDownloadBanner(
|
|
|
|
modifier = Modifier.windowInsetsPadding(mainInsets),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}.fastMap { it.measure(constraints) }
|
|
|
|
val indexingHeight = indexingPlaceable.fastMaxBy { it.height }?.height ?: 0
|
|
|
|
|
|
|
|
val downloadedOnlyPlaceable = subcompose(1) {
|
|
|
|
AnimatedVisibility(
|
|
|
|
visible = downloadedOnlyMode,
|
|
|
|
enter = expandVertically(),
|
|
|
|
exit = shrinkVertically(),
|
|
|
|
) {
|
|
|
|
val top = (mainInsetsTop - indexingHeight).coerceAtLeast(0)
|
|
|
|
DownloadedOnlyModeBanner(
|
|
|
|
modifier = Modifier.windowInsetsPadding(WindowInsets(top = top)),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}.fastMap { it.measure(constraints) }
|
|
|
|
val downloadedOnlyHeight = downloadedOnlyPlaceable.fastMaxBy { it.height }?.height ?: 0
|
|
|
|
|
|
|
|
val incognitoPlaceable = subcompose(2) {
|
|
|
|
AnimatedVisibility(
|
|
|
|
visible = incognitoMode,
|
|
|
|
enter = expandVertically(),
|
|
|
|
exit = shrinkVertically(),
|
|
|
|
) {
|
|
|
|
val top = (mainInsetsTop - indexingHeight - downloadedOnlyHeight).coerceAtLeast(0)
|
|
|
|
IncognitoModeBanner(
|
|
|
|
modifier = Modifier.windowInsetsPadding(WindowInsets(top = top)),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}.fastMap { it.measure(constraints) }
|
|
|
|
val incognitoHeight = incognitoPlaceable.fastMaxBy { it.height }?.height ?: 0
|
|
|
|
|
|
|
|
layout(constraints.maxWidth, indexingHeight + downloadedOnlyHeight + incognitoHeight) {
|
|
|
|
indexingPlaceable.fastForEach {
|
|
|
|
it.place(0, 0)
|
|
|
|
}
|
|
|
|
downloadedOnlyPlaceable.fastForEach {
|
|
|
|
it.place(0, indexingHeight)
|
|
|
|
}
|
|
|
|
incognitoPlaceable.fastForEach {
|
|
|
|
it.place(0, indexingHeight + downloadedOnlyHeight)
|
|
|
|
}
|
2022-10-08 21:24:50 +07:00
|
|
|
}
|
2022-09-18 16:08:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
2022-12-09 23:20:13 +07:00
|
|
|
private fun DownloadedOnlyModeBanner(modifier: Modifier = Modifier) {
|
2022-07-18 08:17:40 +06:00
|
|
|
Text(
|
|
|
|
text = stringResource(R.string.label_downloaded_only),
|
|
|
|
modifier = Modifier
|
2022-12-14 22:54:34 -05:00
|
|
|
.background(DownloadedOnlyBannerBackgroundColor)
|
2022-07-18 08:17:40 +06:00
|
|
|
.fillMaxWidth()
|
2022-12-09 23:20:13 +07:00
|
|
|
.padding(4.dp)
|
|
|
|
.then(modifier),
|
2022-07-18 08:17:40 +06:00
|
|
|
color = MaterialTheme.colorScheme.onTertiary,
|
|
|
|
textAlign = TextAlign.Center,
|
|
|
|
style = MaterialTheme.typography.labelMedium,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
2022-12-09 23:20:13 +07:00
|
|
|
private fun IncognitoModeBanner(modifier: Modifier = Modifier) {
|
2022-07-18 08:17:40 +06:00
|
|
|
Text(
|
|
|
|
text = stringResource(R.string.pref_incognito_mode),
|
|
|
|
modifier = Modifier
|
2022-12-14 22:54:34 -05:00
|
|
|
.background(IncognitoModeBannerBackgroundColor)
|
2022-07-18 08:17:40 +06:00
|
|
|
.fillMaxWidth()
|
2022-12-09 23:20:13 +07:00
|
|
|
.padding(4.dp)
|
|
|
|
.then(modifier),
|
2022-07-18 08:17:40 +06:00
|
|
|
color = MaterialTheme.colorScheme.onPrimary,
|
|
|
|
textAlign = TextAlign.Center,
|
|
|
|
style = MaterialTheme.typography.labelMedium,
|
|
|
|
)
|
|
|
|
}
|
2022-12-17 10:18:17 +07:00
|
|
|
|
|
|
|
@Composable
|
|
|
|
private fun IndexingDownloadBanner(modifier: Modifier = Modifier) {
|
|
|
|
val density = LocalDensity.current
|
|
|
|
Row(
|
|
|
|
modifier = Modifier
|
|
|
|
.background(color = IndexingBannerBackgroundColor)
|
|
|
|
.fillMaxWidth()
|
|
|
|
.padding(8.dp)
|
|
|
|
.then(modifier),
|
|
|
|
horizontalArrangement = Arrangement.Center,
|
|
|
|
) {
|
|
|
|
var textHeight by remember { mutableStateOf(0.dp) }
|
|
|
|
CircularProgressIndicator(
|
|
|
|
modifier = Modifier.requiredSize(textHeight),
|
|
|
|
color = MaterialTheme.colorScheme.onSecondary,
|
|
|
|
strokeWidth = textHeight / 8,
|
|
|
|
)
|
|
|
|
Spacer(modifier = Modifier.width(8.dp))
|
|
|
|
Text(
|
|
|
|
text = stringResource(R.string.download_notifier_cache_renewal),
|
|
|
|
color = MaterialTheme.colorScheme.onSecondary,
|
|
|
|
textAlign = TextAlign.Center,
|
|
|
|
style = MaterialTheme.typography.labelMedium,
|
|
|
|
onTextLayout = {
|
|
|
|
with(density) {
|
|
|
|
textHeight = it.size.height.toDp()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|