Add dynamic theme (#159)

This commit is contained in:
vfsfitvnm
2022-08-10 13:09:35 +02:00
parent a26eebd806
commit 2716319339
42 changed files with 458 additions and 399 deletions

View File

@@ -47,8 +47,8 @@ import it.vfsfitvnm.vimusic.ui.components.MusicBars
import it.vfsfitvnm.vimusic.ui.components.themed.QueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.screens.SmallSongItemShimmer
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LightColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.onOverlay
import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.rememberMediaItemIndex
@@ -91,6 +91,7 @@ fun CurrentPlaylistView(
.nestedScroll(remember {
layoutState.nestedScrollConnection(lazyListState.firstVisibleItemIndex == 0 && lazyListState.firstVisibleItemScrollOffset == 0)
})
.background(colorPalette.background1)
) {
items(
items = windows,
@@ -137,7 +138,7 @@ fun CurrentPlaylistView(
) {
if (shouldBePlaying) {
MusicBars(
color = LightColorPalette.background,
color = colorPalette.onOverlay,
modifier = Modifier
.height(24.dp)
)
@@ -145,7 +146,7 @@ fun CurrentPlaylistView(
Image(
painter = painterResource(R.drawable.play),
contentDescription = null,
colorFilter = ColorFilter.tint(LightColorPalette.background),
colorFilter = ColorFilter.tint(colorPalette.onOverlay),
modifier = Modifier
.size(24.dp)
)
@@ -164,7 +165,6 @@ fun CurrentPlaylistView(
.size(20.dp)
)
},
backgroundColor = colorPalette.background,
modifier = Modifier
// .animateItemPlacement()
.verticalDragAfterLongPressToReorder(
@@ -211,7 +211,7 @@ fun CurrentPlaylistView(
onClick = layoutState::collapseSoft
)
.height(64.dp)
.background(colorPalette.elevatedBackground)
.background(colorPalette.background2)
.fillMaxWidth()
.padding(horizontal = 8.dp)
.align(Alignment.BottomCenter)

View File

@@ -7,6 +7,8 @@ import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
@@ -18,6 +20,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
@ExperimentalAnimationApi
@Composable
fun PlayerBottomSheet(
backgroundColorProvider: () -> Color,
layoutState: BottomSheetState,
onGlobalRouteEmitted: () -> Unit,
modifier: Modifier = Modifier,
@@ -31,7 +34,7 @@ fun PlayerBottomSheet(
collapsedContent = {
Box(
modifier = Modifier
.background(colorPalette.background)
.drawBehind { drawRect(backgroundColorProvider()) }
.fillMaxSize()
) {
Image(
@@ -40,7 +43,6 @@ fun PlayerBottomSheet(
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.padding(all = 8.dp)
.size(18.dp)
)
@@ -52,7 +54,7 @@ fun PlayerBottomSheet(
layoutState = layoutState,
onGlobalRouteEmitted = onGlobalRouteEmitted,
modifier = Modifier
.background(colorPalette.background)
.background(colorPalette.background0)
.fillMaxSize()
)
}

View File

@@ -29,6 +29,7 @@ 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.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.ColorFilter
@@ -49,6 +50,7 @@ import it.vfsfitvnm.vimusic.ui.components.rememberBottomSheetState
import it.vfsfitvnm.vimusic.ui.components.themed.BaseMediaItemMenu
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.collapsedPlayerProgressBar
import it.vfsfitvnm.vimusic.ui.styling.px
import it.vfsfitvnm.vimusic.ui.views.player.Controls
import it.vfsfitvnm.vimusic.ui.views.player.Thumbnail
@@ -70,7 +72,7 @@ fun PlayerView(
) {
val menuState = LocalMenuState.current
val (colorPalette, typography) = LocalAppearance.current
val (colorPalette, typography, thumbnailShape) = LocalAppearance.current
val binder = LocalPlayerServiceBinder.current
val context = LocalContext.current
val configuration = LocalConfiguration.current
@@ -96,30 +98,32 @@ fun PlayerView(
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.background(colorPalette.elevatedBackground)
.background(colorPalette.background1)
.fillMaxSize()
.drawBehind {
val progress =
positionAndDuration.first.toFloat() / positionAndDuration.second.absoluteValue
val offset = Dimensions.thumbnails.player.songPreview.toPx()
drawLine(
color = colorPalette.text,
start = Offset(x = offset, y = 1.dp.toPx()),
end = Offset(
x = ((size.width - offset) * progress) + offset,
y = 1.dp.toPx()
),
color = colorPalette.collapsedPlayerProgressBar,
start = Offset(x = 0f, y = 1.dp.toPx()),
end = Offset(x = size.width * progress, y = 1.dp.toPx()),
strokeWidth = 2.dp.toPx()
)
}
) {
Spacer(
modifier = Modifier
.width(2.dp)
)
AsyncImage(
model = mediaItem.mediaMetadata.artworkUri.thumbnail(Dimensions.thumbnails.player.songPreview.px),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier
.size(Dimensions.thumbnails.player.songPreview)
.clip(thumbnailShape)
.size(48.dp)
)
Column(
@@ -206,7 +210,7 @@ fun PlayerView(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(bottom = 64.dp)
.background(colorPalette.background)
.background(colorPalette.background1)
.padding(top = 16.dp)
) {
Box(
@@ -242,7 +246,7 @@ fun PlayerView(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.padding(bottom = 64.dp)
.background(colorPalette.background)
.background(colorPalette.background1)
.padding(top = 32.dp)
) {
Box(
@@ -355,6 +359,7 @@ fun PlayerView(
)
}
},
backgroundColorProvider = { colorPalette.background2 },
modifier = Modifier
.align(Alignment.BottomCenter)
)

View File

@@ -91,7 +91,7 @@ fun PlaylistPreviewItem(
contentScale = ContentScale.Crop,
modifier = Modifier
.clip(thumbnailShape)
.border(width = 1.dp, color = colorPalette.lightBackground)
.border(width = 1.dp, color = colorPalette.background1)
.align(alignment)
.size(thumbnailSize)
)
@@ -143,7 +143,7 @@ fun PlaylistItem(
Box(
modifier = modifier
.clip(thumbnailShape)
.background(colorPalette.lightBackground)
.background(colorPalette.background1)
.size(thumbnailSize * 2)
) {
Box(

View File

@@ -2,7 +2,6 @@ package it.vfsfitvnm.vimusic.ui.views
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.Arrangement
@@ -22,7 +21,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextOverflow
@@ -48,7 +46,6 @@ fun SongItem(
onClick: () -> Unit,
menuContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
backgroundColor: Color? = null,
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
trailingContent: (@Composable () -> Unit)? = null
) {
@@ -64,7 +61,6 @@ fun SongItem(
onClick = onClick,
onThumbnailContent = onThumbnailContent,
trailingContent = trailingContent,
backgroundColor = backgroundColor,
modifier = modifier,
)
}
@@ -78,7 +74,6 @@ fun SongItem(
onClick: () -> Unit,
menuContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
backgroundColor: Color? = null,
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
trailingContent: (@Composable () -> Unit)? = null
) {
@@ -90,7 +85,6 @@ fun SongItem(
menuContent = menuContent,
onClick = onClick,
onThumbnailContent = onThumbnailContent,
backgroundColor = backgroundColor,
trailingContent = trailingContent,
modifier = modifier,
)
@@ -107,7 +101,6 @@ fun SongItem(
onClick: () -> Unit,
menuContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
backgroundColor: Color? = null,
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
trailingContent: (@Composable () -> Unit)? = null
) {
@@ -134,7 +127,6 @@ fun SongItem(
}
},
menuContent = menuContent,
backgroundColor = backgroundColor,
trailingContent = trailingContent,
modifier = modifier,
)
@@ -151,11 +143,10 @@ fun SongItem(
startContent: @Composable () -> Unit,
menuContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
backgroundColor: Color? = null,
trailingContent: (@Composable () -> Unit)? = null
) {
val menuState = LocalMenuState.current
val (colorPalette, typography) = LocalAppearance.current
val (_, typography) = LocalAppearance.current
Row(
verticalAlignment = Alignment.CenterVertically,
@@ -171,7 +162,6 @@ fun SongItem(
)
.fillMaxWidth()
.padding(vertical = Dimensions.itemsVerticalPadding)
.background(backgroundColor ?: colorPalette.background)
.padding(start = 16.dp, end = if (trailingContent == null) 16.dp else 8.dp)
) {
startContent()

View File

@@ -2,6 +2,7 @@ package it.vfsfitvnm.vimusic.ui.views.player
import android.text.format.DateUtils
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -40,6 +41,7 @@ import it.vfsfitvnm.vimusic.models.Song
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.ui.components.SeekBar
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.favoritesIcon
import it.vfsfitvnm.vimusic.utils.bold
import it.vfsfitvnm.vimusic.utils.rememberRepeatMode
import it.vfsfitvnm.vimusic.utils.secondary
@@ -70,7 +72,7 @@ fun Controls(
Database.likedAt(mediaItem.mediaId).distinctUntilChanged()
}.collectAsState(initial = null, context = Dispatchers.IO)
val playPauseRoundness by animateDpAsState(if (shouldBePlaying) 32.dp else 16.dp)
val playPauseRoundness by animateDpAsState(if (shouldBePlaying) 32.dp else 16.dp, tween())
Column(
horizontalAlignment = Alignment.CenterHorizontally,
@@ -121,7 +123,7 @@ fun Controls(
scrubbingPosition = null
},
color = colorPalette.text,
backgroundColor = colorPalette.backgroundContainer,
backgroundColor = colorPalette.background2,
shape = RoundedCornerShape(8.dp)
)
@@ -166,7 +168,7 @@ fun Controls(
Image(
painter = painterResource(R.drawable.heart),
contentDescription = null,
colorFilter = ColorFilter.tint(if (likedAt != null) colorPalette.red else colorPalette.textDisabled),
colorFilter = ColorFilter.tint(if (likedAt == null) colorPalette.background2 else colorPalette.favoritesIcon),
modifier = Modifier
.clickable {
query {
@@ -211,7 +213,7 @@ fun Controls(
binder.player.play()
}
}
.background(color = colorPalette.backgroundContainer)
.background(colorPalette.background2)
.size(64.dp)
) {
Image(

View File

@@ -57,9 +57,10 @@ import it.vfsfitvnm.vimusic.ui.components.themed.Menu
import it.vfsfitvnm.vimusic.ui.components.themed.MenuEntry
import it.vfsfitvnm.vimusic.ui.components.themed.TextFieldDialog
import it.vfsfitvnm.vimusic.ui.components.themed.TextPlaceholder
import it.vfsfitvnm.vimusic.ui.styling.BlackColorPalette
import it.vfsfitvnm.vimusic.ui.styling.DarkColorPalette
import it.vfsfitvnm.vimusic.ui.styling.PureBlackColorPalette
import it.vfsfitvnm.vimusic.ui.styling.DefaultDarkColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.onOverlayShimmer
import it.vfsfitvnm.vimusic.utils.SynchronizedLyrics
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.color
@@ -88,7 +89,7 @@ fun Lyrics(
nestedScrollConnectionProvider: () -> NestedScrollConnection,
modifier: Modifier = Modifier
) {
val (_, typography) = LocalAppearance.current
val (colorPalette, typography) = LocalAppearance.current
val context = LocalContext.current
AnimatedVisibility(
@@ -194,7 +195,7 @@ fun Lyrics(
) {
BasicText(
text = "An error has occurred while fetching the ${if (isShowingSynchronizedLyrics) "synchronized " else ""}lyrics",
style = typography.xs.center.medium.color(BlackColorPalette.text),
style = typography.xs.center.medium.color(PureBlackColorPalette.text),
modifier = Modifier
.background(Color.Black.copy(0.4f))
.padding(all = 8.dp)
@@ -211,7 +212,7 @@ fun Lyrics(
) {
BasicText(
text = "${if (isShowingSynchronizedLyrics) "Synchronized l" else "L"}yrics are not available for this song",
style = typography.xs.center.medium.color(BlackColorPalette.text),
style = typography.xs.center.medium.color(PureBlackColorPalette.text),
modifier = Modifier
.background(Color.Black.copy(0.4f))
.padding(all = 8.dp)
@@ -227,6 +228,7 @@ fun Lyrics(
) {
repeat(4) { index ->
TextPlaceholder(
color = colorPalette.onOverlayShimmer,
modifier = Modifier
.alpha(1f - index * 0.05f)
)
@@ -269,7 +271,7 @@ fun Lyrics(
itemsIndexed(items = synchronizedLyrics.sentences) { index, sentence ->
BasicText(
text = sentence.second,
style = typography.xs.center.medium.color(if (index == synchronizedLyrics.index) BlackColorPalette.text else BlackColorPalette.textDisabled),
style = typography.xs.center.medium.color(if (index == synchronizedLyrics.index) PureBlackColorPalette.text else PureBlackColorPalette.textDisabled),
modifier = Modifier
.padding(vertical = 4.dp, horizontal = 32.dp)
)
@@ -278,7 +280,7 @@ fun Lyrics(
} else {
BasicText(
text = lyrics,
style = typography.xs.center.medium.color(BlackColorPalette.text),
style = typography.xs.center.medium.color(PureBlackColorPalette.text),
modifier = Modifier
.nestedScroll(remember { nestedScrollConnectionProvider() })
.verticalFadingEdge()
@@ -293,7 +295,7 @@ fun Lyrics(
Image(
painter = painterResource(R.drawable.ellipsis_horizontal),
contentDescription = null,
colorFilter = ColorFilter.tint(DarkColorPalette.text),
colorFilter = ColorFilter.tint(DefaultDarkColorPalette.text),
modifier = Modifier
.padding(all = 4.dp)
.clickable {

View File

@@ -20,7 +20,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import it.vfsfitvnm.vimusic.ui.styling.BlackColorPalette
import it.vfsfitvnm.vimusic.ui.styling.PureBlackColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.utils.center
import it.vfsfitvnm.vimusic.utils.color
@@ -64,7 +64,7 @@ fun PlaybackError(
) {
BasicText(
text = remember { messageProvider() },
style = typography.xs.center.medium.color(BlackColorPalette.text),
style = typography.xs.center.medium.color(PureBlackColorPalette.text),
modifier = Modifier
.background(Color.Black.copy(0.4f))
.padding(all = 8.dp)

View File

@@ -25,7 +25,6 @@ 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.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
@@ -35,8 +34,9 @@ import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.models.Format
import it.vfsfitvnm.vimusic.query
import it.vfsfitvnm.vimusic.ui.styling.BlackColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.onOverlay
import it.vfsfitvnm.vimusic.ui.styling.overlay
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.medium
import it.vfsfitvnm.vimusic.utils.rememberVolume
@@ -53,7 +53,7 @@ fun StatsForNerds(
onDismiss: () -> Unit,
modifier: Modifier = Modifier
) {
val (_, typography) = LocalAppearance.current
val (colorPalette, typography) = LocalAppearance.current
val context = LocalContext.current
val binder = LocalPlayerServiceBinder.current ?: return
@@ -105,7 +105,7 @@ fun StatsForNerds(
}
)
}
.background(Color.Black.copy(alpha = 0.8f))
.background(colorPalette.overlay)
.fillMaxSize()
) {
Row(
@@ -117,50 +117,50 @@ fun StatsForNerds(
Column(horizontalAlignment = Alignment.End) {
BasicText(
text = "Id",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Volume",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Loudness",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Bitrate",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Size",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "Cached",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
}
Column {
BasicText(
text = mediaId,
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = "${volume.times(100).roundToInt()}%",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = format?.loudnessDb?.let { loudnessDb ->
"%.2f dB".format(loudnessDb)
} ?: "Unknown",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = format?.bitrate?.let { bitrate ->
"${bitrate / 1000} kbps"
} ?: "Unknown",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = format?.contentLength?.let { contentLength ->
@@ -169,7 +169,7 @@ fun StatsForNerds(
contentLength
)
} ?: "Unknown",
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
BasicText(
text = buildString {
@@ -179,7 +179,7 @@ fun StatsForNerds(
append(" (${(cachedBytes.toFloat() / contentLength * 100).roundToInt()}%)")
}
},
style = typography.xs.medium.color(BlackColorPalette.text)
style = typography.xs.medium.color(colorPalette.onOverlay)
)
}
}
@@ -187,7 +187,7 @@ fun StatsForNerds(
if (format != null && format?.itag == null) {
BasicText(
text = "FETCH MISSING DATA",
style = typography.xxs.medium.color(BlackColorPalette.text),
style = typography.xxs.medium.color(colorPalette.onOverlay),
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),