Remove unused composables

This commit is contained in:
vfsfitvnm 2022-09-28 14:40:54 +02:00
parent a600c8b457
commit 6a69eb57e9
9 changed files with 62 additions and 375 deletions

View file

@ -1,22 +0,0 @@
package it.vfsfitvnm.vimusic.ui.components
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
fun Modifier.badge(color: Color, isDisplayed: Boolean = true, radius: Dp = 4.dp) =
if (isDisplayed) {
drawWithContent {
drawContent()
drawCircle(
color = color,
center = Offset(x = size.width, y = 0.dp.toPx()),
radius = radius.toPx()
)
}
} else {
this
}

View file

@ -1,50 +0,0 @@
package it.vfsfitvnm.vimusic.ui.components
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
@Composable
fun <T> ChipGroup(
items: List<ChipItem<T>>,
value: T,
selectedBackgroundColor: Color,
unselectedBackgroundColor: Color,
selectedTextStyle: TextStyle,
unselectedTextStyle: TextStyle,
modifier: Modifier = Modifier,
shape: Shape = RoundedCornerShape(16.dp),
onValueChanged: (T) -> Unit
) {
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.horizontalScroll(rememberScrollState())
.then(modifier)
) {
items.forEach { chipItem ->
ChunkyButton(
text = chipItem.text,
textStyle = if (chipItem.value == value) selectedTextStyle else unselectedTextStyle,
backgroundColor = if (chipItem.value == value) selectedBackgroundColor else unselectedBackgroundColor,
shape = shape,
onClick = {
onValueChanged(chipItem.value)
}
)
}
}
}
data class ChipItem<T>(
val text: String,
val value: T
)

View file

@ -1,23 +0,0 @@
package it.vfsfitvnm.vimusic.ui.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@Composable
inline fun TopAppBar(
modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = modifier
.fillMaxWidth(),
content = content
)
}

View file

@ -1,41 +0,0 @@
package it.vfsfitvnm.vimusic.ui.components.themed
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.vimusic.R
@Composable
fun LoadingOrError(
errorMessage: String? = null,
onRetry: (() -> Unit)? = null,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
loadingContent: @Composable ColumnScope.() -> Unit
) {
Box {
Column(
horizontalAlignment = horizontalAlignment,
modifier = Modifier
.alpha(if (errorMessage == null) 1f else 0f)
.shimmer(),
content = loadingContent
)
errorMessage?.let {
TextCard(
icon = R.drawable.alert_circle,
onClick = onRetry,
modifier = Modifier
.align(Alignment.Center)
) {
Title(text = onRetry?.let { "Tap to retry" } ?: "Error")
Text(text = "An error has occurred:\n$errorMessage")
}
}
}
}

View file

@ -1,113 +0,0 @@
package it.vfsfitvnm.vimusic.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.align
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
@Composable
fun TextCard(
modifier: Modifier = Modifier,
@DrawableRes icon: Int? = null,
iconColor: ColorFilter? = null,
onClick: (() -> Unit)? = null,
content: @Composable TextCardScope.() -> Unit,
) {
val (colorPalette) = LocalAppearance.current
Column(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 16.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = true),
enabled = onClick != null,
onClick = onClick ?: {}
)
.background(colorPalette.background1)
.padding(horizontal = 16.dp, vertical = 16.dp)
) {
icon?.let {
Image(
painter = painterResource(icon),
contentDescription = null,
colorFilter = iconColor ?: ColorFilter.tint(Color.Red),
modifier = Modifier
.padding(bottom = 16.dp)
.size(24.dp)
)
}
(icon?.let { IconTextCardScopeImpl } ?: TextCardScopeImpl).content()
}
}
interface TextCardScope {
@Composable
fun Title(text: String)
@Composable
fun Text(text: String)
}
private object TextCardScopeImpl : TextCardScope {
@Composable
override fun Title(text: String) {
val (_, typography) = LocalAppearance.current
BasicText(
text = text,
style = typography.xxs.semiBold,
)
}
@Composable
override fun Text(text: String) {
val (_, typography) = LocalAppearance.current
BasicText(
text = text,
style = typography.xxs.secondary.align(TextAlign.Justify),
)
}
}
private object IconTextCardScopeImpl : TextCardScope {
@Composable
override fun Title(text: String) {
val (_, typography) = LocalAppearance.current
BasicText(
text = text,
style = typography.xxs.semiBold,
modifier = Modifier
.padding(horizontal = 16.dp)
)
}
@Composable
override fun Text(text: String) {
val (_, typography) = LocalAppearance.current
BasicText(
text = text,
style = typography.xxs.secondary,
modifier = Modifier
.padding(horizontal = 16.dp)
)
}
}

