Make LocalIndication provide a bounded ripple

This commit is contained in:
vfsfitvnm 2022-10-04 14:10:41 +02:00
parent d2ce356d10
commit 185c5ec726
30 changed files with 255 additions and 523 deletions

View file

@ -323,7 +323,7 @@ class MainActivity : ComponentActivity() {
CompositionLocalProvider(
LocalAppearance provides appearance,
LocalIndication provides rememberRipple(bounded = false),
LocalIndication provides rememberRipple(bounded = true),
LocalRippleTheme provides rippleTheme,
LocalShimmerTheme provides shimmerTheme,
LocalPlayerServiceBinder provides binder,

View file

@ -10,14 +10,12 @@ import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.DraggableState
import androidx.compose.foundation.gestures.detectVerticalDragGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
@ -120,11 +118,7 @@ fun BottomSheet(
.graphicsLayer {
alpha = 1f - (state.progress * 16).coerceAtMost(1f)
}
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = true),
onClick = state::expandSoft
)
.clickable(onClick = state::expandSoft)
.fillMaxWidth()
.height(state.collapsedBound),
content = collapsedContent

View file

@ -4,7 +4,6 @@ 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.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -15,9 +14,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -51,12 +48,7 @@ fun ChunkyButton(
modifier = modifier
.clip(shape)
.background(backgroundColor)
.clickable(
indication = rememberRipple(bounded = true, color = rippleColor),
interactionSource = remember { MutableInteractionSource() },
enabled = isEnabled,
onClick = onClick
)
.clickable(enabled = isEnabled, onClick = onClick)
.padding(horizontal = 24.dp, vertical = 16.dp)
) {
icon?.let { icon ->

View file

@ -20,9 +20,7 @@ fun ShimmerHost(content: @Composable ColumnScope.() -> Unit) {
.drawWithContent {
drawContent()
drawRect(
brush = Brush.verticalGradient(
listOf(Color.Black, Color.Transparent)
),
brush = Brush.verticalGradient(listOf(Color.Black, Color.Transparent)),
blendMode = BlendMode.DstIn
)
},

View file

@ -7,7 +7,6 @@ import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -25,7 +24,6 @@ import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@ -290,8 +288,6 @@ inline fun <T> ValueSelectorDialog(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = {
onDismiss()
onValueSelected(value)
@ -346,11 +342,7 @@ inline fun <T> ValueSelectorDialog(
modifier = Modifier
.padding(horizontal = 24.dp)
.clip(RoundedCornerShape(36.dp))
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = onDismiss
)
.clickable(onClick = onDismiss)
.padding(horizontal = 24.dp, vertical = 16.dp)
.align(Alignment.End)
)

View file

@ -0,0 +1,62 @@
package it.vfsfitvnm.vimusic.ui.components.themed
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
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.unit.dp
@Composable
fun HeaderIconButton(
onClick: () -> Unit,
@DrawableRes icon: Int,
color: Color,
modifier: Modifier = Modifier,
enabled: Boolean = true
) {
Image(
painter = painterResource(icon),
contentDescription = null,
colorFilter = ColorFilter.tint(color),
modifier = modifier
.clickable(
indication = rememberRipple(bounded = false),
interactionSource = remember { MutableInteractionSource() },
enabled = enabled,
onClick = onClick
)
.padding(all = 4.dp)
.size(18.dp)
)
}
@Composable
fun IconButton(
onClick: () -> Unit,
@DrawableRes icon: Int,
color: Color,
modifier: Modifier = Modifier,
enabled: Boolean = true
) {
Image(
painter = painterResource(icon),
contentDescription = null,
colorFilter = ColorFilter.tint(color),
modifier = modifier
.clickable(
indication = rememberRipple(bounded = false),
interactionSource = remember { MutableInteractionSource() },
enabled = enabled,
onClick = onClick
)
)
}

View file

@ -4,7 +4,6 @@ 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.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -17,9 +16,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@ -65,12 +62,7 @@ fun MenuEntry(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
enabled = isEnabled,
onClick = onClick
)
.clickable(enabled = isEnabled, onClick = onClick)
.fillMaxWidth()
.alpha(if (isEnabled) 1f else 0.4f)
.padding(horizontal = 24.dp, vertical = 16.dp)

View file

@ -6,7 +6,6 @@ import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
@ -19,10 +18,8 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -123,11 +120,7 @@ fun NavigationRail(
val contentModifier = Modifier
.clip(RoundedCornerShape(24.dp))
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onTabIndexChanged(index) }
)
.clickable(onClick = { onTabIndexChanged(index) })
if (isLandscape) {
Column(

View file

@ -2,6 +2,7 @@ package it.vfsfitvnm.vimusic.ui.screens
import android.annotation.SuppressLint
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import it.vfsfitvnm.route.Route0
import it.vfsfitvnm.route.Route1
@ -24,6 +25,7 @@ val viewPlaylistsRoute = Route0("createPlaylistRoute")
@SuppressLint("ComposableNaming")
@Suppress("NOTHING_TO_INLINE")
@ExperimentalAnimationApi
@ExperimentalFoundationApi
@Composable
inline fun RouteHandlerScope.globalRoutes() {
albumRoute { browseId ->

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
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.BoxWithConstraints
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Spacer
@ -14,11 +13,9 @@ import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
@ -44,6 +41,8 @@ import it.vfsfitvnm.vimusic.savers.nullableSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
import it.vfsfitvnm.vimusic.ui.items.AlbumItem
import it.vfsfitvnm.vimusic.ui.items.AlbumItemPlaceholder
import it.vfsfitvnm.vimusic.ui.screens.albumRoute
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
import it.vfsfitvnm.vimusic.ui.screens.searchresult.ItemsPage
@ -51,8 +50,6 @@ import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.styling.shimmer
import it.vfsfitvnm.vimusic.ui.items.AlbumItem
import it.vfsfitvnm.vimusic.ui.items.AlbumItemPlaceholder
import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.produceSaveableState
import it.vfsfitvnm.vimusic.utils.thumbnail
@ -63,7 +60,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.withContext
@OptIn(ExperimentalFoundationApi::class)
@ExperimentalFoundationApi
@ExperimentalAnimationApi
@Composable
fun AlbumScreen(browseId: String) {
@ -271,11 +268,7 @@ fun AlbumScreen(browseId: String) {
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { albumRoute(album.key) }
)
.clickable { albumRoute(album.key) }
)
},
itemPlaceholderContent = {

View file

@ -4,7 +4,6 @@ import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
@ -13,10 +12,8 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
@ -31,10 +28,10 @@ import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
import it.vfsfitvnm.vimusic.ui.components.themed.SecondaryTextButton
import it.vfsfitvnm.vimusic.ui.components.themed.ShimmerHost
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.items.SongItem
import it.vfsfitvnm.vimusic.ui.items.SongItemPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.asMediaItem
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.color
@ -58,8 +55,6 @@ fun AlbumSongs(
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val songs by produceSaveableState(
initialValue = emptyList(),
stateSaver = DetailedSongListSaver
@ -120,8 +115,6 @@ fun AlbumSongs(
},
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)

View file

@ -4,17 +4,14 @@ import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
@ -53,8 +50,6 @@ fun ArtistLocalSongs(
val (colorPalette) = LocalAppearance.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val songs by produceSaveableState(
initialValue = null,
stateSaver = nullableSaver(DetailedSongListSaver)
@ -105,8 +100,6 @@ fun ArtistLocalSongs(
thumbnailSizePx = songThumbnailSizePx,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)

View file

@ -5,7 +5,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -19,9 +18,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@ -64,8 +61,6 @@ fun ArtistOverview(
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val songThumbnailSizeDp = Dimensions.thumbnails.song
val songThumbnailSizePx = songThumbnailSizeDp.px
val albumThumbnailSizeDp = 108.dp
@ -116,11 +111,7 @@ fun ArtistOverview(
text = "View all",
style = typography.xs.secondary,
modifier = sectionTextModifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = onViewAllSongsClick
),
.clickable(onClick = onViewAllSongsClick),
)
}
}
@ -132,8 +123,6 @@ fun ArtistOverview(
thumbnailSizePx = songThumbnailSizePx,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
@ -170,11 +159,7 @@ fun ArtistOverview(
text = "View all",
style = typography.xs.secondary,
modifier = sectionTextModifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = onViewAllAlbumsClick
),
.clickable(onClick = onViewAllAlbumsClick),
)
}
}
@ -193,11 +178,7 @@ fun ArtistOverview(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onAlbumClick(album.key) }
)
.clickable(onClick = { onAlbumClick(album.key) })
)
}
}
@ -221,11 +202,7 @@ fun ArtistOverview(
text = "View all",
style = typography.xs.secondary,
modifier = sectionTextModifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = onViewAllSinglesClick
),
.clickable(onClick = onViewAllSinglesClick),
)
}
}
@ -244,11 +221,7 @@ fun ArtistOverview(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onAlbumClick(album.key) }
)
.clickable(onClick = { onAlbumClick(album.key) })
)
}
}

