diff --git a/app/build.gradle b/app/build.gradle index ab800d15..4c61853a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,7 +34,7 @@ android { } } buildFeatures { -// compose true + compose true viewBinding true } composeOptions { @@ -74,26 +74,26 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-ktx:$room_version" kapt "androidx.room:room-compiler:$room_version" - implementation "com.google.android.material:material:$material_version" implementation "com.google.dagger:hilt-android:$hilt_version" kapt "com.google.dagger:hilt-compiler:$hilt_version" implementation "com.squareup.okhttp3:okhttp:$okhttp_version" implementation "org.osmdroid:osmdroid-android:$osmdroid_version" -// implementation "androidx.compose.ui:ui:$compose_version" -// implementation "androidx.compose.ui:ui-tooling:$compose_version" -// implementation "androidx.compose.runtime:runtime:$compose_version" -// implementation "androidx.compose.runtime:runtime-livedata:$compose_version" -// implementation "androidx.compose.compiler:compiler:$compose_compiler_version" -// implementation "androidx.compose.animation:animation:$compose_version" -// implementation "androidx.compose.foundation:foundation:$compose_foundation_version" -// implementation "androidx.activity:activity-compose:$activity_compose_version" -// implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version" -// implementation "androidx.compose.material:material:$compose_material_version" -// implementation "androidx.compose.material:material-icons-extended:$compose_material_version" -// implementation "com.google.android.material:compose-theme-adapter:$material_adapter_version" + implementation "androidx.compose.ui:ui:$compose_version" + implementation "androidx.compose.ui:ui-tooling:$compose_version" + implementation "androidx.compose.runtime:runtime:$compose_version" + implementation "androidx.compose.runtime:runtime-livedata:$compose_version" + implementation "androidx.compose.compiler:compiler:$compose_compiler_version" + implementation "androidx.compose.animation:animation:$compose_version" + implementation "androidx.compose.foundation:foundation:$compose_foundation_version" + implementation "androidx.navigation:navigation-compose:$navigation_version" + implementation "androidx.activity:activity-compose:$activity_compose_version" + implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version" + implementation "androidx.compose.material:material:$compose_material_version" + implementation "androidx.compose.material:material-icons-extended:$compose_material_version" + implementation "com.google.android.material:compose-theme-adapter:$material_adapter_version" -// debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" + debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" debugImplementation "androidx.fragment:fragment-testing:$fragment_test_version" debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakcanary_version" @@ -108,7 +108,7 @@ dependencies { androidTestImplementation "androidx.test.ext:junit:$androidx_junit_version" androidTestImplementation "androidx.test.ext:truth:$androidx_test_version" androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version" -// androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" + androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" androidTestImplementation "org.mockito:mockito-android:$mockito_version" androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_test_version" } 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 69d550c6..78f930a4 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/MainActivity.kt @@ -24,6 +24,7 @@ import android.content.res.Configuration import android.os.Bundle import android.os.SystemClock import android.view.View +import androidx.activity.compose.setContent import androidx.annotation.IdRes import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen @@ -36,6 +37,8 @@ import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.NavigationUiSaveStateControl import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.ActivityMainBinding +import com.rtbishop.look4sat.presentation.bottomNav.MainScreenView +import com.rtbishop.look4sat.presentation.theme.Look4SatTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint @@ -51,6 +54,7 @@ class MainActivity : AppCompatActivity() { val host = supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment NavigationUI.setupWithNavController(binding.navBar, host.navController, false) setContentView(binding.root) +// setContent { Look4SatTheme { MainScreenView() } } } override fun attachBaseContext(newBase: Context?) { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/aboutScreen/AboutFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/aboutScreen/AboutFragment.kt new file mode 100644 index 00000000..a739045f --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/aboutScreen/AboutFragment.kt @@ -0,0 +1,115 @@ +package com.rtbishop.look4sat.presentation.aboutScreen + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.Card +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +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.fragment.app.Fragment +import com.rtbishop.look4sat.R +import com.rtbishop.look4sat.presentation.theme.Look4SatTheme +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class AboutFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View { + return ComposeView(requireContext()).apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + setContent { AboutScreen() } + } + } + + @Preview(showBackground = true, widthDp = 400, heightDp = 720, showSystemUi = true) + @Composable + private fun AboutScreen() { + Look4SatTheme { + LazyColumn( + contentPadding = PaddingValues(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.fillMaxSize() + ) { + item { CardAbout() } + item { CardOutro() } + } + } + } + + @Composable + private fun CardAbout(modifier: Modifier = Modifier, version: String = "3.2.0") { + Card(modifier = modifier.fillMaxWidth()) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Row(horizontalArrangement = Arrangement.Center) { + Icon( + painter = painterResource(id = R.drawable.ic_satellite), + tint = MaterialTheme.colors.secondary, + contentDescription = null, + modifier = Modifier + .size(96.dp) + .padding(top = 8.dp, end = 8.dp) + ) + Column { + Text( + text = stringResource(id = R.string.app_name), + fontSize = 48.sp, + color = MaterialTheme.colors.secondary + ) + Text( + text = stringResource(id = R.string.app_version, version), + fontSize = 21.sp + ) + } + } + Text( + text = stringResource(id = R.string.app_subtitle), + fontSize = 21.sp, + modifier = modifier.padding(top = 4.dp, bottom = 8.dp) + ) + } + } + } + + @Composable + fun CardOutro(modifier: Modifier = Modifier) { + Card(modifier = modifier.fillMaxWidth()) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = stringResource(id = R.string.outro_title), + fontSize = 19.sp, + color = MaterialTheme.colors.secondary, + modifier = modifier.padding(8.dp) + ) + Text( + text = stringResource(id = R.string.outro_thanks), + fontSize = 17.sp, + textAlign = TextAlign.Center, + modifier = modifier.padding(start = 8.dp, end = 8.dp) + ) + Text( + text = stringResource(id = R.string.outro_license), + fontSize = 17.sp, + textAlign = TextAlign.Center, + modifier = modifier.padding(8.dp) + ) + } + } + } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavItem.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavItem.kt new file mode 100644 index 00000000..3ccf357e --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavItem.kt @@ -0,0 +1,11 @@ +package com.rtbishop.look4sat.presentation.bottomNav + +import com.rtbishop.look4sat.R + +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 WorldMap : BottomNavItem("World Map", R.drawable.ic_map, "world_map") + object Settings : BottomNavItem("Settings", R.drawable.ic_settings, "settings") + object About : BottomNavItem("About", R.drawable.ic_about, "about") +} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavScreens.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavScreens.kt new file mode 100644 index 00000000..7422f66f --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavScreens.kt @@ -0,0 +1,111 @@ +package com.rtbishop.look4sat.presentation.bottomNav + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.sp +import com.rtbishop.look4sat.R + +@Composable +fun SatellitesScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(colorResource(id = R.color.background)) + .wrapContentSize(Alignment.Center) + ) { + Text( + text = "Satellites", + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.align(Alignment.CenterHorizontally), + textAlign = TextAlign.Center, + fontSize = 20.sp + ) + } +} + +@Composable +fun PassesScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(colorResource(id = R.color.background)) + .wrapContentSize(Alignment.Center) + ) { + Text( + text = "Passes", + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.align(Alignment.CenterHorizontally), + textAlign = TextAlign.Center, + fontSize = 20.sp + ) + } +} + +@Composable +fun WorldMapScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(colorResource(id = R.color.background)) + .wrapContentSize(Alignment.Center) + ) { + Text( + text = "World Map", + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.align(Alignment.CenterHorizontally), + textAlign = TextAlign.Center, + fontSize = 20.sp + ) + } +} + +@Composable +fun SettingsScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(colorResource(id = R.color.background)) + .wrapContentSize(Alignment.Center) + ) { + Text( + text = "Settings", + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.align(Alignment.CenterHorizontally), + textAlign = TextAlign.Center, + fontSize = 20.sp + ) + } +} + +@Composable +fun AboutScreen() { + Column( + modifier = Modifier + .fillMaxSize() + .background(colorResource(id = R.color.background)) + .wrapContentSize(Alignment.Center) + ) { + Text( + text = "About", + fontWeight = FontWeight.Bold, + color = Color.White, + modifier = Modifier.align(Alignment.CenterHorizontally), + textAlign = TextAlign.Center, + fontSize = 20.sp + ) + } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavView.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavView.kt new file mode 100644 index 00000000..1a4fdb80 --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/bottomNav/BottomNavView.kt @@ -0,0 +1,79 @@ +package com.rtbishop.look4sat.presentation.bottomNav + +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.sp +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.theme.Yellow +import com.rtbishop.look4sat.presentation.theme.Look4SatTheme +import com.rtbishop.look4sat.presentation.theme.TextWhite + +@Composable +fun BottomNavView(navController: NavController) { + val items = listOf( + BottomNavItem.Satellites, + BottomNavItem.Passes, + BottomNavItem.WorldMap, + BottomNavItem.Settings, + BottomNavItem.About + ) + BottomNavigation(backgroundColor = colorResource(id = R.color.bottomBar)) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + items.forEach { item -> + BottomNavigationItem(icon = { + Icon(painterResource(id = item.icon), contentDescription = item.title) + }, + label = { Text(text = item.title, fontSize = 9.sp) }, + selectedContentColor = Yellow, + unselectedContentColor = TextWhite.copy(0.4f), + alwaysShowLabel = true, + selected = currentRoute == item.screen_route, + onClick = { + navController.navigate(item.screen_route) { + navController.graph.startDestinationRoute?.let { screen_route -> + popUpTo(screen_route) { saveState = true } + } + launchSingleTop = true + restoreState = true + } + }) + } + } +} + +@Composable +fun NavigationGraph(navController: NavHostController) { + NavHost(navController, startDestination = BottomNavItem.Satellites.screen_route) { + composable(BottomNavItem.Satellites.screen_route) { SatellitesScreen() } + composable(BottomNavItem.Passes.screen_route) { PassesScreen() } + composable(BottomNavItem.WorldMap.screen_route) { WorldMapScreen() } + composable(BottomNavItem.Settings.screen_route) { SettingsScreen() } + composable(BottomNavItem.About.screen_route) { AboutScreen() } + } +} + +@Composable +fun MainScreenView() { + val navController = rememberNavController() + Scaffold(bottomBar = { BottomNavView(navController = navController) }) { + NavigationGraph(navController = navController) + it.calculateBottomPadding() + } +} + +@Preview(showBackground = true) +@Composable +fun DefaultPreview() { + Look4SatTheme { MainScreenView() } +} diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Color.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Color.kt new file mode 100644 index 00000000..8aa20283 --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Color.kt @@ -0,0 +1,12 @@ +package com.rtbishop.look4sat.presentation.theme + +import androidx.compose.ui.graphics.Color + +val Yellow = Color(0xFFFFE082) +val TextWhite = Color(0xCCFFFFFF) +val TextGrey = Color(0x66FFFFFF) +val TextBlack = Color(0xFF000000) +val ButtonGrey = Color(0xFF2A2A2A) +val SurfaceGrey = Color(0xFF1C1C1C) +val Background = Color(0xFF121212) +val Transparent = Color(0x00000000) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Shape.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Shape.kt new file mode 100644 index 00000000..300e421f --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Shape.kt @@ -0,0 +1,11 @@ +package com.rtbishop.look4sat.presentation.theme + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Shapes +import androidx.compose.ui.unit.dp + +val Shapes = Shapes( + small = RoundedCornerShape(8.dp), + medium = RoundedCornerShape(8.dp), + large = RoundedCornerShape(8.dp) +) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt new file mode 100644 index 00000000..546ad5d6 --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Theme.kt @@ -0,0 +1,37 @@ +package com.rtbishop.look4sat.presentation.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material.MaterialTheme +import androidx.compose.material.darkColors +import androidx.compose.material.lightColors +import androidx.compose.runtime.Composable + +@Composable +fun Look4SatTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { + val colors = if (darkTheme) DarkColors else LightColors + MaterialTheme(colors = colors, typography = Typography, shapes = Shapes, content = content) +} + +private val LightColors = lightColors( + primary = SurfaceGrey, + primaryVariant = Background, + secondary = Yellow, + background = Background, + surface = SurfaceGrey, + onPrimary = TextWhite, + onSecondary = TextBlack, + onBackground = TextWhite, + onSurface = TextWhite +) + +private val DarkColors = darkColors( + primary = SurfaceGrey, + primaryVariant = Background, + secondary = Yellow, + background = Background, + surface = SurfaceGrey, + onPrimary = TextWhite, + onSecondary = TextBlack, + onBackground = TextWhite, + onSurface = TextWhite +) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Type.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Type.kt new file mode 100644 index 00000000..0a861c54 --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/theme/Type.kt @@ -0,0 +1,23 @@ +package com.rtbishop.look4sat.presentation.theme + +import androidx.compose.material.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +val Typography = Typography( + body1 = TextStyle( + fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 16.sp + ) +// button = TextStyle( +// fontFamily = FontFamily.Default, +// fontWeight = FontWeight.W500, +// fontSize = 14.sp +// ), +// caption = TextStyle( +// fontFamily = FontFamily.Default, +// fontWeight = FontWeight.Normal, +// fontSize = 12.sp +// ) +) diff --git a/app/src/main/res/drawable/ic_radar_def.xml b/app/src/main/res/drawable/ic_radar_def.xml new file mode 100644 index 00000000..8771c662 --- /dev/null +++ b/app/src/main/res/drawable/ic_radar_def.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_radar_pos.xml b/app/src/main/res/drawable/ic_radar_pos.xml new file mode 100644 index 00000000..94dc8f5b --- /dev/null +++ b/app/src/main/res/drawable/ic_radar_pos.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_radar_tech.xml b/app/src/main/res/drawable/ic_radar_tech.xml new file mode 100644 index 00000000..7f2a47ef --- /dev/null +++ b/app/src/main/res/drawable/ic_radar_tech.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index e5abb3f4..8890fb21 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -56,8 +56,7 @@ tools:layout="@layout/fragment_settings" /> + android:name="com.rtbishop.look4sat.presentation.aboutScreen.AboutFragment"> I would like to say thanks to: • You for downloading and using Look4Sat! \nMay your sky always be clear! - \n • David A. B. Johnson + \n\n • David A. B. Johnson and Dave Moten for creating predict4java lib under the GNU GPLv2. - \n • Alexandru Csete for creating Gpredict + \n\n • Alexandru Csete for creating Gpredict satellite tracker that inspired the creation of Look4Sat. - \n • Dr T.S. Kelso for maintaining his + \n\n • Dr T.S. Kelso for maintaining his Celestrak website that provides access to the TLE data. - \n • Libre Space Foundation for their + \n\n • Libre Space Foundation for their SatNOGS API and DB providing a huge amount of satellite data. - \n • DownloadAstro + \n\n • DownloadAstro team for their interest to the app and the interview published. Privacy Policy. diff --git a/build.gradle b/build.gradle index 40bd232b..30f1f407 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,16 @@ buildscript { ext { hilt_version = '2.44.2' - application_version = '8.3.0' + application_version = '7.4.0' library_version = '7.1.2' kotlin_android_version = '1.8.0' core_ktx_version = '1.9.0' - core_splashscreen_version = '1.0.1' + core_splashscreen_version = '1.0.0' constraint_version = '2.1.4' lifecycle_version = '2.5.1' navigation_version = '2.5.3' work_version = '2.7.1' room_version = '2.5.0' - material_version = '1.6.1' - okhttp_version = '4.10.0' osmdroid_version = '6.1.14' json_version = '20220924' compose_version = '1.3.3'