View file

@ -299,7 +299,7 @@ fun AlbumOverview(
.fillMaxSize() .fillMaxSize()
) { ) {
BasicText( BasicText(
text = "An error has occurred.\nTap to retry", text = "An error has occurred.",
style = typography.s.medium.secondary.center, style = typography.s.medium.secondary.center,
modifier = Modifier modifier = Modifier
.align(Alignment.Center) .align(Alignment.Center)

View file

@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -32,7 +31,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.center import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.ColorFilter
@ -50,17 +48,12 @@ import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.models.Artist import it.vfsfitvnm.vimusic.models.Artist
import it.vfsfitvnm.vimusic.models.DetailedSong import it.vfsfitvnm.vimusic.models.DetailedSong
import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.LoadingOrError
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.screens.album.AlbumOverview
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.px import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.ui.views.SongItem import it.vfsfitvnm.vimusic.ui.views.SongItem
import it.vfsfitvnm.vimusic.utils.asMediaItem import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex import it.vfsfitvnm.vimusic.utils.forcePlayAtIndex
@ -73,7 +66,6 @@ import it.vfsfitvnm.youtubemusic.YouTube
import it.vfsfitvnm.youtubemusic.models.NavigationEndpoint import it.vfsfitvnm.youtubemusic.models.NavigationEndpoint
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -147,21 +139,7 @@ fun ArtistScreen2(browseId: String) {
.fillMaxSize() .fillMaxSize()
) { ) {
item { item {
TopAppBar(
modifier = Modifier
.height(52.dp)
) {
Image(
painter = painterResource(R.drawable.chevron_back),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable(onClick = pop)
.padding(vertical = 8.dp)
.padding(horizontal = 16.dp)
.size(24.dp)
)
}
} }
item { item {
@ -234,17 +212,17 @@ fun ArtistScreen2(browseId: String) {
) )
} }
} ?: artistResult?.exceptionOrNull()?.let { throwable -> } ?: artistResult?.exceptionOrNull()?.let { throwable ->
LoadingOrError( // LoadingOrError(
errorMessage = throwable.javaClass.canonicalName, // errorMessage = throwable.javaClass.canonicalName,
onRetry = { // onRetry = {
query { // query {
runBlocking { // runBlocking {
Database.artist(browseId).first()?.let(Database::update) // Database.artist(browseId).first()?.let(Database::update)
} // }
} // }
} // }
) // )
} ?: LoadingOrError() }
} }
item("songs") { item("songs") {
@ -367,39 +345,6 @@ fun ArtistScreen2(browseId: String) {
} }
} }
@Composable
private fun LoadingOrError(
errorMessage: String? = null,
onRetry: (() -> Unit)? = null
) {
val (colorPalette) = LocalAppearance.current
LoadingOrError(
errorMessage = errorMessage,
onRetry = onRetry,
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(
modifier = Modifier
.background(color = colorPalette.shimmer, shape = CircleShape)
.size(Dimensions.thumbnails.artist)
)
TextPlaceholder(
modifier = Modifier
.alpha(0.9f)
.padding(vertical = 8.dp, horizontal = 16.dp)
)
repeat(3) {
TextPlaceholder(
modifier = Modifier
.alpha(0.8f)
.padding(horizontal = 16.dp)
)
}
}
}
private suspend fun fetchArtist(browseId: String): Result<Artist>? { private suspend fun fetchArtist(browseId: String): Result<Artist>? {
return YouTube.artist(browseId) return YouTube.artist(browseId)

View file

@ -2,27 +2,32 @@ package it.vfsfitvnm.vimusic.ui.screens.searchresult
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.savers.ListSaver import it.vfsfitvnm.vimusic.savers.ListSaver
import it.vfsfitvnm.vimusic.savers.StringResultSaver import it.vfsfitvnm.vimusic.savers.StringResultSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.views.SearchResultLoadingOrError import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.produceSaveableRelaunchableOneShotState import it.vfsfitvnm.vimusic.utils.produceSaveableRelaunchableOneShotState
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.youtubemusic.YouTube import it.vfsfitvnm.youtubemusic.YouTube
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -37,6 +42,8 @@ inline fun <T : YouTube.Item> SearchResult(
crossinline itemContent: @Composable LazyItemScope.(T) -> Unit, crossinline itemContent: @Composable LazyItemScope.(T) -> Unit,
noinline itemShimmer: @Composable BoxScope.() -> Unit, noinline itemShimmer: @Composable BoxScope.() -> Unit,
) { ) {
val (_, typography) = LocalAppearance.current
var items by rememberSaveable(query, filter, stateSaver = stateSaver) { var items by rememberSaveable(query, filter, stateSaver = stateSaver) {
mutableStateOf(listOf()) mutableStateOf(listOf())
} }
@ -93,28 +100,54 @@ inline fun <T : YouTube.Item> SearchResult(
SideEffect(fetch) SideEffect(fetch)
} }
} }
} ?: continuationResult?.exceptionOrNull()?.let { throwable -> } ?: continuationResult?.exceptionOrNull()?.let {
item { item {
SearchResultLoadingOrError( Box(
errorMessage = throwable.javaClass.canonicalName, modifier = Modifier
onRetry = fetch, .pointerInput(Unit) {
shimmerContent = {} detectTapGestures {
) fetch()
}
}
.fillMaxSize()
) {
BasicText(
text = "An error has occurred.\nTap to retry",
style = typography.s.medium.secondary.center,
modifier = Modifier
.align(Alignment.Center)
)
}
} }
} ?: continuationResult?.let { } ?: continuationResult?.let {
if (items.isEmpty()) { if (items.isEmpty()) {
item { item {
TextCard(icon = R.drawable.sad) { Box(
Title(text = "No results found") modifier = Modifier
Text(text = "Please try a different query or category.") .pointerInput(Unit) {
detectTapGestures {
fetch()
}
}
.fillMaxSize()
) {
BasicText(
text = "No results found.\nPlease try a different query or category",
style = typography.s.medium.secondary.center,
modifier = Modifier
.align(Alignment.Center)
)
} }
} }
} }
} ?: item(key = "loading") { } ?: item(key = "loading") {
SearchResultLoadingOrError( repeat(if (items.isEmpty()) 8 else 3) { index ->
itemCount = if (items.isEmpty()) 8 else 3, Box(
shimmerContent = itemShimmer modifier = Modifier
) .alpha(1f - index * 0.125f),
content = itemShimmer
)
}
} }
} }
} }