View file

@ -4,11 +4,9 @@ import android.content.Intent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Spacer
@ -17,10 +15,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -260,7 +256,7 @@ fun ArtistScreen(browseId: String) {
val thumbnailSizeDp = Dimensions.thumbnails.song
val thumbnailSizePx = thumbnailSizeDp.px
val rippleIndication = rememberRipple(bounded = true)
ItemsPage(
stateSaver = InnertubeSongsPageSaver,
@ -297,8 +293,6 @@ fun ArtistScreen(browseId: String) {
thumbnailSizePx = thumbnailSizePx,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
@ -357,11 +351,7 @@ fun ArtistScreen(browseId: String) {
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { albumRoute(album.info?.endpoint?.browseId) }
)
.clickable(onClick = { albumRoute(album.key) })
)
},
itemPlaceholderContent = {
@ -409,11 +399,7 @@ fun ArtistScreen(browseId: String) {
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { albumRoute(album.info?.endpoint?.browseId) }
)
.clickable(onClick = { albumRoute(album.key) })
)
},
itemPlaceholderContent = {

View file

@ -4,16 +4,13 @@ import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
@ -49,8 +46,6 @@ fun BuiltInPlaylistSongs(builtInPlaylist: BuiltInPlaylist) {
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val songs by produceSaveableState(
initialValue = emptyList(),
stateSaver = DetailedSongListSaver
@ -118,8 +113,6 @@ fun BuiltInPlaylistSongs(builtInPlaylist: BuiltInPlaylist) {
thumbnailSizePx = thumbnailSize,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
when (builtInPlaylist) {

View file

@ -1,31 +1,22 @@
package it.vfsfitvnm.vimusic.ui.screens.home
import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
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.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
@ -35,6 +26,7 @@ import it.vfsfitvnm.vimusic.enums.SortOrder
import it.vfsfitvnm.vimusic.models.Album
import it.vfsfitvnm.vimusic.savers.AlbumListSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
import it.vfsfitvnm.vimusic.ui.items.AlbumItem
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -76,8 +68,6 @@ fun HomeAlbums(
animationSpec = tween(durationMillis = 400, easing = LinearEasing)
)
val rippleIndication = rememberRipple(bounded = true)
LazyColumn(
contentPadding = LocalPlayerAwarePaddingValues.current,
modifier = Modifier
@ -89,35 +79,22 @@ fun HomeAlbums(
contentType = 0
) {
Header(title = "Albums") {
@Composable
fun Item(
@DrawableRes iconId: Int,
targetSortBy: AlbumSortBy
) {
Image(
painter = painterResource(iconId),
contentDescription = null,
colorFilter = ColorFilter.tint(if (sortBy == targetSortBy) colorPalette.text else colorPalette.textDisabled),
modifier = Modifier
.clickable { sortBy = targetSortBy }
.padding(all = 4.dp)
.size(18.dp)
)
}
Item(
iconId = R.drawable.calendar,
targetSortBy = AlbumSortBy.Year
HeaderIconButton(
icon = R.drawable.calendar,
color = if (sortBy == AlbumSortBy.Year) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = AlbumSortBy.Year }
)
Item(
iconId = R.drawable.text,
targetSortBy = AlbumSortBy.Title
HeaderIconButton(
icon = R.drawable.text,
color = if (sortBy == AlbumSortBy.Title) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = AlbumSortBy.Title }
)
Item(
iconId = R.drawable.time,
targetSortBy = AlbumSortBy.DateAdded
HeaderIconButton(
icon = R.drawable.time,
color = if (sortBy == AlbumSortBy.DateAdded) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = AlbumSortBy.DateAdded }
)
Spacer(
@ -125,14 +102,11 @@ fun HomeAlbums(
.width(2.dp)
)
Image(
painter = painterResource(R.drawable.arrow_up),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
HeaderIconButton(
icon = R.drawable.arrow_up,
color = colorPalette.text,
onClick = { sortOrder = !sortOrder },
modifier = Modifier
.clickable { sortOrder = !sortOrder }
.padding(all = 4.dp)
.size(18.dp)
.graphicsLayer { rotationZ = sortOrderIconRotation }
)
}
@ -147,11 +121,7 @@ fun HomeAlbums(
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { onAlbumClick(album) }
)
.clickable(onClick = { onAlbumClick(album) })
.animateItemPlacement()
)
}

View file

@ -1,35 +1,26 @@
package it.vfsfitvnm.vimusic.ui.screens.home
import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
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.Arrangement
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
@ -39,6 +30,7 @@ import it.vfsfitvnm.vimusic.enums.SortOrder
import it.vfsfitvnm.vimusic.models.Artist
import it.vfsfitvnm.vimusic.savers.ArtistListSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
import it.vfsfitvnm.vimusic.ui.items.ArtistItem
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ -80,8 +72,6 @@ fun HomeArtistList(
animationSpec = tween(durationMillis = 400, easing = LinearEasing)
)
val rippleIndication = rememberRipple(bounded = true)
LazyVerticalGrid(
columns = GridCells.Adaptive(Dimensions.thumbnails.song * 2 + Dimensions.itemsVerticalPadding * 2),
contentPadding = LocalPlayerAwarePaddingValues.current,
@ -100,30 +90,16 @@ fun HomeArtistList(
span = { GridItemSpan(maxLineSpan) }
) {
Header(title = "Artists") {
@Composable
fun Item(
@DrawableRes iconId: Int,
targetSortBy: ArtistSortBy
) {
Image(
painter = painterResource(iconId),
contentDescription = null,
colorFilter = ColorFilter.tint(if (sortBy == targetSortBy) colorPalette.text else colorPalette.textDisabled),
modifier = Modifier
.clickable { sortBy = targetSortBy }
.padding(all = 4.dp)
.size(18.dp)
)
}
Item(
iconId = R.drawable.text,
targetSortBy = ArtistSortBy.Name
HeaderIconButton(
icon = R.drawable.text,
color = if (sortBy == ArtistSortBy.Name) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = ArtistSortBy.Name }
)
Item(
iconId = R.drawable.time,
targetSortBy = ArtistSortBy.DateAdded
HeaderIconButton(
icon = R.drawable.time,
color = if (sortBy == ArtistSortBy.DateAdded) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = ArtistSortBy.DateAdded }
)
Spacer(
@ -131,14 +107,11 @@ fun HomeArtistList(
.width(2.dp)
)
Image(
painter = painterResource(R.drawable.arrow_up),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
HeaderIconButton(
icon = R.drawable.arrow_up,
color = colorPalette.text,
onClick = { sortOrder = !sortOrder },
modifier = Modifier
.clickable { sortOrder = !sortOrder }
.padding(all = 4.dp)
.size(18.dp)
.graphicsLayer { rotationZ = sortOrderIconRotation }
)
}
@ -151,12 +124,7 @@ fun HomeArtistList(
thumbnailSizeDp = thumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { onArtistClick(artist) }
)
// .requiredWidth(thumbnailSizeDp)
.clickable(onClick = { onArtistClick(artist) })
.animateItemPlacement()
)
}

View file

@ -1,36 +1,27 @@
package it.vfsfitvnm.vimusic.ui.screens.home
import androidx.annotation.DrawableRes
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
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.Arrangement
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
@ -42,6 +33,7 @@ import it.vfsfitvnm.vimusic.models.Playlist
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.savers.PlaylistPreviewListSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
import it.vfsfitvnm.vimusic.ui.components.themed.SecondaryTextButton
import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog
import it.vfsfitvnm.vimusic.ui.items.PlaylistItem
@ -117,22 +109,6 @@ fun HomePlaylists(
) {
item(key = "header", contentType = 0, span = { GridItemSpan(maxLineSpan) }) {
Header(title = "Playlists") {
@Composable
fun Item(
@DrawableRes iconId: Int,
targetSortBy: PlaylistSortBy
) {
Image(
painter = painterResource(iconId),
contentDescription = null,
colorFilter = ColorFilter.tint(if (sortBy == targetSortBy) colorPalette.text else colorPalette.textDisabled),
modifier = Modifier
.clickable { sortBy = targetSortBy }
.padding(all = 4.dp)
.size(18.dp)
)
}
SecondaryTextButton(
text = "New playlist",
onClick = { isCreatingANewPlaylist = true }
@ -143,19 +119,22 @@ fun HomePlaylists(
.weight(1f)
)
Item(
iconId = R.drawable.medical,
targetSortBy = PlaylistSortBy.SongCount
HeaderIconButton(
icon = R.drawable.medical,
color = if (sortBy == PlaylistSortBy.SongCount) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = PlaylistSortBy.SongCount }
)
Item(
iconId = R.drawable.text,
targetSortBy = PlaylistSortBy.Name
HeaderIconButton(
icon = R.drawable.text,
color = if (sortBy == PlaylistSortBy.Name) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = PlaylistSortBy.Name }
)
Item(
iconId = R.drawable.time,
targetSortBy = PlaylistSortBy.DateAdded
HeaderIconButton(
icon = R.drawable.time,
color = if (sortBy == PlaylistSortBy.DateAdded) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = PlaylistSortBy.DateAdded }
)
Spacer(
@ -163,14 +142,11 @@ fun HomePlaylists(
.width(2.dp)
)
Image(
painter = painterResource(R.drawable.arrow_up),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
HeaderIconButton(
icon = R.drawable.arrow_up,
color = colorPalette.text,
onClick = { sortOrder = !sortOrder },
modifier = Modifier
.clickable { sortOrder = !sortOrder }
.padding(all = 4.dp)
.size(18.dp)
.graphicsLayer { rotationZ = sortOrderIconRotation }
)
}
@ -185,11 +161,7 @@ fun HomePlaylists(
thumbnailSizeDp = thumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onBuiltInPlaylist(BuiltInPlaylist.Favorites) }
)
.clickable(onClick = { onBuiltInPlaylist(BuiltInPlaylist.Favorites) })
.animateItemPlacement()
)
}
@ -203,11 +175,7 @@ fun HomePlaylists(
thumbnailSizeDp = thumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onBuiltInPlaylist(BuiltInPlaylist.Offline) }
)
.clickable(onClick = { onBuiltInPlaylist(BuiltInPlaylist.Offline) })
.animateItemPlacement()
)
}
@ -219,11 +187,7 @@ fun HomePlaylists(
thumbnailSizePx = thumbnailSizePx,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onPlaylistClick(playlistPreview.playlist) }
)
.clickable(onClick = { onPlaylistClick(playlistPreview.playlist) })
.animateItemPlacement()
)
}

View file

@ -1,40 +1,31 @@
package it.vfsfitvnm.vimusic.ui.screens.home
import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.Database
@ -47,6 +38,7 @@ import it.vfsfitvnm.vimusic.models.DetailedSong
import it.vfsfitvnm.vimusic.savers.DetailedSongListSaver
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
import it.vfsfitvnm.vimusic.ui.components.themed.InHistoryMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.ScrollToTop
import it.vfsfitvnm.vimusic.ui.items.SongItem
@ -75,8 +67,6 @@ fun HomeSongs() {
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val thumbnailSizeDp = Dimensions.thumbnails.song
val thumbnailSizePx = thumbnailSizeDp.px
@ -115,35 +105,22 @@ fun HomeSongs() {
contentType = 0
) {
Header(title = "Songs") {
@Composable
fun Item(
@DrawableRes iconId: Int,
targetSortBy: SongSortBy
) {
Image(
painter = painterResource(iconId),
contentDescription = null,
colorFilter = ColorFilter.tint(if (sortBy == targetSortBy) colorPalette.text else colorPalette.textDisabled),
modifier = Modifier
.clickable { sortBy = targetSortBy }
.padding(all = 4.dp)
.size(18.dp)
)
}
Item(
iconId = R.drawable.trending,
targetSortBy = SongSortBy.PlayTime
HeaderIconButton(
icon = R.drawable.trending,
color = if (sortBy == SongSortBy.PlayTime) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = SongSortBy.PlayTime }
)
Item(
iconId = R.drawable.text,
targetSortBy = SongSortBy.Title
HeaderIconButton(
icon = R.drawable.text,
color = if (sortBy == SongSortBy.Title) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = SongSortBy.Title }
)
Item(
iconId = R.drawable.time,
targetSortBy = SongSortBy.DateAdded
HeaderIconButton(
icon = R.drawable.time,
color = if (sortBy == SongSortBy.DateAdded) colorPalette.text else colorPalette.textDisabled,
onClick = { sortBy = SongSortBy.DateAdded }
)
Spacer(
@ -151,14 +128,11 @@ fun HomeSongs() {
.width(2.dp)
)
Image(
painter = painterResource(R.drawable.arrow_up),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
HeaderIconButton(
icon = R.drawable.arrow_up,
color = colorPalette.text,
onClick = { sortOrder = !sortOrder },
modifier = Modifier
.clickable { sortOrder = !sortOrder }
.padding(all = 4.dp)
.size(18.dp)
.graphicsLayer { rotationZ = sortOrderIconRotation }
)
}
@ -192,8 +166,6 @@ fun HomeSongs() {
}) else null,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
InHistoryMediaItemMenu(song = song)

View file

@ -5,7 +5,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -22,19 +21,11 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerAwarePaddingValues
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
@ -43,6 +34,7 @@ import it.vfsfitvnm.vimusic.savers.InnertubeRelatedPageSaver
import it.vfsfitvnm.vimusic.savers.nullableSaver
import it.vfsfitvnm.vimusic.savers.resultSaver
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.ShimmerHost
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
@ -85,8 +77,6 @@ fun QuickPicks(
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val trending by produceSaveableState(
initialValue = null,
stateSaver = nullableSaver(DetailedSongSaver),
@ -146,8 +136,6 @@ fun QuickPicks(
thumbnailSizeDp = songThumbnailSizeDp,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
@ -178,8 +166,6 @@ fun QuickPicks(
thumbnailSizeDp = songThumbnailSizeDp,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
@ -217,11 +203,7 @@ fun QuickPicks(
thumbnailSizeDp = albumThumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onAlbumClick(album.key) }
)
.clickable(onClick = { onAlbumClick(album.key) })
)
}
}
@ -243,11 +225,7 @@ fun QuickPicks(
thumbnailSizeDp = artistThumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onArtistClick(artist.key) }
)
.clickable(onClick = { onArtistClick(artist.key) })
)
}
}
@ -271,11 +249,7 @@ fun QuickPicks(
thumbnailSizeDp = playlistThumbnailSizeDp,
alternative = true,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onPlaylistClick(playlist.key) }
)
.clickable(onClick = { onPlaylistClick(playlist.key) })
)
}
}
@ -287,20 +261,7 @@ fun QuickPicks(
.align(Alignment.CenterHorizontally)
.padding(all = 16.dp)
)
} ?: Column(
modifier = Modifier
.shimmer()
.graphicsLayer(alpha = 0.99f)
.drawWithContent {
drawContent()
drawRect(
brush = Brush.verticalGradient(
listOf(Color.Black, Color.Transparent)
),
blendMode = BlendMode.DstIn
)
}
) {
} ?: ShimmerHost {
repeat(4) {
SongItemPlaceholder(
thumbnailSizeDp = songThumbnailSizeDp,

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
@ -14,11 +13,9 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@ -76,8 +73,6 @@ fun LocalPlaylistSongs(
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val playlistWithSongs by produceSaveableState(
initialValue = null,
stateSaver = nullableSaver(PlaylistWithSongsSaver)
@ -252,8 +247,6 @@ fun LocalPlaylistSongs(
},
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
InPlaylistMediaItemMenu(

View file

@ -41,6 +41,7 @@ import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.models.Song
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.ui.components.SeekBar
import it.vfsfitvnm.vimusic.ui.components.themed.IconButton
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.favoritesIcon
import it.vfsfitvnm.vimusic.utils.bold
@ -150,7 +151,8 @@ fun Controls(
.fillMaxWidth()
) {
BasicText(
text = DateUtils.formatElapsedTime((scrubbingPosition ?: position) / 1000).removePrefix("0"),
text = DateUtils.formatElapsedTime((scrubbingPosition ?: position) / 1000)
.removePrefix("0"),
style = typography.xxs.semiBold,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
@ -176,31 +178,35 @@ fun Controls(
modifier = Modifier
.fillMaxWidth()
) {
Image(
painter = painterResource(if (likedAt == null) R.drawable.heart_outline else R.drawable.heart),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.favoritesIcon),
modifier = Modifier
.clickable {
val currentMediaItem = binder.player.currentMediaItem
query {
if (Database.like(mediaId, if (likedAt == null) System.currentTimeMillis() else null) == 0) {
currentMediaItem?.takeIf { it.mediaId == mediaId }?.let {
IconButton(
icon = if (likedAt == null) R.drawable.heart_outline else R.drawable.heart,
color = colorPalette.favoritesIcon,
onClick = {
val currentMediaItem = binder.player.currentMediaItem
query {
if (Database.like(
mediaId,
if (likedAt == null) System.currentTimeMillis() else null
) == 0
) {
currentMediaItem
?.takeIf { it.mediaId == mediaId }
?.let {
Database.insert(currentMediaItem, Song::toggleLike)
}
}
}
}
},
modifier = Modifier
.weight(1f)
.size(24.dp)
)
Image(
painter = painterResource(R.drawable.play_skip_back),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
IconButton(
icon = R.drawable.play_skip_back,
color = colorPalette.text,
onClick = binder.player::forceSeekToPrevious,
modifier = Modifier
.clickable(onClick = binder.player::forceSeekToPrevious)
.weight(1f)
.size(24.dp)
)
@ -241,33 +247,29 @@ fun Controls(
.width(8.dp)
)
Image(
painter = painterResource(R.drawable.play_skip_forward),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
IconButton(
icon = R.drawable.play_skip_forward,
color = colorPalette.text,
onClick = binder.player::forceSeekToNext,
modifier = Modifier
.clickable(onClick = binder.player::forceSeekToNext)
.weight(1f)
.size(24.dp)
)
Image(
painter = painterResource(R.drawable.infinite),
contentDescription = null,
colorFilter = ColorFilter.tint(
if (repeatMode == Player.REPEAT_MODE_ONE) {
colorPalette.text
} else {
colorPalette.textDisabled
IconButton(
icon = R.drawable.infinite,
color = if (repeatMode == Player.REPEAT_MODE_ONE) {
colorPalette.text
} else {
colorPalette.textDisabled
},
onClick = {
binder.player.repeatMode = when (binder.player.repeatMode) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
else -> Player.REPEAT_MODE_ONE
}
),
},
modifier = Modifier
.clickable {
binder.player.repeatMode = when (binder.player.repeatMode) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
else -> Player.REPEAT_MODE_ONE
}
}
.weight(1f)
.size(24.dp)
)

View file

@ -8,7 +8,6 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
@ -28,7 +27,6 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@ -110,8 +108,6 @@ fun PlayerBottomSheet(
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val thumbnailSizeDp = Dimensions.thumbnails.song
val thumbnailSizePx = thumbnailSizeDp.px
@ -209,8 +205,6 @@ fun PlayerBottomSheet(
},
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
QueuedMediaItemMenu(
@ -259,11 +253,7 @@ fun PlayerBottomSheet(
Box(
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = layoutState::collapseSoft
)
.clickable(onClick = layoutState::collapseSoft)
.height(64.dp + bottomPadding)
.background(colorPalette.background2)
.fillMaxWidth()

View file

@ -7,7 +7,6 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -15,7 +14,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState
@ -192,8 +190,6 @@ fun StatsForNerds(
style = typography.xxs.medium.color(colorPalette.onOverlay),
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = {
query {
runBlocking(Dispatchers.IO) {

View file

@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic.ui.screens.playlist
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import it.vfsfitvnm.route.RouteHandler
@ -8,6 +9,7 @@ import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
@ExperimentalFoundationApi
@ExperimentalAnimationApi
@Composable
fun PlaylistScreen(browseId: String) {

View file

@ -7,7 +7,6 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
@ -22,10 +21,8 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.autoSaver
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -84,8 +81,6 @@ fun PlaylistSongList(
val context = LocalContext.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val playlistPageResult by produceSaveableState(
initialValue = null,
stateSaver = resultSaver(InnertubePlaylistOrAlbumPageSaver),
@ -215,8 +210,6 @@ fun PlaylistSongList(
thumbnailSizeDp = songThumbnailSizeDp,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)

View file

@ -3,16 +3,13 @@ package it.vfsfitvnm.vimusic.ui.screens.search
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.input.ImeAction
@ -52,8 +49,6 @@ fun LocalSongSearch(
val binder = LocalPlayerServiceBinder.current
val menuState = LocalMenuState.current
val rippleIndication = rememberRipple(bounded = true)
val items by produceSaveableState(
initialValue = emptyList(),
stateSaver = DetailedSongListSaver,
@ -113,8 +108,6 @@ fun LocalSongSearch(
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
InHistoryMediaItemMenu(song = song)

View file

@ -1,5 +1,6 @@
package it.vfsfitvnm.vimusic.ui.screens.search
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
@ -102,10 +103,10 @@ fun OnlineSearch(
if (isPlaylistUrl) textFieldValue.text.toUri().getQueryParameter("list") else null
}
val rippleIndication = rememberRipple(bounded = false)
val timeIconPainter = painterResource(R.drawable.time)
val closeIconPainter = painterResource(R.drawable.close)
val arrowForwardIconPainter = painterResource(R.drawable.arrow_forward)
val rippleIndication = rememberRipple(bounded = true)
val focusRequester = remember {
FocusRequester()
@ -174,11 +175,7 @@ fun OnlineSearch(
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { onSearch(searchQuery.query) }
)
.clickable(onClick = { onSearch(searchQuery.query) })
.fillMaxWidth()
.padding(all = 16.dp)
) {
@ -200,38 +197,44 @@ fun OnlineSearch(
.weight(1f)
)
Spacer(
Image(
painter = closeIconPainter,
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.textDisabled),
modifier = Modifier
.clickable {
query {
Database.delete(searchQuery)
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = {
query {
Database.delete(searchQuery)
}
}
}
)
.padding(horizontal = 8.dp)
.size(20.dp)
.paint(
painter = closeIconPainter,
colorFilter = ColorFilter.tint(colorPalette.textDisabled)
)
)
Spacer(
Image(
painter = arrowForwardIconPainter,
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.textDisabled),
modifier = Modifier
.clickable {
onTextFieldValueChanged(
TextFieldValue(
text = searchQuery.query,
selection = TextRange(searchQuery.query.length)
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = {
onTextFieldValueChanged(
TextFieldValue(
text = searchQuery.query,
selection = TextRange(searchQuery.query.length)
)
)
)
}
}
)
.rotate(225f)
.padding(horizontal = 8.dp)
.size(20.dp)
.paint(
painter = arrowForwardIconPainter,
colorFilter = ColorFilter.tint(colorPalette.textDisabled)
)
.size(22.dp)
)
}
}
@ -241,11 +244,7 @@ fun OnlineSearch(
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { onSearch(suggestion) }
)
.clickable(onClick = { onSearch(suggestion) })
.fillMaxWidth()
.padding(all = 16.dp)
) {
@ -263,23 +262,26 @@ fun OnlineSearch(
.weight(1f)
)
Spacer(
Image(
painter = arrowForwardIconPainter,
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.textDisabled),
modifier = Modifier
.clickable {
onTextFieldValueChanged(
TextFieldValue(
text = suggestion,
selection = TextRange(suggestion.length)
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = {
onTextFieldValueChanged(
TextFieldValue(
text = suggestion,
selection = TextRange(suggestion.length)
)
)
)
}
}
)
.rotate(225f)
.padding(horizontal = 8.dp)
.size(22.dp)
.paint(
painter = arrowForwardIconPainter,
colorFilter = ColorFilter.tint(colorPalette.textDisabled)
)
)
}
}

View file

@ -5,10 +5,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
@ -77,7 +74,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
val emptyItemsText = "No results found. Please try a different query or category"
val rippleIndication = rememberRipple(bounded = true)
Scaffold(
topIconButtonId = R.drawable.chevron_back,
@ -125,8 +122,6 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = song.asMediaItem)
@ -173,11 +168,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { albumRoute(album.info?.endpoint?.browseId) }
)
.clickable(onClick = { albumRoute(album.key) })
)
},
@ -214,11 +205,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { artistRoute(artist.info?.endpoint?.browseId) }
)
.clickable(onClick = { artistRoute(artist.key) })
)
},
itemPlaceholderContent = {
@ -257,8 +244,6 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
thumbnailHeightDp = thumbnailHeightDp,
modifier = Modifier
.combinedClickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onLongClick = {
menuState.display {
NonQueuedMediaItemMenu(mediaItem = video.asMediaItem)
@ -314,11 +299,7 @@ fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
thumbnailSizePx = thumbnailSizePx,
thumbnailSizeDp = thumbnailSizeDp,
modifier = Modifier
.clickable(
indication = rippleIndication,
interactionSource = remember { MutableInteractionSource() },
onClick = { playlistRoute(playlist.info?.endpoint?.browseId) }
)
.clickable(onClick = { playlistRoute(playlist.key) })
)
},
itemPlaceholderContent = {

View file

@ -2,10 +2,8 @@ package it.vfsfitvnm.vimusic.ui.screens.settings
import androidx.compose.animation.*
import androidx.compose.foundation.*
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicText
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
@ -24,6 +22,7 @@ import it.vfsfitvnm.vimusic.ui.screens.settings.*
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.*
@ExperimentalFoundationApi
@ExperimentalAnimationApi
@Composable
fun SettingsScreen() {
@ -139,12 +138,7 @@ fun SwitchSettingEntry(
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = { onCheckedChange(!isChecked) },
enabled = isEnabled
)
.clickable(enabled = isEnabled) { onCheckedChange(!isChecked) }
.alpha(if (isEnabled) 1f else 0.5f)
.padding(start = 16.dp)
.padding(all = 16.dp)
@ -182,12 +176,7 @@ fun SettingsEntry(
Column(
modifier = modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = onClick,
enabled = isEnabled
)
.clickable(enabled = isEnabled, onClick = onClick)
.alpha(if (isEnabled) 1f else 0.5f)
.padding(start = 16.dp)
.padding(all = 16.dp)