refactor: put navigation logic into main view

This commit is contained in:
Fritz Heiden 2025-04-06 16:32:29 +02:00
parent c6f3a0b0f9
commit c0a86c5635
4 changed files with 112 additions and 91 deletions

View File

@ -5,24 +5,8 @@ import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.core.app.ActivityCompat
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.example.tvcontroller.client.WebClient
import com.example.tvcontroller.client.WebsocketClient
import com.example.tvcontroller.services.BluetoothService
@ -31,9 +15,7 @@ import com.example.tvcontroller.services.ControllerService
import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.services.webrtc.WebRtcService
import com.example.tvcontroller.ui.theme.TVControllerTheme
import com.example.tvcontroller.ui.views.CameraView
import com.example.tvcontroller.ui.views.RemoteView
import com.example.tvcontroller.ui.views.SettingsView
import com.example.tvcontroller.ui.views.MainView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -77,7 +59,7 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
setContent {
TVControllerTheme {
TvControllerApp(
MainView(
deviceService = deviceService,
controllerService = controllerService,
bluetoothService = bluetoothService,
@ -101,67 +83,3 @@ class MainActivity : ComponentActivity() {
}
}
@Composable
fun TvControllerApp(
navController: NavHostController = rememberNavController(),
deviceService: DeviceService,
controllerService: ControllerService,
bluetoothService: BluetoothService,
webRtcService: WebRtcService,
cameraService: CameraService
) {
val backStackEntry by navController.currentBackStackEntryAsState()
val currentScreen = Screen.valueOf(backStackEntry?.destination?.route ?: Screen.Camera.name)
val baselineCamera24 = painterResource(R.drawable.baseline_camera_24)
val baselineRemote24 = painterResource(R.drawable.baseline_settings_remote_24)
val baselineSettings24 = painterResource(R.drawable.baseline_settings_24)
Scaffold(modifier = Modifier.fillMaxSize(), bottomBar = {
NavigationBar {
NavigationBarItem(
onClick = { navController.navigate(Screen.Camera.name) }, icon = {
Icon(
baselineCamera24, contentDescription = "Camera"
)
}, label = { Text("Camera") }, selected = currentScreen == Screen.Camera
)
NavigationBarItem(
onClick = { navController.navigate(Screen.Remote.name) }, icon = {
Icon(
baselineRemote24, contentDescription = "Remote"
)
}, label = { Text("Remote") }, selected = currentScreen == Screen.Remote
)
NavigationBarItem(
onClick = { navController.navigate(Screen.Settings.name) }, icon = {
Icon(
baselineSettings24, contentDescription = "Settings"
)
}, label = { Text("Settings") }, selected = currentScreen == Screen.Settings
)
}
}) { innerPadding ->
NavHost(
navController = navController,
startDestination = Screen.Settings.name,
modifier = Modifier.padding(innerPadding)
) {
composable(route = Screen.Camera.name) {
CameraView(
eglBaseContext = cameraService.eglBaseContext,
videoTrack = webRtcService.videoTrack
)
}
composable(route = Screen.Remote.name) {
RemoteView(
controllerService = controllerService
)
}
composable(route = Screen.Settings.name) {
SettingsView(
deviceService = deviceService, bluetoothService = bluetoothService
)
}
}
}
}

View File

@ -1,7 +0,0 @@
package com.example.tvcontroller
enum class Screen {
Camera,
Remote,
Settings
}

View File

@ -0,0 +1,96 @@
package com.example.tvcontroller.ui.views
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.example.tvcontroller.R
import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.CameraService
import com.example.tvcontroller.services.ControllerService
import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.services.webrtc.WebRtcService
import com.example.tvcontroller.ui.views.MainViewModel.Companion.CAMERA_VIEW
import com.example.tvcontroller.ui.views.MainViewModel.Companion.REMOTE_VIEW
import com.example.tvcontroller.ui.views.MainViewModel.Companion.SETTINGS_VIEW
@Composable
fun MainView(
deviceService: DeviceService,
controllerService: ControllerService,
bluetoothService: BluetoothService,
webRtcService: WebRtcService,
cameraService: CameraService
) {
val viewModel = viewModel<MainViewModel>()
val navController = rememberNavController()
val backStackEntry by navController.currentBackStackEntryAsState()
val currentView = backStackEntry?.destination?.route
val baselineCamera24 = painterResource(R.drawable.baseline_camera_24)
val baselineRemote24 = painterResource(R.drawable.baseline_settings_remote_24)
val baselineSettings24 = painterResource(R.drawable.baseline_settings_24)
Scaffold(modifier = Modifier.fillMaxSize(), bottomBar = {
NavigationBar {
NavigationBarItem(
onClick = { navController.navigate(CAMERA_VIEW) }, icon = {
Icon(
baselineCamera24, contentDescription = "Camera"
)
}, label = { Text("Camera") }, selected = currentView == CAMERA_VIEW
)
NavigationBarItem(
onClick = { navController.navigate(REMOTE_VIEW) }, icon = {
Icon(
baselineRemote24, contentDescription = "Remote"
)
}, label = { Text("Remote") }, selected = currentView == REMOTE_VIEW
)
NavigationBarItem(
onClick = { navController.navigate(SETTINGS_VIEW) },
icon = {
Icon(
baselineSettings24, contentDescription = "Settings"
)
},
label = { Text("Settings") },
selected = currentView == SETTINGS_VIEW
)
}
}) { innerPadding ->
NavHost(
navController = navController,
startDestination = viewModel.currentView.value,
modifier = Modifier.padding(innerPadding)
) {
composable(route = CAMERA_VIEW) {
CameraView(
eglBaseContext = cameraService.eglBaseContext,
videoTrack = webRtcService.videoTrack
)
}
composable(route = REMOTE_VIEW) {
RemoteView(
controllerService = controllerService
)
}
composable(route = SETTINGS_VIEW) {
SettingsView(
deviceService = deviceService, bluetoothService = bluetoothService
)
}
}
}
}

View File

@ -0,0 +1,14 @@
package com.example.tvcontroller.ui.views
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
var currentView = mutableStateOf(CAMERA_VIEW)
companion object {
const val CAMERA_VIEW = "camera_view"
const val REMOTE_VIEW = "remote_view"
const val SETTINGS_VIEW = "settings_view"
}
}