Revamp compose-routing
This commit is contained in:
parent
795bf3d56f
commit
fcd84cde43
23 changed files with 122 additions and 474 deletions
|
@ -43,9 +43,9 @@ import it.vfsfitvnm.vimusic.transaction
|
|||
import it.vfsfitvnm.vimusic.ui.components.ChunkyButton
|
||||
import it.vfsfitvnm.vimusic.ui.components.LocalMenuState
|
||||
import it.vfsfitvnm.vimusic.ui.components.Pager
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberCreatePlaylistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.albumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.artistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.viewPlaylistsRoute
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.addNext
|
||||
import it.vfsfitvnm.vimusic.utils.asMediaItem
|
||||
|
@ -235,9 +235,6 @@ fun BaseMediaItemMenu(
|
|||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
MediaItemMenu(
|
||||
mediaItem = mediaItem,
|
||||
onDismiss = onDismiss,
|
||||
|
@ -299,8 +296,6 @@ fun MediaItemMenu(
|
|||
Database.playlistPreviews(PlaylistSortBy.DateAdded, SortOrder.Descending)
|
||||
}.collectAsState(initial = emptyList(), context = Dispatchers.IO)
|
||||
|
||||
val viewPlaylistsRoute = rememberCreatePlaylistRoute()
|
||||
|
||||
Menu(modifier = modifier) {
|
||||
RouteHandler(
|
||||
transitionSpec = {
|
||||
|
|
|
@ -81,9 +81,7 @@ import kotlinx.coroutines.runBlocking
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun AlbumScreen(
|
||||
browseId: String
|
||||
) {
|
||||
fun AlbumScreen(browseId: String) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val albumResult by remember(browseId) {
|
||||
|
@ -99,21 +97,8 @@ fun AlbumScreen(
|
|||
Database.albumSongs(browseId)
|
||||
}.collectAsState(initial = emptyList(), context = Dispatchers.IO)
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val context = LocalContext.current
|
||||
|
|
|
@ -63,26 +63,11 @@ import kotlinx.coroutines.runBlocking
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun ArtistScreen(
|
||||
browseId: String,
|
||||
) {
|
||||
fun ArtistScreen(browseId: String) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
|
|
|
@ -54,26 +54,11 @@ import kotlinx.coroutines.flow.map
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun BuiltInPlaylistScreen(
|
||||
builtInPlaylist: BuiltInPlaylist,
|
||||
) {
|
||||
fun BuiltInPlaylistScreen(builtInPlaylist: BuiltInPlaylist) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val menuState = LocalMenuState.current
|
||||
|
|
|
@ -108,15 +108,6 @@ fun HomeScreen() {
|
|||
val lazyListState = rememberLazyListState()
|
||||
val lazyHorizontalGridState = rememberLazyGridState()
|
||||
|
||||
val intentUriRoute = rememberIntentUriRoute()
|
||||
val settingsRoute = rememberSettingsRoute()
|
||||
val playlistRoute = rememberLocalPlaylistRoute()
|
||||
val builtInPlaylistRoute = rememberBuiltInPlaylistRoute()
|
||||
val searchRoute = rememberSearchRoute()
|
||||
val searchResultRoute = rememberSearchResultRoute()
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
var playlistSortBy by rememberPreference(playlistSortByKey, PlaylistSortBy.DateAdded)
|
||||
var playlistSortOrder by rememberPreference(playlistSortOrderKey, SortOrder.Descending)
|
||||
var playlistGridExpanded by rememberPreference(playlistGridExpandedKey, false)
|
||||
|
@ -137,7 +128,7 @@ fun HomeScreen() {
|
|||
SettingsScreen()
|
||||
}
|
||||
|
||||
playlistRoute { playlistId ->
|
||||
localPlaylistRoute { playlistId ->
|
||||
LocalPlaylistScreen(
|
||||
playlistId = playlistId ?: error("playlistId cannot be null")
|
||||
)
|
||||
|
@ -520,7 +511,7 @@ fun HomeScreen() {
|
|||
.clickable(
|
||||
indication = rememberRipple(bounded = true),
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
onClick = { playlistRoute(playlistPreview.playlist.id) }
|
||||
onClick = { localPlaylistRoute(playlistPreview.playlist.id) }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -54,8 +54,6 @@ import kotlinx.coroutines.withContext
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun IntentUriScreen(uri: Uri) {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
|
@ -98,17 +96,7 @@ fun IntentUriScreen(uri: Uri) {
|
|||
}
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val menuState = LocalMenuState.current
|
||||
|
|
|
@ -65,30 +65,15 @@ import kotlinx.coroutines.flow.map
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun LocalPlaylistScreen(
|
||||
playlistId: Long,
|
||||
) {
|
||||
fun LocalPlaylistScreen(playlistId: Long) {
|
||||
val playlistWithSongs by remember(playlistId) {
|
||||
Database.playlistWithSongs(playlistId).map { it ?: PlaylistWithSongs.NotFound }
|
||||
}.collectAsState(initial = PlaylistWithSongs.Empty, context = Dispatchers.IO)
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val hapticFeedback = LocalHapticFeedback.current
|
||||
|
|
|
@ -75,26 +75,11 @@ import kotlinx.coroutines.withContext
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun PlaylistScreen(
|
||||
browseId: String,
|
||||
) {
|
||||
fun PlaylistScreen(browseId: String) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val context = LocalContext.current
|
||||
|
|
|
@ -1,104 +1,45 @@
|
|||
package it.vfsfitvnm.vimusic.ui.screens
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.net.Uri
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import it.vfsfitvnm.route.Route0
|
||||
import it.vfsfitvnm.route.Route1
|
||||
import it.vfsfitvnm.route.RouteHandlerScope
|
||||
import it.vfsfitvnm.vimusic.enums.BuiltInPlaylist
|
||||
|
||||
@Composable
|
||||
fun rememberIntentUriRoute(): Route1<Uri?> {
|
||||
val uri = rememberSaveable {
|
||||
mutableStateOf<Uri?>(null)
|
||||
}
|
||||
return remember {
|
||||
Route1("IntentUriRoute", uri)
|
||||
}
|
||||
}
|
||||
val aboutRoute = Route0("aboutRoute")
|
||||
val albumRoute = Route1<String?>("albumRoute")
|
||||
val appearanceSettingsRoute = Route0("appearanceSettingsRoute")
|
||||
val artistRoute = Route1<String?>("artistRoute")
|
||||
val backupAndRestoreRoute = Route0("backupAndRestoreRoute")
|
||||
val builtInPlaylistRoute = Route1<BuiltInPlaylist>("builtInPlaylistRoute")
|
||||
val cacheSettingsRoute = Route0("cacheSettingsRoute")
|
||||
val intentUriRoute = Route1<Uri?>("intentUriRoute")
|
||||
val localPlaylistRoute = Route1<Long?>("localPlaylistRoute")
|
||||
val otherSettingsRoute = Route0("otherSettingsRoute")
|
||||
val playerSettingsRoute = Route0("playerSettingsRoute")
|
||||
val playlistRoute = Route1<String?>("playlistRoute")
|
||||
val searchResultRoute = Route1<String>("searchResultRoute")
|
||||
val searchRoute = Route1<String>("searchRoute")
|
||||
val settingsRoute = Route0("settingsRoute")
|
||||
val viewPlaylistsRoute = Route0("createPlaylistRoute")
|
||||
|
||||
@SuppressLint("ComposableNaming")
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun rememberPlaylistRoute(): Route1<String?> {
|
||||
val browseId = rememberSaveable {
|
||||
mutableStateOf<String?>(null)
|
||||
inline fun RouteHandlerScope.globalRoutes() {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
return remember {
|
||||
Route1("PlaylistRoute", browseId)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberAlbumRoute(): Route1<String?> {
|
||||
val browseId = rememberSaveable {
|
||||
mutableStateOf<String?>(null)
|
||||
}
|
||||
return remember {
|
||||
Route1("AlbumRoute", browseId)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberArtistRoute(): Route1<String?> {
|
||||
val browseId = rememberSaveable {
|
||||
mutableStateOf<String?>(null)
|
||||
}
|
||||
return remember {
|
||||
Route1("ArtistRoute", browseId)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberLocalPlaylistRoute(): Route1<Long?> {
|
||||
val playlistId = rememberSaveable {
|
||||
mutableStateOf<Long?>(null)
|
||||
}
|
||||
return remember {
|
||||
Route1("LocalPlaylistRoute", playlistId)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberBuiltInPlaylistRoute(): Route1<BuiltInPlaylist> {
|
||||
val playlistType = rememberSaveable {
|
||||
mutableStateOf(BuiltInPlaylist.Favorites)
|
||||
}
|
||||
return remember {
|
||||
Route1("BuiltInPlaylistRoute", playlistType)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberSearchRoute(): Route1<String> {
|
||||
val initialTextInput = remember {
|
||||
mutableStateOf("")
|
||||
}
|
||||
return remember {
|
||||
Route1("SearchRoute", initialTextInput)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberCreatePlaylistRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("CreatePlaylistRoute")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberSearchResultRoute(): Route1<String> {
|
||||
val searchQuery = rememberSaveable {
|
||||
mutableStateOf("")
|
||||
}
|
||||
return remember {
|
||||
Route1("SearchResultRoute", searchQuery)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberSettingsRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("SettingsRoute")
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,10 +71,7 @@ import kotlinx.coroutines.withContext
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun SearchResultScreen(
|
||||
query: String,
|
||||
onSearchAgain: () -> Unit,
|
||||
) {
|
||||
fun SearchResultScreen(query: String, onSearchAgain: () -> Unit) {
|
||||
val (colorPalette, typography) = LocalAppearance.current
|
||||
val binder = LocalPlayerServiceBinder.current
|
||||
|
||||
|
@ -107,10 +104,6 @@ fun SearchResultScreen(
|
|||
|
||||
val thumbnailSizePx = Dimensions.thumbnails.song.px
|
||||
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val playlistRoute = rememberPlaylistRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
|
@ -118,14 +111,14 @@ fun SearchResultScreen(
|
|||
)
|
||||
}
|
||||
|
||||
playlistRoute { browseId ->
|
||||
PlaylistScreen(
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: "browseId cannot be null"
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
playlistRoute { browseId ->
|
||||
PlaylistScreen(
|
||||
browseId = browseId ?: "browseId cannot be null"
|
||||
)
|
||||
}
|
||||
|
|
|
@ -69,26 +69,9 @@ import kotlinx.coroutines.withContext
|
|||
|
||||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun SearchScreen(
|
||||
initialTextInput: String,
|
||||
onSearch: (String) -> Unit,
|
||||
onUri: (Uri) -> Unit,
|
||||
) {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
fun SearchScreen(initialTextInput: String, onSearch: (String) -> Unit, onUri: (Uri) -> Unit) {
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val (colorPalette, typography) = LocalAppearance.current
|
||||
|
|
|
@ -29,15 +29,6 @@ import it.vfsfitvnm.vimusic.utils.*
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun SettingsScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
val appearanceSettingsRoute = rememberAppearanceSettingsRoute()
|
||||
val playerSettingsRoute = rememberPlayerSettingsRoute()
|
||||
val backupAndRestoreRoute = rememberBackupAndRestoreRoute()
|
||||
val cacheSettingsRoute = rememberCacheSettingsRoute()
|
||||
val otherSettingsRoute = rememberOtherSettingsRoute()
|
||||
val aboutRoute = rememberAboutRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(
|
||||
|
@ -53,17 +44,7 @@ fun SettingsScreen() {
|
|||
}
|
||||
}
|
||||
) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
appearanceSettingsRoute {
|
||||
AppearanceSettingsScreen()
|
||||
|
|
|
@ -27,10 +27,7 @@ import it.vfsfitvnm.route.RouteHandler
|
|||
import it.vfsfitvnm.vimusic.BuildConfig
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.screens.AlbumScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.bold
|
||||
import it.vfsfitvnm.vimusic.utils.secondary
|
||||
|
@ -39,23 +36,10 @@ import it.vfsfitvnm.vimusic.utils.semiBold
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun AboutScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val (colorPalette, typography) = LocalAppearance.current
|
||||
|
|
|
@ -25,12 +25,9 @@ import it.vfsfitvnm.vimusic.R
|
|||
import it.vfsfitvnm.vimusic.enums.ColorPaletteMode
|
||||
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.screens.AlbumScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.EnumValueSelectorSettingsEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.colorPaletteModeKey
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
|
@ -40,23 +37,11 @@ import it.vfsfitvnm.vimusic.utils.thumbnailRoundnessKey
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun AppearanceSettingsScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val (colorPalette, typography) = LocalAppearance.current
|
||||
|
|
|
@ -43,10 +43,7 @@ import it.vfsfitvnm.vimusic.service.PlayerService
|
|||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.ConfirmationDialog
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
|
||||
import it.vfsfitvnm.vimusic.ui.screens.AlbumScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.intent
|
||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||
|
@ -59,23 +56,11 @@ import kotlin.system.exitProcess
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun BackupAndRestoreScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val (colorPalette, typography) = LocalAppearance.current
|
||||
|
|
|
@ -35,14 +35,11 @@ import it.vfsfitvnm.vimusic.enums.CoilDiskCacheMaxSize
|
|||
import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
|
||||
import it.vfsfitvnm.vimusic.ui.screens.AlbumScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.DisabledSettingsEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.EnumValueSelectorSettingsEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.coilDiskCacheMaxSizeKey
|
||||
import it.vfsfitvnm.vimusic.utils.exoPlayerDiskCacheMaxSizeKey
|
||||
|
@ -55,23 +52,11 @@ import kotlinx.coroutines.launch
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun CacheSettingsScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val context = LocalContext.current
|
||||
|
|
|
@ -35,13 +35,10 @@ import it.vfsfitvnm.route.RouteHandler
|
|||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
|
||||
import it.vfsfitvnm.vimusic.ui.screens.AlbumScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SwitchSettingEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.isIgnoringBatteryOptimizations
|
||||
import it.vfsfitvnm.vimusic.utils.isInvincibilityEnabledKey
|
||||
|
@ -51,23 +48,11 @@ import it.vfsfitvnm.vimusic.utils.semiBold
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun OtherSettingsScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val context = LocalContext.current
|
||||
|
|
|
@ -30,13 +30,10 @@ import it.vfsfitvnm.route.RouteHandler
|
|||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||
import it.vfsfitvnm.vimusic.R
|
||||
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
|
||||
import it.vfsfitvnm.vimusic.ui.screens.AlbumScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.ArtistScreen
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SettingsEntryGroupText
|
||||
import it.vfsfitvnm.vimusic.ui.screens.SwitchSettingEntry
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberAlbumRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.rememberArtistRoute
|
||||
import it.vfsfitvnm.vimusic.ui.screens.globalRoutes
|
||||
import it.vfsfitvnm.vimusic.ui.styling.LocalAppearance
|
||||
import it.vfsfitvnm.vimusic.utils.persistentQueueKey
|
||||
import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||
|
@ -47,23 +44,11 @@ import it.vfsfitvnm.vimusic.utils.volumeNormalizationKey
|
|||
@ExperimentalAnimationApi
|
||||
@Composable
|
||||
fun PlayerSettingsScreen() {
|
||||
val albumRoute = rememberAlbumRoute()
|
||||
val artistRoute = rememberArtistRoute()
|
||||
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
RouteHandler(listenToGlobalEmitter = true) {
|
||||
albumRoute { browseId ->
|
||||
AlbumScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
|
||||
artistRoute { browseId ->
|
||||
ArtistScreen(
|
||||
browseId = browseId ?: error("browseId cannot be null")
|
||||
)
|
||||
}
|
||||
globalRoutes()
|
||||
|
||||
host {
|
||||
val context = LocalContext.current
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
package it.vfsfitvnm.vimusic.ui.screens.settings
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import it.vfsfitvnm.route.Route0
|
||||
|
||||
@Composable
|
||||
fun rememberAppearanceSettingsRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("AppearanceSettingsRoute")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberPlayerSettingsRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("PlayerSettingsRoute")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberBackupAndRestoreRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("BackupAndRestoreRoute")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberCacheSettingsRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("CacheSettingsRoute")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberOtherSettingsRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("OtherSettingsRoute")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberAboutRoute(): Route0 {
|
||||
return remember {
|
||||
Route0("AboutRoute")
|
||||
}
|
||||
}
|
|
@ -1,10 +1,15 @@
|
|||
@file:Suppress("UNCHECKED_CAST")
|
||||
|
||||
package it.vfsfitvnm.route
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.SaverScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
|
||||
@Stable
|
||||
@Immutable
|
||||
open class Route internal constructor(val tag: String) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return when {
|
||||
|
@ -19,7 +24,7 @@ open class Route internal constructor(val tag: String) {
|
|||
}
|
||||
|
||||
object GlobalEmitter {
|
||||
var listener: ((Route) -> Unit)? = null
|
||||
var listener: ((Route, Array<Any?>) -> Unit)? = null
|
||||
}
|
||||
|
||||
object Saver : androidx.compose.runtime.saveable.Saver<Route?, String> {
|
||||
|
@ -35,10 +40,8 @@ fun rememberRoute(route: Route? = null): MutableState<Route?> {
|
|||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
class Route0(
|
||||
tag: String
|
||||
) : Route(tag) {
|
||||
@Immutable
|
||||
class Route0(tag: String) : Route(tag) {
|
||||
context(RouteHandlerScope)
|
||||
@Composable
|
||||
operator fun invoke(content: @Composable () -> Unit) {
|
||||
|
@ -48,64 +51,36 @@ class Route0(
|
|||
}
|
||||
|
||||
fun global() {
|
||||
GlobalEmitter.listener?.invoke(this)
|
||||
GlobalEmitter.listener?.invoke(this, emptyArray())
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
class Route1<P0>(
|
||||
tag: String,
|
||||
state0: MutableState<P0>
|
||||
) : Route(tag) {
|
||||
var p0 by state0
|
||||
|
||||
@Immutable
|
||||
class Route1<P0>(tag: String) : Route(tag) {
|
||||
context(RouteHandlerScope)
|
||||
@Composable
|
||||
operator fun invoke(content: @Composable (P0) -> Unit) {
|
||||
if (this == route) {
|
||||
if (route is Route1<*>) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(route as Route1<P0>).let { route ->
|
||||
this.p0 = route.p0
|
||||
}
|
||||
}
|
||||
content(this.p0)
|
||||
content(parameters[0] as P0)
|
||||
}
|
||||
}
|
||||
|
||||
fun global(p0: P0 = this.p0) {
|
||||
this.p0 = p0
|
||||
GlobalEmitter.listener?.invoke(this)
|
||||
fun global(p0: P0) {
|
||||
GlobalEmitter.listener?.invoke(this, arrayOf(p0))
|
||||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
class Route2<P0, P1>(
|
||||
tag: String,
|
||||
state0: MutableState<P0>,
|
||||
state1: MutableState<P1>
|
||||
) : Route(tag) {
|
||||
var p0 by state0
|
||||
var p1 by state1
|
||||
|
||||
@Immutable
|
||||
class Route2<P0, P1>(tag: String) : Route(tag) {
|
||||
context(RouteHandlerScope)
|
||||
@Composable
|
||||
operator fun invoke(content: @Composable (P0, P1) -> Unit) {
|
||||
if (this == route) {
|
||||
if (route is Route2<*, *>) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(route as Route2<P0, P1>).let { route ->
|
||||
this.p0 = route.p0
|
||||
this.p1 = route.p1
|
||||
}
|
||||
}
|
||||
content(this.p0, this.p1)
|
||||
content(parameters[0] as P0, parameters[1] as P1)
|
||||
}
|
||||
}
|
||||
|
||||
fun global(p0: P0 = this.p0, p1: P1 = this.p1) {
|
||||
this.p0 = p0
|
||||
this.p1 = p1
|
||||
GlobalEmitter.listener?.invoke(this)
|
||||
fun global(p0: P0, p1: P1) {
|
||||
GlobalEmitter.listener?.invoke(this, arrayOf(p0, p1))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,12 @@ import androidx.compose.animation.AnimatedContentScope
|
|||
import androidx.compose.animation.ContentTransform
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.animation.core.updateTransition
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
|
@ -45,9 +50,14 @@ fun RouteHandler(
|
|||
) {
|
||||
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
|
||||
|
||||
val parameters = rememberSaveable {
|
||||
arrayOfNulls<Any?>(2)
|
||||
}
|
||||
|
||||
val scope = remember(route) {
|
||||
RouteHandlerScope(
|
||||
route = route,
|
||||
parameters = parameters,
|
||||
push = onRouteChanged,
|
||||
pop = { if (handleBackPress) backDispatcher?.onBackPressed() else onRouteChanged(null) }
|
||||
)
|
||||
|
@ -55,7 +65,10 @@ fun RouteHandler(
|
|||
|
||||
if (listenToGlobalEmitter) {
|
||||
LaunchedEffect(route) {
|
||||
Route.GlobalEmitter.listener = if (route == null) onRouteChanged else null
|
||||
Route.GlobalEmitter.listener = if (route == null) ({ newRoute, newParameters ->
|
||||
newParameters.forEachIndexed(parameters::set)
|
||||
onRouteChanged(newRoute)
|
||||
}) else null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +78,7 @@ fun RouteHandler(
|
|||
|
||||
updateTransition(targetState = scope, label = null).AnimatedContent(
|
||||
transitionSpec = transitionSpec,
|
||||
contentKey = { it.route?.tag },
|
||||
contentKey = RouteHandlerScope::route,
|
||||
modifier = modifier,
|
||||
) {
|
||||
it.content()
|
||||
|
|
|
@ -2,11 +2,12 @@ package it.vfsfitvnm.route
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
|
||||
@Immutable
|
||||
@Stable
|
||||
class RouteHandlerScope(
|
||||
val route: Route?,
|
||||
val parameters: Array<Any?>,
|
||||
private val push: (Route?) -> Unit,
|
||||
val pop: () -> Unit,
|
||||
) {
|
||||
|
@ -18,23 +19,17 @@ class RouteHandlerScope(
|
|||
}
|
||||
}
|
||||
|
||||
operator fun Route0.invoke() {
|
||||
operator fun Route.invoke() {
|
||||
push(this)
|
||||
}
|
||||
|
||||
operator fun <P0> Route1<P0>.invoke(
|
||||
p0: P0 = this.p0
|
||||
) {
|
||||
this.p0 = p0
|
||||
push(this)
|
||||
operator fun <P0> Route.invoke(p0: P0) {
|
||||
parameters[0] = p0
|
||||
invoke()
|
||||
}
|
||||
|
||||
operator fun <P0, P1> Route2<P0, P1>.invoke(
|
||||
p0: P0 = this.p0,
|
||||
p1: P1 = this.p1
|
||||
) {
|
||||
this.p0 = p0
|
||||
this.p1 = p1
|
||||
push(this)
|
||||
operator fun <P0, P1> Route.invoke(p0: P0, p1: P1) {
|
||||
parameters[1] = p1
|
||||
invoke(p0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
package it.vfsfitvnm.route
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.AnimatedContentScope
|
||||
import androidx.compose.animation.ContentTransform
|
||||
import androidx.compose.animation.EnterTransition
|
||||
import androidx.compose.animation.ExitTransition
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.animation.core.tween
|
||||
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.with
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
val AnimatedContentScope<RouteHandlerScope>.leftSlide: ContentTransform
|
||||
|
|
Loading…
Reference in a new issue