package at.lockstep.player.ui import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.IBinder import androidx.activity.ComponentActivity import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.core.content.ContextCompat import androidx.navigation.NavHostController import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.navArgument import at.lockstep.jukebox.PlaylistSummary import at.lockstep.player.LockstepViewModel import at.lockstep.player.playback.PlaybackService import at.lockstep.player.ui.library.LibraryScreen import at.lockstep.player.ui.navigation.Routes import at.lockstep.player.ui.pairing.PairingScreen import at.lockstep.player.ui.settings.SettingsScreen @Composable fun LockstepAppNavHost( activity: ComponentActivity, navController: NavHostController, viewModel: LockstepViewModel, ) { var playback by remember { mutableStateOf(null) } DisposableEffect(Unit) { val connection = object : ServiceConnection { override fun onServiceConnected( name: ComponentName?, binder: IBinder?, ) { playback = (binder as PlaybackService.LocalBinder).getService() } override fun onServiceDisconnected(name: ComponentName?) { playback = null } } activity.bindService( Intent(activity, PlaybackService::class.java), connection, Context.BIND_AUTO_CREATE, ) onDispose { activity.unbindService(connection) } } NavHost( navController = navController, startDestination = Routes.Library, ) { composable(Routes.Library) { LibraryScreen( viewModel = viewModel, onPlaylistSelected = { playlist: PlaylistSummary, hasPaired -> if (!hasPaired) { navController.navigate(Routes.pairing(playlist.id)) } else { startPlaylistPlayback(activity, playlist.id) navController.navigate(Routes.nowPlaying(playlist.id)) } }, onOpenSettings = { navController.navigate(Routes.Settings) }, ) } composable(Routes.Settings) { SettingsScreen( onBack = { navController.popBackStack() }, ) } composable( route = Routes.Pairing, arguments = listOf( navArgument("playlistId") { type = NavType.StringType }, ), ) { entry -> val playlistId = entry.arguments?.getString("playlistId").orEmpty() PairingScreen( playlistId = playlistId, viewModel = viewModel, onBack = { navController.popBackStack() }, ) } composable( route = Routes.NowPlaying, arguments = listOf( navArgument("playlistId") { type = NavType.StringType }, ), ) { entry -> val playlistId = entry.arguments?.getString("playlistId").orEmpty() NowPlayingRoute( playlistId = playlistId, playback = playback, onBack = { navController.popBackStack() }, ) } } } private fun startPlaylistPlayback( context: Context, playlistId: String, ) { ContextCompat.startForegroundService( context, Intent(context, PlaybackService::class.java).apply { action = PlaybackService.ACTION_START_PLAYLIST putExtra(PlaybackService.EXTRA_PLAYLIST_ID, playlistId) }, ) }