Skip to content

Commit 2326198

Browse files
authored
Merge pull request #152 from joreilly/dependency_updates
dependency updates
2 parents 04b0559 + c6fac33 commit 2326198

File tree

27 files changed

+2190
-276
lines changed

27 files changed

+2190
-276
lines changed

.junie/guidelines.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Project Guidelines
2+
3+
## Project Structure
4+
This is a Kotlin Multiplatform project with Compose Multiplatform that includes:
5+
* `composeApp` - Shared Kotlin code with Compose UI
6+
* `iosApp` - iOS application
7+
8+
## Building the Project
9+
When building this project, Junie should use the following Gradle task:
10+
```
11+
:shared:compileDebugSources
12+
```

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ A small SwiftUI iOS app that uses same shared Kotlin Multiplatform code is in th
4141
* StarWars (https://github.com/joreilly/StarWars)
4242
* WordMasterKMP (https://github.com/joreilly/WordMasterKMP)
4343
* Chip-8 (https://github.com/joreilly/chip-8)
44+
* FirebaseAILogicKMPSample (https://github.com/joreilly/FirebaseAILogicKMPSample)

androidApp/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ dependencies {
5151
implementation(libs.androidx.compose.foundation.layout)
5252
implementation(libs.androidx.compose.material)
5353
implementation(libs.androidx.compose.material.iconsExtended)
54+
implementation(libs.androidx.compose.material3)
55+
implementation(libs.androidx.compose.material3.windowSizeClass)
5456
implementation(libs.androidx.compose.runtime)
5557
implementation(libs.androidx.compose.ui)
5658
implementation(libs.androidx.compose.ui.tooling)

androidApp/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
android:name="dev.johnoreilly.mortycomposekmm.MortyComposeKMMApplication"
88
android:allowBackup="false"
99
android:supportsRtl="true"
10-
android:theme="@style/AppTheme">
10+
android:theme="@android:style/Theme.Material.Light.NoActionBar">
1111
<activity android:name="dev.johnoreilly.mortycomposekmm.ui.MainActivity" android:exported="true">
1212
<intent-filter>
1313
<action android:name="android.intent.action.MAIN"/>

androidApp/src/main/java/dev/johnoreilly/mortycomposekmm/ui/MainActivity.kt

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,29 @@ package dev.johnoreilly.mortycomposekmm.ui
33
import android.os.Bundle
44
import androidx.activity.ComponentActivity
55
import androidx.activity.compose.setContent
6+
import androidx.activity.enableEdgeToEdge
67
import androidx.compose.foundation.layout.fillMaxSize
78
import androidx.compose.foundation.layout.padding
8-
import androidx.compose.material.*
99
import androidx.compose.material.icons.Icons
1010
import androidx.compose.material.icons.filled.LocationOn
1111
import androidx.compose.material.icons.filled.Person
1212
import androidx.compose.material.icons.filled.Tv
13+
import androidx.compose.material3.*
1314
import androidx.compose.runtime.*
1415
import androidx.compose.ui.Modifier
1516
import androidx.compose.ui.graphics.vector.ImageVector
17+
import androidx.compose.ui.unit.dp
1618
import androidx.navigation.NavHostController
1719
import androidx.navigation.compose.*
1820
import dev.johnoreilly.mortycomposekmm.ui.characters.CharacterDetailView
1921
import dev.johnoreilly.mortycomposekmm.ui.characters.CharactersListView
22+
import dev.johnoreilly.mortycomposekmm.ui.components.MortyTopAppBar
23+
import dev.johnoreilly.mortycomposekmm.ui.components.MortyDetailTopAppBar
2024
import dev.johnoreilly.mortycomposekmm.ui.episodes.EpisodeDetailView
2125
import dev.johnoreilly.mortycomposekmm.ui.episodes.EpisodesListView
2226
import dev.johnoreilly.mortycomposekmm.ui.locations.LocationDetailView
2327
import dev.johnoreilly.mortycomposekmm.ui.locations.LocationsListView
28+
import dev.johnoreilly.mortycomposekmm.ui.theme.MortyComposeTheme
2429

2530

2631
sealed class Screens(val route: String, val label: String, val icon: ImageVector? = null) {
@@ -37,35 +42,89 @@ class MainActivity : ComponentActivity() {
3742
override fun onCreate(savedInstanceState: Bundle?) {
3843
super.onCreate(savedInstanceState)
3944

45+
enableEdgeToEdge()
4046
setContent {
41-
MaterialTheme {
47+
MortyComposeTheme {
4248
MainLayout()
4349
}
4450
}
4551
}
4652
}
4753

54+
@OptIn(ExperimentalMaterial3Api::class)
4855
@Composable
4956
fun MainLayout() {
5057
val navController = rememberNavController()
58+
val currentRoute = currentRoute(navController)
59+
60+
// State to hold the detail screen title
61+
var detailTitle by remember { mutableStateOf("") }
62+
63+
// Function to update the detail title (will be passed to detail screens)
64+
val updateDetailTitle: (String) -> Unit = { title ->
65+
detailTitle = title
66+
}
67+
68+
// Determine if we're on a detail screen
69+
val isDetailScreen = remember(currentRoute) {
70+
currentRoute?.startsWith(Screens.CharacterDetailsScreen.route) == true ||
71+
currentRoute?.startsWith(Screens.EpisodeDetailsScreen.route) == true ||
72+
currentRoute?.startsWith(Screens.LocationDetailsScreen.route) == true
73+
}
74+
75+
// Get current main screen based on route
76+
val currentMainScreen = remember(currentRoute) {
77+
when (currentRoute) {
78+
Screens.CharactersScreen.route -> Screens.CharactersScreen
79+
Screens.EpisodesScreen.route -> Screens.EpisodesScreen
80+
Screens.LocationsScreen.route -> Screens.LocationsScreen
81+
else -> Screens.CharactersScreen
82+
}
83+
}
5184

5285
val bottomNavigationItems = listOf(Screens.CharactersScreen, Screens.EpisodesScreen, Screens.LocationsScreen)
5386

5487
Scaffold(
55-
topBar = { TopAppBar(title = { Text( "Characters") }) },
56-
bottomBar = { MortyBottomNavigation(navController, bottomNavigationItems) })
57-
{
88+
// Use our shared MortyTopAppBar component with dynamic content
89+
topBar = {
90+
if (isDetailScreen) {
91+
// Use detail app bar for detail screens
92+
MortyDetailTopAppBar(
93+
title = detailTitle,
94+
onBackClick = { navController.popBackStack() }
95+
)
96+
} else {
97+
// Use regular app bar for main screens
98+
MortyTopAppBar(
99+
title = currentMainScreen.label
100+
)
101+
}
102+
},
103+
// Apply navigation bar padding to the bottom navigation
104+
bottomBar = {
105+
Surface(
106+
tonalElevation = 8.dp,
107+
color = MaterialTheme.colorScheme.surface,
108+
) {
109+
MortyBottomNavigation(navController, bottomNavigationItems)
110+
}
111+
},
112+
containerColor = MaterialTheme.colorScheme.background
113+
) { paddingValues ->
58114

59-
NavHost(navController, startDestination = Screens.CharactersScreen.route, modifier = Modifier.padding(it).fillMaxSize()) {
115+
NavHost(navController, startDestination = Screens.CharactersScreen.route,
116+
modifier = Modifier.padding(paddingValues).fillMaxSize()) {
60117
composable(Screens.CharactersScreen.route) {
61118
CharactersListView() {
62119
navController.navigate(Screens.CharacterDetailsScreen.route + "/${it.id}")
63120
}
64121
}
65122
composable(Screens.CharacterDetailsScreen.route + "/{id}") { backStackEntry ->
66123
CharacterDetailView(
67-
backStackEntry.arguments?.getString("id") as String,
68-
popBack = { navController.popBackStack() })
124+
characterId = backStackEntry.arguments?.getString("id") as String,
125+
popBack = { navController.popBackStack() },
126+
updateTitle = updateDetailTitle
127+
)
69128
}
70129
composable(Screens.EpisodesScreen.route) {
71130
EpisodesListView() {
@@ -74,8 +133,10 @@ fun MainLayout() {
74133
}
75134
composable(Screens.EpisodeDetailsScreen.route + "/{id}") { backStackEntry ->
76135
EpisodeDetailView(
77-
backStackEntry.arguments?.getString("id") as String,
78-
popBack = { navController.popBackStack() })
136+
episodeId = backStackEntry.arguments?.getString("id") as String,
137+
popBack = { navController.popBackStack() },
138+
updateTitle = updateDetailTitle
139+
)
79140
}
80141
composable(Screens.LocationsScreen.route) {
81142
LocationsListView() {
@@ -84,8 +145,10 @@ fun MainLayout() {
84145
}
85146
composable(Screens.LocationDetailsScreen.route + "/{id}") { backStackEntry ->
86147
LocationDetailView(
87-
backStackEntry.arguments?.getString("id") as String,
88-
popBack = { navController.popBackStack() })
148+
locationId = backStackEntry.arguments?.getString("id") as String,
149+
popBack = { navController.popBackStack() },
150+
updateTitle = updateDetailTitle
151+
)
89152
}
90153
}
91154
}
@@ -97,10 +160,10 @@ private fun MortyBottomNavigation(
97160
navController: NavHostController,
98161
items: List<Screens>
99162
) {
100-
BottomNavigation {
163+
NavigationBar {
101164
val currentRoute = currentRoute(navController)
102165
items.forEach { screen ->
103-
BottomNavigationItem(
166+
NavigationBarItem(
104167
icon = { screen.icon?.let { Icon(screen.icon, contentDescription = screen.label) } },
105168
label = { Text(screen.label) },
106169
selected = currentRoute == screen.route,
@@ -115,12 +178,10 @@ private fun MortyBottomNavigation(
115178
)
116179
}
117180
}
118-
119181
}
120182

121183
@Composable
122184
private fun currentRoute(navController: NavHostController): String? {
123185
val navBackStackEntry by navController.currentBackStackEntryAsState()
124186
return navBackStackEntry?.destination?.route
125-
}
126-
187+
}

0 commit comments

Comments
 (0)