diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/IconButton.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/IconButton.kt index 6348bbb..934c5e8 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/IconButton.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/themed/IconButton.kt @@ -23,17 +23,12 @@ fun HeaderIconButton( modifier: Modifier = Modifier, enabled: Boolean = true ) { - Image( - painter = painterResource(icon), - contentDescription = null, - colorFilter = ColorFilter.tint(color), + IconButton( + icon = icon, + color = color, + onClick = onClick, + enabled = enabled, modifier = modifier - .clickable( - indication = rememberRipple(bounded = false), - interactionSource = remember { MutableInteractionSource() }, - enabled = enabled, - onClick = onClick - ) .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) ) } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/album/AlbumScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/album/AlbumScreen.kt index cb6997d..cb4ec58 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/album/AlbumScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/album/AlbumScreen.kt @@ -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,49 +141,39 @@ fun AlbumScreen(browseId: String) { .weight(1f) ) - Image( - painter = painterResource( - if (album?.bookmarkedAt == null) { - R.drawable.bookmark_outline - } else { - R.drawable.bookmark - } - ), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.accent), - modifier = Modifier - .clickable { - val bookmarkedAt = - if (album?.bookmarkedAt == null) System.currentTimeMillis() else null + HeaderIconButton( + icon = if (album?.bookmarkedAt == null) { + R.drawable.bookmark_outline + } else { + R.drawable.bookmark + }, + color = colorPalette.accent, + onClick = { + val bookmarkedAt = + if (album?.bookmarkedAt == null) System.currentTimeMillis() else null - query { - album - ?.copy(bookmarkedAt = bookmarkedAt) - ?.let(Database::update) - } + query { + album + ?.copy(bookmarkedAt = bookmarkedAt) + ?.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 { - album?.shareUrl?.let { url -> - val sendIntent = Intent().apply { - action = Intent.ACTION_SEND - type = "text/plain" - putExtra(Intent.EXTRA_TEXT, url) - } - - context.startActivity(Intent.createChooser(sendIntent, null)) + HeaderIconButton( + icon = R.drawable.share_social, + color = colorPalette.text, + onClick = { + album?.shareUrl?.let { url -> + val sendIntent = Intent().apply { + action = Intent.ACTION_SEND + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, url) } + + context.startActivity(Intent.createChooser(sendIntent, null)) } - .padding(all = 4.dp) - .size(18.dp) + } ) } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/artist/ArtistScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/artist/ArtistScreen.kt index cd02be2..e1535ed 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/artist/ArtistScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/artist/ArtistScreen.kt @@ -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,35 +156,33 @@ fun ArtistScreen(browseId: String) { } } - val headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit = { textButton -> - if (artist?.timestamp == null) { - HeaderPlaceholder( - modifier = Modifier - .shimmer() - ) - } else { - val context = LocalContext.current - - Header(title = artist?.name ?: "Unknown") { - textButton?.invoke() - - Spacer( + val headerContent: @Composable (textButton: (@Composable () -> Unit)?) -> Unit = + { textButton -> + if (artist?.timestamp == null) { + HeaderPlaceholder( modifier = Modifier - .weight(1f) + .shimmer() ) + } else { + val (colorPalette) = LocalAppearance.current + val context = LocalContext.current - Image( - painter = painterResource( - if (artist?.bookmarkedAt == null) { + Header(title = artist?.name ?: "Unknown") { + textButton?.invoke() + + Spacer( + modifier = Modifier + .weight(1f) + ) + + 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,19 +207,12 @@ fun ArtistScreen(browseId: String) { ) } - context.startActivity( - Intent.createChooser( - sendIntent, - null - ) - ) + context.startActivity(Intent.createChooser(sendIntent, null)) } - .padding(all = 4.dp) - .size(18.dp) - ) + ) + } } } - } Scaffold( topIconButtonId = R.drawable.chevron_back, @@ -256,36 +245,36 @@ fun ArtistScreen(browseId: String) { val thumbnailSizeDp = Dimensions.thumbnails.song val thumbnailSizePx = thumbnailSizeDp.px - - ItemsPage( stateSaver = InnertubeSongsPageSaver, headerContent = headerContent, - itemsPageProvider = youtubeArtist?.let {({ continuation -> - continuation?.let { - Innertube.itemsPage( - body = ContinuationBody(continuation = continuation), - fromMusicResponsiveListItemRenderer = Innertube.SongItem::from, - ) - } ?: youtubeArtist - ?.songsEndpoint - ?.takeIf { it.browseId != null } - ?.let { endpoint -> + itemsPageProvider = youtubeArtist?.let { + ({ continuation -> + continuation?.let { Innertube.itemsPage( - body = BrowseBody( - browseId = endpoint.browseId!!, - params = endpoint.params, - ), + body = ContinuationBody(continuation = continuation), fromMusicResponsiveListItemRenderer = Innertube.SongItem::from, ) - } - ?: Result.success( - Innertube.ItemsPage( - items = youtubeArtist?.songs, - continuation = null + } ?: youtubeArtist + ?.songsEndpoint + ?.takeIf { it.browseId != null } + ?.let { endpoint -> + Innertube.itemsPage( + body = BrowseBody( + browseId = endpoint.browseId!!, + params = endpoint.params, + ), + fromMusicResponsiveListItemRenderer = Innertube.SongItem::from, + ) + } + ?: Result.success( + Innertube.ItemsPage( + items = youtubeArtist?.songs, + continuation = null + ) ) - ) - })}, + }) + }, itemContent = { song -> SongItem( song = song, @@ -320,31 +309,33 @@ fun ArtistScreen(browseId: String) { stateSaver = InnertubeAlbumsPageSaver, headerContent = headerContent, emptyItemsText = "This artist didn't release any album", - itemsPageProvider = youtubeArtist?.let {({ continuation -> - continuation?.let { - Innertube.itemsPage( - body = ContinuationBody(continuation = continuation), - fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from, - ) - } ?: youtubeArtist - ?.albumsEndpoint - ?.takeIf { it.browseId != null } - ?.let { endpoint -> + itemsPageProvider = youtubeArtist?.let { + ({ continuation -> + continuation?.let { Innertube.itemsPage( - body = BrowseBody( - browseId = endpoint.browseId!!, - params = endpoint.params, - ), + body = ContinuationBody(continuation = continuation), fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from, ) - } - ?: Result.success( - Innertube.ItemsPage( - items = youtubeArtist?.albums, - continuation = null + } ?: youtubeArtist + ?.albumsEndpoint + ?.takeIf { it.browseId != null } + ?.let { endpoint -> + Innertube.itemsPage( + body = BrowseBody( + browseId = endpoint.browseId!!, + params = endpoint.params, + ), + fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from, + ) + } + ?: Result.success( + Innertube.ItemsPage( + items = youtubeArtist?.albums, + continuation = null + ) ) - ) - })}, + }) + }, itemContent = { album -> AlbumItem( album = album, @@ -368,31 +359,33 @@ fun ArtistScreen(browseId: String) { stateSaver = InnertubeAlbumsPageSaver, headerContent = headerContent, emptyItemsText = "This artist didn't release any single", - itemsPageProvider = youtubeArtist?.let {({ continuation -> - continuation?.let { - Innertube.itemsPage( - body = ContinuationBody(continuation = continuation), - fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from, - ) - } ?: youtubeArtist - ?.singlesEndpoint - ?.takeIf { it.browseId != null } - ?.let { endpoint -> + itemsPageProvider = youtubeArtist?.let { + ({ continuation -> + continuation?.let { Innertube.itemsPage( - body = BrowseBody( - browseId = endpoint.browseId!!, - params = endpoint.params, - ), + body = ContinuationBody(continuation = continuation), fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from, ) - } - ?: Result.success( - Innertube.ItemsPage( - items = youtubeArtist?.singles, - continuation = null + } ?: youtubeArtist + ?.singlesEndpoint + ?.takeIf { it.browseId != null } + ?.let { endpoint -> + Innertube.itemsPage( + body = BrowseBody( + browseId = endpoint.browseId!!, + params = endpoint.params, + ), + fromMusicTwoRowItemRenderer = Innertube.AlbumItem::from, + ) + } + ?: Result.success( + Innertube.ItemsPage( + items = youtubeArtist?.singles, + continuation = null + ) ) - ) - })}, + }) + }, itemContent = { album -> AlbumItem( album = album, diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt index 3c16c5a..473da26 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/localplaylist/LocalPlaylistSongs.kt @@ -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,59 +165,46 @@ fun LocalPlaylistSongs( ) playlistWithSongs?.playlist?.browseId?.let { browseId -> - Image( - painter = painterResource(R.drawable.sync), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.text), - modifier = Modifier - .clickable { - transaction { - runBlocking(Dispatchers.IO) { - withContext(Dispatchers.IO) { - Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed() - } - }?.getOrNull()?.let { remotePlaylist -> - Database.clearPlaylist(playlistId) - - remotePlaylist. - songsPage - ?.items - ?.map(Innertube.SongItem::asMediaItem) - ?.onEach(Database::insert) - ?.mapIndexed { position, mediaItem -> - SongPlaylistMap( - songId = mediaItem.mediaId, - playlistId = playlistId, - position = position - ) - }?.let(Database::insertSongPlaylistMaps) + HeaderIconButton( + icon = R.drawable.sync, + color = colorPalette.text, + onClick = { + transaction { + runBlocking(Dispatchers.IO) { + withContext(Dispatchers.IO) { + Innertube.playlistPage(BrowseBody(browseId = browseId))?.completed() } + }?.getOrNull()?.let { remotePlaylist -> + Database.clearPlaylist(playlistId) + + remotePlaylist. + songsPage + ?.items + ?.map(Innertube.SongItem::asMediaItem) + ?.onEach(Database::insert) + ?.mapIndexed { position, mediaItem -> + SongPlaylistMap( + songId = mediaItem.mediaId, + playlistId = playlistId, + position = position + ) + }?.let(Database::insertSongPlaylistMaps) } } - .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 } ) } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerBottomSheet.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerBottomSheet.kt index 34181b5..0309f7d 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerBottomSheet.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerBottomSheet.kt @@ -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 { - reorderingState.coroutineScope.launch { - reorderingState.lazyListState.smoothScrollToTop() - }.invokeOnCompletion { - binder.player.shuffleQueue() - } + 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) ) } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerView.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerView.kt index ea374f9..68a34ae 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerView.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/player/PlayerView.kt @@ -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,44 +175,32 @@ fun PlayerView( modifier = Modifier .height(Dimensions.collapsedPlayer) ) { - Box( - modifier = Modifier - .clickable { - if (shouldBePlaying) { - binder.player.pause() - } else { - if (binder.player.playbackState == Player.STATE_IDLE) { - binder.player.prepare() - } - binder.player.play() + IconButton( + icon = if (shouldBePlaying) R.drawable.pause else R.drawable.play, + color = colorPalette.text, + onClick = { + if (shouldBePlaying) { + binder.player.pause() + } else { + if (binder.player.playbackState == Player.STATE_IDLE) { + binder.player.prepare() } + 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) - .size(20.dp) - ) - } - - Box( + }, 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) - ) - } + .size(20.dp) + ) + + IconButton( + icon = R.drawable.play_skip_forward, + color = colorPalette.text, + onClick = binder.player::seekToNext, + modifier = Modifier + .padding(horizontal = 4.dp, vertical = 8.dp) + .size(20.dp) + ) } Spacer( @@ -335,65 +320,60 @@ fun PlayerView( .padding(horizontal = 8.dp) .fillMaxHeight() ) { - Image( - painter = painterResource(R.drawable.ellipsis_horizontal), - contentDescription = null, - colorFilter = ColorFilter.tint(colorPalette.text), - modifier = Modifier - .clickable { - menuState.display { - val resultRegistryOwner = - LocalActivityResultRegistryOwner.current + IconButton( + icon = R.drawable.ellipsis_horizontal, + color = colorPalette.text, + onClick = { + menuState.display { + val resultRegistryOwner = + LocalActivityResultRegistryOwner.current - BaseMediaItemMenu( - mediaItem = mediaItem, - onStartRadio = { - binder.stopRadio() - binder.player.seamlessPlay(mediaItem) - binder.setupRadio( - NavigationEndpoint.Endpoint.Watch(videoId = mediaItem.mediaId) - ) - }, - onGoToEqualizer = { - val intent = - Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply { - putExtra( - AudioEffect.EXTRA_AUDIO_SESSION, - binder.player.audioSessionId - ) - putExtra( - AudioEffect.EXTRA_PACKAGE_NAME, - context.packageName - ) - putExtra( - AudioEffect.EXTRA_CONTENT_TYPE, - AudioEffect.CONTENT_TYPE_MUSIC - ) - } - - if (intent.resolveActivity(context.packageManager) != null) { - val contract = - ActivityResultContracts.StartActivityForResult() - - resultRegistryOwner?.activityResultRegistry - ?.register("", contract) {} - ?.launch(intent) - } else { - Toast - .makeText( - context, - "No equalizer app found!", - Toast.LENGTH_SHORT - ) - .show() + BaseMediaItemMenu( + mediaItem = mediaItem, + onStartRadio = { + binder.stopRadio() + binder.player.seamlessPlay(mediaItem) + binder.setupRadio( + NavigationEndpoint.Endpoint.Watch(videoId = mediaItem.mediaId) + ) + }, + onGoToEqualizer = { + val intent = + Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL).apply { + putExtra( + AudioEffect.EXTRA_AUDIO_SESSION, + binder.player.audioSessionId + ) + putExtra( + AudioEffect.EXTRA_PACKAGE_NAME, + context.packageName + ) + putExtra( + AudioEffect.EXTRA_CONTENT_TYPE, + AudioEffect.CONTENT_TYPE_MUSIC + ) } - }, - onSetSleepTimer = {}, - onDismiss = menuState::hide - ) - } + + if (intent.resolveActivity(context.packageManager) != null) { + val contract = + ActivityResultContracts.StartActivityForResult() + + resultRegistryOwner?.activityResultRegistry + ?.register("", contract) {} + ?.launch(intent) + } else { + Toast + .makeText(context, "No equalizer app found!", Toast.LENGTH_SHORT) + .show() + } + }, + onSetSleepTimer = {}, + onDismiss = menuState::hide + ) } - .padding(all = 8.dp) + }, + modifier = Modifier + .padding(horizontal = 4.dp, vertical = 8.dp) .size(20.dp) ) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt index b7f3694..e861d97 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/playlist/PlaylistSongList.kt @@ -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,57 +134,47 @@ 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) { - transaction { - val playlistId = - Database.insert( - Playlist( - name = playlist.title ?: "Unknown", - browseId = browseId - ) + HeaderIconButton( + icon = if (isImported == true) R.drawable.bookmark else R.drawable.bookmark_outline, + color = colorPalette.accent, + onClick = { + transaction { + val playlistId = + Database.insert( + Playlist( + name = playlist.title ?: "Unknown", + browseId = browseId ) + ) - playlist.songsPage?.items - ?.map(Innertube.SongItem::asMediaItem) - ?.onEach(Database::insert) - ?.mapIndexed { index, mediaItem -> - SongPlaylistMap( - songId = mediaItem.mediaId, - playlistId = playlistId, - position = index - ) - }?.let(Database::insertSongPlaylistMaps) - } + playlist.songsPage?.items + ?.map(Innertube.SongItem::asMediaItem) + ?.onEach(Database::insert) + ?.mapIndexed { index, mediaItem -> + SongPlaylistMap( + songId = mediaItem.mediaId, + playlistId = playlistId, + position = index + ) + }?.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 { - (playlist.url ?: "https://music.youtube.com/playlist?list=${browseId.removePrefix("VL")}").let { url -> - val sendIntent = Intent().apply { - action = Intent.ACTION_SEND - type = "text/plain" - putExtra(Intent.EXTRA_TEXT, url) - } - - context.startActivity(Intent.createChooser(sendIntent, null)) + 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 + type = "text/plain" + putExtra(Intent.EXTRA_TEXT, url) } + + context.startActivity(Intent.createChooser(sendIntent, null)) } - .padding(all = 4.dp) - .size(18.dp) + } ) }