Add IconButton composable

This commit is contained in:
vfsfitvnm 2022-10-04 14:31:59 +02:00
parent 185c5ec726
commit 7fe9c1dee8
7 changed files with 299 additions and 366 deletions

View file

@ -23,17 +23,12 @@ fun HeaderIconButton(
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() },
IconButton(
icon = icon,
color = color,
onClick = onClick,
enabled = enabled,
onClick = onClick
)
modifier = modifier
.padding(all = 4.dp)
.size(18.dp)
)
@ -51,12 +46,13 @@ fun IconButton(
painter = painterResource(icon),
contentDescription = null,
colorFilter = ColorFilter.tint(color),
modifier = modifier
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = false),
interactionSource = remember { MutableInteractionSource() },
enabled = enabled,
onClick = onClick
)
.then(modifier)
)
}

View file

@ -3,7 +3,6 @@ package it.vfsfitvnm.vimusic.ui.screens.album
import android.content.Intent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.BoxWithConstraints
@ -21,9 +20,7 @@ import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.valentinilk.shimmer.shimmer
@ -39,6 +36,7 @@ import it.vfsfitvnm.vimusic.savers.InnertubePlaylistOrAlbumPageSaver
import it.vfsfitvnm.vimusic.savers.innertubeItemsPageSaver
import it.vfsfitvnm.vimusic.savers.nullableSaver
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
import it.vfsfitvnm.vimusic.ui.items.AlbumItem
@ -143,18 +141,14 @@ fun AlbumScreen(browseId: String) {
.weight(1f)
)
Image(
painter = painterResource(
if (album?.bookmarkedAt == null) {
HeaderIconButton(
icon = if (album?.bookmarkedAt == null) {
R.drawable.bookmark_outline
} else {
R.drawable.bookmark
}
),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.accent),
modifier = Modifier
.clickable {
},
color = colorPalette.accent,
onClick = {
val bookmarkedAt =
if (album?.bookmarkedAt == null) System.currentTimeMillis() else null
@ -164,16 +158,12 @@ fun AlbumScreen(browseId: String) {
?.let(Database::update)
}
}
.padding(all = 4.dp)
.size(18.dp)
)
Image(
painter = painterResource(R.drawable.share_social),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
HeaderIconButton(
icon = R.drawable.share_social,
color = colorPalette.text,
onClick = {
album?.shareUrl?.let { url ->
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
@ -184,8 +174,6 @@ fun AlbumScreen(browseId: String) {
context.startActivity(Intent.createChooser(sendIntent, null))
}
}
.padding(all = 4.dp)
.size(18.dp)
)
}
}

View file

@ -3,7 +3,6 @@ package it.vfsfitvnm.vimusic.ui.screens.artist
import android.content.Intent
import androidx.compose.animation.ExperimentalAnimationApi
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
@ -21,9 +20,7 @@ import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.valentinilk.shimmer.shimmer
@ -40,6 +37,7 @@ import it.vfsfitvnm.vimusic.savers.InnertubeSongsPageSaver
import it.vfsfitvnm.vimusic.savers.nullableSaver
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.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.Scaffold
@ -96,7 +94,11 @@ fun ArtistScreen(browseId: String) {
stateSaver = nullableSaver(InnertubeArtistPageSaver),
tabIndex < 4
) {
if (value != null || (tabIndex == 4 && withContext(Dispatchers.IO) { Database.artistTimestamp(browseId) } != null)) return@produceSaveableState
if (value != null || (tabIndex == 4 && withContext(Dispatchers.IO) {
Database.artistTimestamp(
browseId
)
} != null)) return@produceSaveableState
withContext(Dispatchers.IO) {
Innertube.artistPage(BrowseBody(browseId = browseId))
@ -154,13 +156,15 @@ fun ArtistScreen(browseId: String) {
}
}
val headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit = { textButton ->
val headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit =
{ textButton ->
if (artist?.timestamp == null) {
HeaderPlaceholder(
modifier = Modifier
.shimmer()
)
} else {
val (colorPalette) = LocalAppearance.current
val context = LocalContext.current
Header(title = artist?.name ?: "Unknown") {
@ -171,18 +175,14 @@ fun ArtistScreen(browseId: String) {
.weight(1f)
)
Image(
painter = painterResource(
if (artist?.bookmarkedAt == null) {
HeaderIconButton(
icon = if (artist?.bookmarkedAt == null) {
R.drawable.bookmark_outline
} else {
R.drawable.bookmark
}
),
contentDescription = null,
colorFilter = ColorFilter.tint(LocalAppearance.current.colorPalette.accent),
modifier = Modifier
.clickable {
},
color = colorPalette.accent,
onClick = {
val bookmarkedAt =
if (artist?.bookmarkedAt == null) System.currentTimeMillis() else null
@ -192,16 +192,12 @@ fun ArtistScreen(browseId: String) {
?.let(Database::update)
}
}
.padding(all = 4.dp)
.size(18.dp)
)
Image(
painter = painterResource(R.drawable.share_social),
contentDescription = null,
colorFilter = ColorFilter.tint(LocalAppearance.current.colorPalette.text),
modifier = Modifier
.clickable {
HeaderIconButton(
icon = R.drawable.share_social,
color = colorPalette.text,
onClick = {
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
@ -211,15 +207,8 @@ fun ArtistScreen(browseId: String) {
)
}
context.startActivity(
Intent.createChooser(
sendIntent,
null
)
)
context.startActivity(Intent.createChooser(sendIntent, null))
}
.padding(all = 4.dp)
.size(18.dp)
)
}
}
@ -256,12 +245,11 @@ fun ArtistScreen(browseId: String) {
val thumbnailSizeDp = Dimensions.thumbnails.song
val thumbnailSizePx = thumbnailSizeDp.px
ItemsPage(
stateSaver = InnertubeSongsPageSaver,
headerContent = headerContent,
itemsPageProvider = youtubeArtist?.let {({ continuation ->
itemsPageProvider = youtubeArtist?.let {
({ continuation ->
continuation?.let {
Innertube.itemsPage(
body = ContinuationBody(continuation = continuation),
@ -285,7 +273,8 @@ fun ArtistScreen(browseId: String) {
continuation = null
)
)
})},
})
},
itemContent = { song ->
SongItem(
song = song,
@ -320,7 +309,8 @@ fun ArtistScreen(browseId: String) {
stateSaver = InnertubeAlbumsPageSaver,
headerContent = headerContent,
emptyItemsText = "This artist didn't release any album",
itemsPageProvider = youtubeArtist?.let {({ continuation ->
itemsPageProvider = youtubeArtist?.let {
({ continuation ->
continuation?.let {
Innertube.itemsPage(
body = ContinuationBody(continuation = continuation),
@ -344,7 +334,8 @@ fun ArtistScreen(browseId: String) {
continuation = null
)
)
})},
})
},
itemContent = { album ->
AlbumItem(
album = album,
@ -368,7 +359,8 @@ fun ArtistScreen(browseId: String) {
stateSaver = InnertubeAlbumsPageSaver,
headerContent = headerContent,
emptyItemsText = "This artist didn't release any single",
itemsPageProvider = youtubeArtist?.let {({ continuation ->
itemsPageProvider = youtubeArtist?.let {
({ continuation ->
continuation?.let {
Innertube.itemsPage(
body = ContinuationBody(continuation = continuation),
@ -392,7 +384,8 @@ fun ArtistScreen(browseId: String) {
continuation = null
)
)
})},
})
},
itemContent = { album ->
AlbumItem(
album = album,

View file

@ -40,6 +40,7 @@ import it.vfsfitvnm.vimusic.transaction
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
import it.vfsfitvnm.vimusic.ui.components.themed.Header
import it.vfsfitvnm.vimusic.ui.components.themed.HeaderIconButton
import it.vfsfitvnm.vimusic.ui.components.themed.InPlaylistMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
import it.vfsfitvnm.vimusic.ui.components.themed.SecondaryTextButton
@ -164,12 +165,10 @@ fun LocalPlaylistSongs(
)
playlistWithSongs?.playlist?.browseId?.let { browseId ->
Image(
painter = painterResource(R.drawable.sync),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
HeaderIconButton(
icon = R.drawable.sync,
color = colorPalette.text,
onClick = {
transaction {
runBlocking(Dispatchers.IO) {
withContext(Dispatchers.IO) {
@ -193,30 +192,19 @@ fun LocalPlaylistSongs(
}
}
}
.padding(all = 4.dp)
.size(18.dp)
)
}
Image(
painter = painterResource(R.drawable.pencil),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable { isRenaming = true }
.padding(all = 4.dp)
.size(18.dp)
HeaderIconButton(
icon = R.drawable.pencil,
color = colorPalette.text,
onClick = { isRenaming = true }
)
Image(
painter = painterResource(R.drawable.trash),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable { isDeleting = true }
.padding(all = 4.dp)
.size(18.dp)
HeaderIconButton(
icon = R.drawable.trash,
color = colorPalette.text,
onClick = { isDeleting = true }
)
}
}

View file

@ -52,6 +52,7 @@ import it.vfsfitvnm.vimusic.ui.components.BottomSheet
import it.vfsfitvnm.vimusic.ui.components.BottomSheetState
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.MusicBars
import it.vfsfitvnm.vimusic.ui.components.themed.IconButton
import it.vfsfitvnm.vimusic.ui.components.themed.QueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.items.SongItem
import it.vfsfitvnm.vimusic.ui.items.SongItemPlaceholder
@ -227,7 +228,10 @@ fun PlayerBottomSheet(
}
)
.animateItemPlacement(reorderingState = reorderingState)
.draggedItem(reorderingState = reorderingState, index = window.firstPeriodIndex)
.draggedItem(
reorderingState = reorderingState,
index = window.firstPeriodIndex
)
)
}
@ -257,14 +261,13 @@ fun PlayerBottomSheet(
.height(64.dp + bottomPadding)
.background(colorPalette.background2)
.fillMaxWidth()
.padding(horizontal = 8.dp)
.padding(horizontal = 12.dp)
.padding(bottom = bottomPadding)
) {
BasicText(
text = "${windows.size} songs",
style = typography.xxs.medium,
modifier = Modifier
.padding(start = 4.dp)
.background(color = colorPalette.background1, shape = RoundedCornerShape(16.dp))
.align(Alignment.CenterStart)
.padding(all = 8.dp)
@ -279,22 +282,20 @@ fun PlayerBottomSheet(
.size(18.dp)
)
Image(
painter = painterResource(R.drawable.shuffle),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.padding(end = 2.dp)
.clickable {
IconButton(
icon = R.drawable.shuffle,
color = colorPalette.text,
onClick = {
reorderingState.coroutineScope.launch {
reorderingState.lazyListState.smoothScrollToTop()
}.invokeOnCompletion {
binder.player.shuffleQueue()
}
}
.align(Alignment.CenterEnd)
.padding(all = 8.dp)
},
modifier = Modifier
.padding(horizontal = 4.dp, vertical = 8.dp)
.size(20.dp)
.align(Alignment.CenterEnd)
)
}
}

View file

@ -8,9 +8,7 @@ import androidx.activity.compose.LocalActivityResultRegistryOwner
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -40,12 +38,10 @@ 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
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.media3.common.Player
@ -58,6 +54,7 @@ import it.vfsfitvnm.vimusic.ui.components.BottomSheetState
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
import it.vfsfitvnm.vimusic.ui.components.rememberBottomSheetState
import it.vfsfitvnm.vimusic.ui.components.themed.BaseMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.IconButton
import it.vfsfitvnm.vimusic.ui.styling.Dimensions
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
import it.vfsfitvnm.vimusic.ui.styling.collapsedPlayerProgressBar
@ -178,9 +175,10 @@ fun PlayerView(
modifier = Modifier
.height(Dimensions.collapsedPlayer)
) {
Box(
modifier = Modifier
.clickable {
IconButton(
icon = if (shouldBePlaying) R.drawable.pause else R.drawable.play,
color = colorPalette.text,
onClick = {
if (shouldBePlaying) {
binder.player.pause()
} else {
@ -189,34 +187,21 @@ fun PlayerView(
}
binder.player.play()
}
}
.padding(horizontal = 4.dp, vertical = 8.dp)
) {
Image(
painter = painterResource(if (shouldBePlaying) R.drawable.pause else R.drawable.play),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
},
modifier = Modifier
.align(Alignment.Center)
.padding(horizontal = 4.dp, vertical = 8.dp)
.size(20.dp)
)
}
Box(
IconButton(
icon = R.drawable.play_skip_forward,
color = colorPalette.text,
onClick = binder.player::seekToNext,
modifier = Modifier
.clickable(onClick = binder.player::seekToNext)
.padding(horizontal = 4.dp, vertical = 8.dp)
) {
Image(
painter = painterResource(R.drawable.play_skip_forward),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.align(Alignment.Center)
.size(20.dp)
)
}
}
Spacer(
modifier = Modifier
@ -335,12 +320,10 @@ fun PlayerView(
.padding(horizontal = 8.dp)
.fillMaxHeight()
) {
Image(
painter = painterResource(R.drawable.ellipsis_horizontal),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
IconButton(
icon = R.drawable.ellipsis_horizontal,
color = colorPalette.text,
onClick = {
menuState.display {
val resultRegistryOwner =
LocalActivityResultRegistryOwner.current
@ -380,11 +363,7 @@ fun PlayerView(
?.launch(intent)
} else {
Toast
.makeText(
context,
"No equalizer app found!",
Toast.LENGTH_SHORT
)
.makeText(context, "No equalizer app found!", Toast.LENGTH_SHORT)
.show()
}
},
@ -392,8 +371,9 @@ fun PlayerView(
onDismiss = menuState::hide
)
}
}
.padding(all = 8.dp)
},
modifier = Modifier
.padding(horizontal = 4.dp, vertical = 8.dp)
.size(20.dp)
)

View file

@ -3,9 +3,7 @@ package it.vfsfitvnm.vimusic.ui.screens.playlist
import android.content.Intent
import androidx.compose.animation.ExperimentalAnimationApi
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.layout.Arrangement
import androidx.compose.foundation.layout.Box
@ -28,9 +26,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.valentinilk.shimmer.shimmer
@ -45,6 +41,7 @@ import it.vfsfitvnm.vimusic.savers.resultSaver
import it.vfsfitvnm.vimusic.transaction
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.HeaderPlaceholder
import it.vfsfitvnm.vimusic.ui.components.themed.NonQueuedMediaItemMenu
import it.vfsfitvnm.vimusic.ui.components.themed.PrimaryButton
@ -137,14 +134,10 @@ fun PlaylistSongList(
.weight(1f)
)
Image(
painter = painterResource(
if (isImported == true) R.drawable.bookmark else R.drawable.bookmark_outline
),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.accent),
modifier = Modifier
.clickable(enabled = isImported == false) {
HeaderIconButton(
icon = if (isImported == true) R.drawable.bookmark else R.drawable.bookmark_outline,
color = colorPalette.accent,
onClick = {
transaction {
val playlistId =
Database.insert(
@ -166,16 +159,12 @@ fun PlaylistSongList(
}?.let(Database::insertSongPlaylistMaps)
}
}
.padding(all = 4.dp)
.size(18.dp)
)
Image(
painter = painterResource(R.drawable.share_social),
contentDescription = null,
colorFilter = ColorFilter.tint(colorPalette.text),
modifier = Modifier
.clickable {
HeaderIconButton(
icon = R.drawable.share_social,
color = colorPalette.text,
onClick = {
(playlist.url ?: "https://music.youtube.com/playlist?list=${browseId.removePrefix("VL")}").let { url ->
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
@ -186,8 +175,6 @@ fun PlaylistSongList(
context.startActivity(Intent.createChooser(sendIntent, null))
}
}
.padding(all = 4.dp)
.size(18.dp)
)
}