diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/BottomNavBar.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/BottomNavBar.kt deleted file mode 100644 index f11b7128..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/BottomNavBar.kt +++ /dev/null @@ -1,92 +0,0 @@ -package com.rtbishop.look4sat.presentation - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.navigation.NavController -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.rtbishop.look4sat.R -import com.rtbishop.look4sat.presentation.entriesScreen.EntriesScreen -import com.rtbishop.look4sat.presentation.mapScreen.MapScreen -import com.rtbishop.look4sat.presentation.passesScreen.PassesScreen -import com.rtbishop.look4sat.presentation.passesScreen.PassesViewModel -import com.rtbishop.look4sat.presentation.radarScreen.RadarScreen -import com.rtbishop.look4sat.presentation.settingsScreen.SettingsScreen - -sealed class BottomNavItem(var title: String, var icon: Int, var screen_route: String) { - object Satellites : BottomNavItem("Satellites", R.drawable.ic_satellite, "satellites") - object Passes : BottomNavItem("Passes", R.drawable.ic_list, "passes") - object Radar : BottomNavItem("Radar", R.drawable.ic_radar, "radar") - object WorldMap : BottomNavItem("World Map", R.drawable.ic_world, "world_map") - object Settings : BottomNavItem("Settings", R.drawable.ic_settings, "settings") -} - -@Composable -fun BottomNavBar(navController: NavController) { - val items = listOf( - BottomNavItem.Satellites, - BottomNavItem.Passes, - BottomNavItem.Radar, - BottomNavItem.WorldMap, - BottomNavItem.Settings - ) - NavigationBar(modifier = Modifier.height(48.dp)) { - val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentRoute = navBackStackEntry?.destination?.route - items.forEach { item -> - NavigationBarItem(selected = currentRoute == item.screen_route, onClick = { - navController.navigate(item.screen_route) { - navController.graph.startDestinationRoute?.let { screen_route -> - popUpTo(screen_route) { saveState = false } - } - launchSingleTop = true - restoreState = false - } - }, icon = { Icon(painterResource(id = item.icon), contentDescription = item.title) }) - } - } -} - -@Composable -fun NavigationGraph(navController: NavHostController) { - val navToPasses = { navController.navigate(BottomNavItem.Passes.screen_route) } - val navToRadar = { navController.navigate(BottomNavItem.Radar.screen_route) } - val passesViewModel: PassesViewModel = hiltViewModel() - NavHost(navController, startDestination = BottomNavItem.Passes.screen_route) { - composable(BottomNavItem.Satellites.screen_route) { - EntriesScreen(navToPasses, passesViewModel = passesViewModel) - } - composable(BottomNavItem.Passes.screen_route) { - PassesScreen(navToRadar, viewModel = passesViewModel) - } - composable(BottomNavItem.Radar.screen_route) { RadarScreen() } - composable(BottomNavItem.WorldMap.screen_route) { MapScreen() } - composable(BottomNavItem.Settings.screen_route) { SettingsScreen() } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MainScreenView(navController: NavHostController = rememberNavController()) { - Scaffold(bottomBar = { BottomNavBar(navController = navController) }) { innerPadding -> - Box(modifier = Modifier.padding(innerPadding)) { NavigationGraph(navController) } - } -} - -@Preview(showBackground = true) -@Composable -fun DefaultPreview() { - MainTheme { MainScreenView() } -} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt index 6020c3ec..714dc738 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt @@ -24,7 +24,27 @@ import android.content.res.Configuration import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.navigation.NavController +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.rtbishop.look4sat.R +import com.rtbishop.look4sat.presentation.entriesScreen.EntriesScreen +import com.rtbishop.look4sat.presentation.mapScreen.MapScreen +import com.rtbishop.look4sat.presentation.passesScreen.PassesScreen +import com.rtbishop.look4sat.presentation.radarScreen.RadarScreen +import com.rtbishop.look4sat.presentation.settingsScreen.SettingsScreen import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -35,7 +55,7 @@ class MainActivity : ComponentActivity() { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT installSplashScreen() super.onCreate(savedInstanceState) - setContent { MainTheme { MainScreenView() } } + setContent { MainTheme { MainScreen() } } } override fun attachBaseContext(newBase: Context?) { @@ -45,3 +65,50 @@ class MainActivity : ComponentActivity() { super.attachBaseContext(newBase) } } + +sealed class Screen(var title: String, var icon: Int, var route: String) { + object Entries : Screen("Entries", R.drawable.ic_entries, "entries") + object Passes : Screen("Passes", R.drawable.ic_passes, "passes") + object Radar : Screen("Radar", R.drawable.ic_radar, "radar") + object Map : Screen("World Map", R.drawable.ic_world_map, "world_map") + object Settings : Screen("Settings", R.drawable.ic_settings, "settings") +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun MainScreen(navController: NavHostController = rememberNavController()) { + Scaffold(bottomBar = { MainNavBar(navController = navController) }) { innerPadding -> + Box(modifier = Modifier.padding(innerPadding)) { MainNavGraph(navController) } + } +} + +@Composable +private fun MainNavBar(navController: NavController) { + val items = listOf(Screen.Entries, Screen.Passes, Screen.Radar, Screen.Map, Screen.Settings) + NavigationBar(modifier = Modifier.height(48.dp)) { + val navBackStackEntry = navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry.value?.destination?.route + items.forEach { item -> + NavigationBarItem(selected = currentRoute == item.route, onClick = { + navController.navigate(item.route) { + navController.graph.startDestinationRoute?.let { route -> + popUpTo(route) { saveState = false } + } + launchSingleTop = true + restoreState = false + } + }, icon = { Icon(painterResource(id = item.icon), contentDescription = item.title) }) + } + } +} + +@Composable +private fun MainNavGraph(navController: NavHostController) { + NavHost(navController, startDestination = Screen.Passes.route) { + composable(Screen.Entries.route) { EntriesScreen(navController) } + composable(Screen.Passes.route) { PassesScreen(navController) } + composable(Screen.Radar.route) { RadarScreen() } + composable(Screen.Map.route) { MapScreen() } + composable(Screen.Settings.route) { SettingsScreen(navController) } + } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt index 75df32a8..ffcf1f5d 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainComponents.kt @@ -3,6 +3,7 @@ package com.rtbishop.look4sat.presentation import android.content.Context import android.content.Intent import android.net.Uri +import android.widget.Toast import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.tween @@ -68,6 +69,10 @@ fun RadarPing() { ) } +fun showToast(context: Context, message: String) { + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() +} + fun gotoUrl(context: Context, url: String) { context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesScreen.kt index 4c63e4d7..82b60b5d 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesScreen.kt @@ -26,21 +26,20 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.model.SatItem +import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.CardLoadingIndicator import com.rtbishop.look4sat.presentation.MainTheme import com.rtbishop.look4sat.presentation.onClick -import com.rtbishop.look4sat.presentation.passesScreen.PassesViewModel @Composable -fun EntriesScreen( - navToPasses: () -> Unit, - viewModel: EntriesViewModel = hiltViewModel(), - passesViewModel: PassesViewModel = hiltViewModel() -) { +fun EntriesScreen(navController: NavController) { + val viewModel: EntriesViewModel = hiltViewModel() val state = viewModel.satData.collectAsState(initial = DataState.Loading) + val navToPasses = { navController.navigate(Screen.Passes.route) } val showDialog = rememberSaveable { mutableStateOf(false) } val toggleDialog = { showDialog.value = showDialog.value.not() } @@ -54,8 +53,7 @@ fun EntriesScreen( val selectAll = { viewModel.selectCurrentItems(true) } Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) { TopBar(setQuery = { newQuery: String -> viewModel.setQuery(newQuery) }, saveSelection = { - val entries = viewModel.saveSelection() - passesViewModel.calculatePasses(selection = entries) + viewModel.saveSelection() navToPasses() }) Row(horizontalArrangement = Arrangement.spacedBy(6.dp), modifier = Modifier.height(48.dp)) { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt index 92781e5f..92e40d99 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/entriesScreen/EntriesViewModel.kt @@ -20,6 +20,7 @@ package com.rtbishop.look4sat.presentation.entriesScreen import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.rtbishop.look4sat.domain.IDataRepository +import com.rtbishop.look4sat.domain.ISatelliteManager import com.rtbishop.look4sat.domain.ISettingsManager import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.model.SatItem @@ -34,19 +35,17 @@ import javax.inject.Inject @OptIn(ExperimentalCoroutinesApi::class) @HiltViewModel class EntriesViewModel @Inject constructor( - private val repository: IDataRepository, private val settings: ISettingsManager + private val satelliteManager: ISatelliteManager, + private val repository: IDataRepository, + private val settings: ISettingsManager ) : ViewModel() { private val satType = MutableStateFlow("All") -// private val transModes = MutableLiveData(settings.loadModesSelection()) private val currentQuery = MutableStateFlow(String()) private val itemsFromRepo = MutableStateFlow>(emptyList()) private val itemsWithType = satType.flatMapLatest { type -> itemsFromRepo.map { items -> filterByType(items, type) } } -// private val itemsWithModes = transModes.switchMap { modes -> -// itemsWithType.map { items -> filterByModes(items, modes) } -// } private val itemsWithQuery = currentQuery.flatMapLatest { query -> itemsWithType.map { items -> filterByQuery(items, query) } } @@ -66,26 +65,24 @@ class EntriesViewModel @Inject constructor( satType.value = type } - fun selectCurrentItems(selectAll: Boolean) { - viewModelScope.launch { - val lastValue = itemsWithQuery.last() - updateSelection(lastValue.map { item -> item.catnum }, selectAll) - } + fun selectCurrentItems(selectAll: Boolean) = viewModelScope.launch { + updateSelection(itemsWithQuery.first().map { item -> item.catnum }, selectAll) } -// fun saveSelectedModes(modes: List) { -// transModes.value = modes -// settings.saveModesSelection(modes) -// } - fun setQuery(query: String) { currentQuery.value = query } - fun saveSelection(): List { - return itemsFromRepo.value.let { itemsAll -> - itemsAll.filter { item -> item.isSelected }.map { item -> item.catnum } - } + fun saveSelection() = viewModelScope.launch { + val newSelection = itemsFromRepo.value.filter { it.isSelected }.map { it.catnum } + settings.saveEntriesSelection(newSelection) + val selectedIds = settings.loadEntriesSelection() + val satellites = repository.getEntriesWithIds(selectedIds) + val stationPos = settings.loadStationPosition() + val timeRef = System.currentTimeMillis() + val hoursAhead = settings.getHoursAhead() + val minElev = settings.getMinElevation() + satelliteManager.calculatePasses(satellites, stationPos, timeRef, hoursAhead, minElev) } fun updateSelection(catNums: List, isSelected: Boolean) { @@ -110,11 +107,6 @@ class EntriesViewModel @Inject constructor( return items.filter { item -> item.catnum in catnums } } -// private fun filterByModes(items: List, modes: List): List { -// if (modes.isEmpty()) return items -// return items.filter { item -> item.modes.any { mode -> mode in modes } } -// } - private fun filterByQuery(items: List, query: String): List { if (query.isBlank()) return items return try { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesScreen.kt index 0bbcb6b2..e07c4f7b 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesScreen.kt @@ -21,11 +21,13 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.* import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController import com.rtbishop.look4sat.R import com.rtbishop.look4sat.domain.model.DataState import com.rtbishop.look4sat.domain.predict.NearEarthSat import com.rtbishop.look4sat.domain.predict.OrbitalData import com.rtbishop.look4sat.domain.predict.SatPass +import com.rtbishop.look4sat.presentation.Screen import com.rtbishop.look4sat.presentation.MainTheme import com.rtbishop.look4sat.presentation.pullRefresh.PullRefreshIndicator import com.rtbishop.look4sat.presentation.pullRefresh.PullRefreshState @@ -37,7 +39,9 @@ import java.util.* private val sdf = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH) @Composable -fun PassesScreen(navToRadar: () -> Unit, viewModel: PassesViewModel = hiltViewModel()) { +fun PassesScreen(navController: NavController) { + val viewModel: PassesViewModel = hiltViewModel() + val navToRadar = { navController.navigate(Screen.Radar.route) } val state = viewModel.passes.collectAsState(initial = null) val timerText = viewModel.timerText.collectAsState(initial = null) val isRefreshing = state.value is DataState.Loading diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsScreen.kt index c4437e14..03c54ef4 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settingsScreen/SettingsScreen.kt @@ -2,10 +2,7 @@ package com.rtbishop.look4sat.presentation.settingsScreen import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material3.ElevatedCard -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text +import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -14,11 +11,14 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.navigation.NavController import com.rtbishop.look4sat.BuildConfig import com.rtbishop.look4sat.R import com.rtbishop.look4sat.presentation.CardButton +import com.rtbishop.look4sat.presentation.MainTheme import com.rtbishop.look4sat.presentation.gotoUrl private const val POLICY_URL = "https://sites.google.com/view/look4sat-privacy-policy/home" @@ -28,7 +28,7 @@ private const val DONATE_URL = "https://ko-fi.com/rt_bishop" private const val FDROID_URL = "https://f-droid.org/en/packages/com.rtbishop.look4sat/" @Composable -fun SettingsScreen() { +fun SettingsScreen(navController: NavController) { LazyColumn( modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp) ) { @@ -44,7 +44,7 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Row(horizontalArrangement = Arrangement.Center) { Icon( - painter = painterResource(id = R.drawable.ic_satellite), + painter = painterResource(id = R.drawable.ic_entries), tint = MaterialTheme.colorScheme.secondary, contentDescription = null, modifier = Modifier @@ -90,43 +90,102 @@ private fun CardAbout(version: String, modifier: Modifier = Modifier) { } } +@Preview(showBackground = true) @Composable -private fun CardCredits(modifier: Modifier = Modifier) { +private fun LocationCardPreview() { + MainTheme { LocationCard() } +} + +@Composable +private fun LocationCard() { val context = LocalContext.current - ElevatedCard(modifier = modifier.fillMaxWidth()) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text( - text = stringResource(id = R.string.outro_title), - fontSize = 18.sp, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.secondary, - modifier = modifier.padding(8.dp) - ) - Text( - text = stringResource(id = R.string.outro_thanks), - fontSize = 16.sp, - textAlign = TextAlign.Center, - modifier = modifier.padding(horizontal = 6.dp, vertical = 4.dp) - ) - Text( - text = stringResource(id = R.string.outro_license), - fontSize = 18.sp, - fontWeight = FontWeight.Medium, - color = MaterialTheme.colorScheme.secondary, - modifier = modifier.padding(8.dp) - ) + // setPositionText(viewModel.getStationPosition()) + ElevatedCard(modifier = Modifier.fillMaxWidth()) { + Column(modifier = Modifier.padding(4.dp)) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(text = "Station position") + LinearProgressIndicator( + modifier = Modifier + .weight(1f) + .padding(start = 6.dp, end = 6.dp) + ) + } Row( - horizontalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.padding(4.dp) + horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() ) { + Text(text = "Updated: 3 Mar 2023 - 15:51") + Text(text = "QTH: IO91vl") + } + Row( + horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() + ) { + Text(text = "Latitude: *") + Text(text = "Longitude: *") + } + Row(horizontalArrangement = Arrangement.SpaceEvenly) { CardButton( - onClick = { gotoUrl(context, LICENSE_URL) }, - text = stringResource(id = R.string.btn_license), - modifier = Modifier.weight(1f) + onClick = { }, // locationRequest.launch(arrayOf(locationFine, locationCoarse)) + text = stringResource(id = R.string.btn_gps), modifier = Modifier.weight(1f) ) CardButton( - onClick = { gotoUrl(context, POLICY_URL) }, - text = stringResource(id = R.string.btn_privacy), - modifier = Modifier.weight(1f) + onClick = { }, // open Position dialog + text = stringResource(id = R.string.btn_manual), modifier = Modifier.weight(1f) + ) // viewModel.setStationPosition(position.first, position.second) + CardButton( + onClick = { }, // open Locator dialog + text = stringResource(id = R.string.btn_qth), modifier = Modifier.weight(1f) + ) // viewModel.setPositionFromQth(locator) + } + } + } +} + +@Preview(showBackground = true) +@Composable +private fun DataCardPreview() { + MainTheme { DataCard() } +} + +@Composable +private fun DataCard() { + val context = LocalContext.current + // setUpdateTime(viewModel.getLastUpdateTime()) + // viewModel.entriesTotal + // viewModel.radiosTotal + ElevatedCard(modifier = Modifier.fillMaxWidth()) { + Column(modifier = Modifier.padding(4.dp)) { + Row(verticalAlignment = Alignment.CenterVertically) { + Text(text = "Satellite data") + LinearProgressIndicator( + modifier = Modifier + .weight(1f) + .padding(start = 6.dp, end = 6.dp) + ) + } + Row( + horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() + ) { + Text(text = "Updated: 3 Mar 2023 - 15:51") + Text(text = "") + } + Row( + horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth() + ) { + Text(text = "Satellites: 7749") + Text(text = "Transceivers: 2240") + } + Row(horizontalArrangement = Arrangement.SpaceEvenly) { + CardButton( + onClick = { }, // viewModel.updateFromWeb() + text = stringResource(id = R.string.btn_web), modifier = Modifier.weight(1f) + ) + CardButton( + onClick = { }, // contentRequest.launch("*/*") + text = stringResource(id = R.string.btn_file), modifier = Modifier.weight(1f) + ) + CardButton( + onClick = { }, // viewModel.clearAllData() + text = stringResource(id = R.string.btn_clear), modifier = Modifier.weight(1f) ) } } @@ -159,80 +218,6 @@ private fun CardCredits(modifier: Modifier = Modifier) { //private val contentRequest = registerForActivityResult(contentContract) { uri -> // uri?.let { viewModel.updateFromFile(uri.toString()) } //} -//private lateinit var binding: FragmentSettingsBinding -// -//override fun onViewCreated(view: View, savedInstanceState: Bundle?) { -// super.onViewCreated(view, savedInstanceState) -// binding = FragmentSettingsBinding.bind(view).apply { -// settingsBtnBack.clickWithDebounce { findNavController().navigateUp() } -// settingsScroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, y, _, newY -> -// if (y > newY) settingsFab.hide() else settingsFab.show() -// }) -// settingsBtnGithub.clickWithDebounce { -// gotoUrl("https://github.com/rt-bishop/Look4Sat/") -// } -// settingsFab.clickWithDebounce { -// gotoUrl("https://ko-fi.com/rt_bishop") -// } -// settingsBtnFdroid.clickWithDebounce { -// gotoUrl("https://f-droid.org/en/packages/com.rtbishop.look4sat/") -// } -// } -// setupLocationCard() -// setupDataCard() -// setupRemoteCard() -// setupBTCard() -// setupOtherCard() -// viewModel.stationPosition.asLiveData().observe(viewLifecycleOwner) { stationPos -> -// stationPos?.let { handleStationPosition(stationPos) } -// } -// viewModel.getUpdateState().asLiveData().observe(viewLifecycleOwner) { updateState -> -// updateState?.let { handleSatState(updateState) } -// } -//} -// -//private fun setupLocationCard() { -// binding.run { -// setPositionText(viewModel.getStationPosition()) -// settingsLocation.locationBtnGps.clickWithDebounce { -// locationRequest.launch(arrayOf(locationFine, locationCoarse)) -// } -// settingsLocation.locationBtnManual.clickWithDebounce { -// val action = SettingsFragmentDirections.globalToPosition() -// findNavController().navigate(action) -// } -// settingsLocation.locationBtnQth.clickWithDebounce { -// val action = SettingsFragmentDirections.globalToLocator() -// findNavController().navigate(action) -// } -// getNavResult>(R.id.nav_settings, "position") { position -> -// viewModel.setStationPosition(position.first, position.second) -// } -// getNavResult(R.id.nav_settings, "locator") { locator -> -// viewModel.setPositionFromQth(locator) -// } -// } -//} -// -//private fun setupDataCard() { -// binding.run { -// setUpdateTime(viewModel.getLastUpdateTime()) -// settingsData.dataBtnWeb.clickWithDebounce { viewModel.updateFromWeb() } -// settingsData.dataBtnFile.clickWithDebounce { contentRequest.launch("*/*") } -// settingsData.dataBtnClear.clickWithDebounce { viewModel.clearAllData() } -// viewModel.entriesTotal.observe(viewLifecycleOwner) { number -> -// val entriesFormat = getString(R.string.data_entries) -// settingsData.dataEntries.text = String.format(entriesFormat, number) -// } -// viewModel.radiosTotal.observe(viewLifecycleOwner) { number -> -// val radiosFormat = getString(R.string.data_radios) -// settingsData.dataRadios.text = String.format(radiosFormat, number) -// } -// getNavResult>(R.id.nav_settings, "sources") { -// viewModel.updateFromWeb() -// } -// } -//} // //private fun setupRemoteCard() { // binding.run { @@ -288,26 +273,54 @@ private fun CardCredits(modifier: Modifier = Modifier) { // } //} // -//private fun setupOtherCard() { -// binding.run { -// settingsOther.otherSwitchUtc.apply { -// isChecked = viewModel.getUseUTC() -// setOnCheckedChangeListener { _, isChecked -> viewModel.setUseUTC(isChecked) } -// } -// settingsOther.otherSwitchUpdate.apply { -// isChecked = viewModel.getAutoUpdateEnabled() -// setOnCheckedChangeListener { _, isChecked -> viewModel.setAutoUpdateEnabled(isChecked) } -// } -// settingsOther.otherSwitchSweep.apply { -// isChecked = viewModel.getShowSweep() -// setOnCheckedChangeListener { _, isChecked -> viewModel.setShowSweep(isChecked) } -// } -// settingsOther.otherSwitchSensors.apply { -// isChecked = viewModel.getUseCompass() -// setOnCheckedChangeListener { _, isChecked -> viewModel.setUseCompass(isChecked) } -// } -// } -//} +@Preview(showBackground = true) +@Composable +private fun OtherCardPreview() { + MainTheme { OtherCard() } +} + +@Composable +private fun OtherCard() { + val context = LocalContext.current + ElevatedCard(modifier = Modifier.fillMaxWidth()) { + Column(modifier = Modifier.padding(4.dp)) { + Text(text = stringResource(id = R.string.other_title)) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = stringResource(id = R.string.other_switch_utc)) + Switch(checked = true, onCheckedChange = {}) + } // viewModel.setUseUTC(isChecked) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = stringResource(id = R.string.other_switch_update)) + Switch(checked = true, onCheckedChange = {}) + } // AutoUpdateEnabled(isChecked) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = stringResource(id = R.string.other_switch_sweep)) + Switch(checked = true, onCheckedChange = {}) + } // viewModel.setShowSweep(isChecked) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = stringResource(id = R.string.other_switch_sensors)) + Switch(checked = true, onCheckedChange = {}) + } // viewModel.setUseCompass(isChecked) + } + } +} + // //private fun handleStationPosition(pos: DataState) { // when (pos) { @@ -372,10 +385,45 @@ private fun CardCredits(modifier: Modifier = Modifier) { // binding.settingsData.dataUpdate.text = String.format(updatePattern, updateDate) //} // -//private fun showToast(message: String) { -// Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() -//} -// -//private fun gotoUrl(url: String) { -// startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) -//} +@Composable +private fun CardCredits(modifier: Modifier = Modifier) { + val context = LocalContext.current + ElevatedCard(modifier = modifier.fillMaxWidth()) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = stringResource(id = R.string.outro_title), + fontSize = 18.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.secondary, + modifier = modifier.padding(8.dp) + ) + Text( + text = stringResource(id = R.string.outro_thanks), + fontSize = 16.sp, + textAlign = TextAlign.Center, + modifier = modifier.padding(horizontal = 6.dp, vertical = 4.dp) + ) + Text( + text = stringResource(id = R.string.outro_license), + fontSize = 18.sp, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.secondary, + modifier = modifier.padding(8.dp) + ) + Row( + horizontalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.padding(4.dp) + ) { + CardButton( + onClick = { gotoUrl(context, LICENSE_URL) }, + text = stringResource(id = R.string.btn_license), + modifier = Modifier.weight(1f) + ) + CardButton( + onClick = { gotoUrl(context, POLICY_URL) }, + text = stringResource(id = R.string.btn_privacy), + modifier = Modifier.weight(1f) + ) + } + } + } +} diff --git a/app/src/main/res/drawable/ic_satellite.xml b/app/src/main/res/drawable/ic_entries.xml similarity index 100% rename from app/src/main/res/drawable/ic_satellite.xml rename to app/src/main/res/drawable/ic_entries.xml diff --git a/app/src/main/res/drawable/ic_list.xml b/app/src/main/res/drawable/ic_passes.xml similarity index 100% rename from app/src/main/res/drawable/ic_list.xml rename to app/src/main/res/drawable/ic_passes.xml diff --git a/app/src/main/res/drawable/ic_world.xml b/app/src/main/res/drawable/ic_world_map.xml similarity index 100% rename from app/src/main/res/drawable/ic_world.xml rename to app/src/main/res/drawable/ic_world_map.xml