View file

@ -7,7 +7,6 @@ import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@ -22,7 +21,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@ -30,7 +28,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage import coil.compose.AsyncImage
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.themed.LoadingOrError
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.Dimensions import it.vfsfitvnm.vimusic.ui.styling.Dimensions
@ -458,42 +455,3 @@ fun ArtistItemShimmer(
} }
} }
} }
@Composable
fun SearchResultLoadingOrError(
itemCount: Int = 0,
errorMessage: String? = null,
onRetry: (() -> Unit)? = null,
shimmerContent: @Composable BoxScope.() -> Unit,
) {
LoadingOrError(
errorMessage = errorMessage,
onRetry = onRetry,
horizontalAlignment = Alignment.CenterHorizontally
) {
repeat(itemCount) { index ->
Box(
modifier = Modifier
.alpha(1f - index * 0.125f),
content = shimmerContent
)
// if (isLoadingArtists) {
// SmallArtistItemShimmer(
// thumbnailSizeDp = Dimensions.thumbnails.song,
// modifier = Modifier
// .alpha(1f - index * 0.125f)
// .fillMaxWidth()
// .padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
// )
// } else {
// SmallSongItemShimmer(
// thumbnailSizeDp = Dimensions.thumbnails.song,
// modifier = Modifier
// .alpha(1f - index * 0.125f)
// .fillMaxWidth()
// .padding(vertical = Dimensions.itemsVerticalPadding, horizontal = 16.dp)
// )
// }
}
}
}