Skip to content

Commit 3390f25

Browse files
authored
Merge pull request #476 from DennisBauer/migrate_to_single_scaffold
Migrate to a single scaffold in app
2 parents 218b0db + df7e8a3 commit 3390f25

File tree

10 files changed

+765
-857
lines changed

10 files changed

+765
-857
lines changed

app/src/commonMain/kotlin/di/Module.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.koin.core.module.dsl.viewModelOf
1313
import org.koin.dsl.bind
1414
import org.koin.dsl.module
1515
import viewmodel.EditRecurringExpenseViewModel
16+
import viewmodel.MainNavigationViewModel
1617
import viewmodel.RecurringExpenseViewModel
1718
import viewmodel.SettingsViewModel
1819
import viewmodel.UpcomingPaymentsViewModel
@@ -34,4 +35,5 @@ val sharedModule =
3435
viewModelOf(::SettingsViewModel)
3536
singleOf(::ExchangeRateProvider)
3637
singleOf(::ExpenseNotificationManager)
38+
viewModelOf(::MainNavigationViewModel)
3739
}

app/src/commonMain/kotlin/ui/MainContent.kt

Lines changed: 170 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,48 @@ package ui
22

33
import androidx.compose.foundation.layout.PaddingValues
44
import androidx.compose.foundation.layout.fillMaxSize
5+
import androidx.compose.foundation.layout.padding
6+
import androidx.compose.material.icons.Icons
7+
import androidx.compose.material.icons.rounded.Add
8+
import androidx.compose.material3.ExperimentalMaterial3Api
9+
import androidx.compose.material3.FloatingActionButton
10+
import androidx.compose.material3.Icon
11+
import androidx.compose.material3.Scaffold
12+
import androidx.compose.material3.Text
13+
import androidx.compose.material3.TopAppBar
514
import androidx.compose.runtime.Composable
615
import androidx.compose.runtime.getValue
16+
import androidx.compose.runtime.mutableStateOf
17+
import androidx.compose.runtime.remember
18+
import androidx.compose.runtime.setValue
719
import androidx.compose.ui.Modifier
820
import androidx.compose.ui.unit.dp
921
import androidx.navigation.compose.NavHost
1022
import androidx.navigation.compose.composable
23+
import androidx.navigation.compose.currentBackStackEntryAsState
1124
import androidx.navigation.compose.rememberNavController
1225
import data.EditExpensePane
1326
import data.EditExpensePane.Companion.getArgExpenseId
1427
import data.HomePane
1528
import data.SettingsPane
1629
import data.UpcomingPane
1730
import model.database.UserPreferencesRepository
31+
import org.jetbrains.compose.resources.stringResource
1832
import org.koin.compose.KoinContext
1933
import org.koin.compose.koinInject
2034
import org.koin.compose.viewmodel.koinViewModel
35+
import recurringexpensetracker.app.generated.resources.Res
36+
import recurringexpensetracker.app.generated.resources.edit_expense_button_add
37+
import recurringexpensetracker.app.generated.resources.home_title
38+
import recurringexpensetracker.app.generated.resources.upcoming_title
2139
import toCurrencyString
2240
import ui.editexpense.EditRecurringExpenseScreen
2341
import ui.upcomingexpenses.UpcomingPaymentsScreen
42+
import viewmodel.MainNavigationViewModel
2443
import viewmodel.RecurringExpenseViewModel
2544
import viewmodel.UpcomingPaymentsViewModel
2645

46+
@OptIn(ExperimentalMaterial3Api::class)
2747
@Suppress("ktlint:compose:vm-forwarding-check")
2848
@Composable
2949
fun MainContent(
@@ -41,88 +61,165 @@ fun MainContent(
4161
updateWidget: () -> Unit,
4262
modifier: Modifier = Modifier,
4363
startRoute: String = HomePane.ROUTE,
64+
mainNavigationViewModel: MainNavigationViewModel = koinViewModel<MainNavigationViewModel>(),
4465
recurringExpenseViewModel: RecurringExpenseViewModel = koinViewModel<RecurringExpenseViewModel>(),
4566
upcomingPaymentsViewModel: UpcomingPaymentsViewModel = koinViewModel<UpcomingPaymentsViewModel>(),
4667
userPreferencesRepository: UserPreferencesRepository = koinInject(),
4768
) {
4869
val navController = rememberNavController()
70+
val backStackEntry = navController.currentBackStackEntryAsState()
4971
val currencyCode by userPreferencesRepository.defaultCurrency.collectAsState()
5072

5173
KoinContext {
52-
NavHost(
53-
navController = navController,
54-
startDestination = startRoute,
55-
modifier = modifier.fillMaxSize(),
56-
) {
57-
composable(HomePane.ROUTE) {
58-
val weeklyExpense =
59-
recurringExpenseViewModel.currencyPrefix +
60-
recurringExpenseViewModel.weeklyExpense.toCurrencyString(currencyCode)
61-
val monthlyExpense =
62-
recurringExpenseViewModel.currencyPrefix +
63-
recurringExpenseViewModel.monthlyExpense.toCurrencyString(currencyCode)
64-
val yearlyExpense =
65-
recurringExpenseViewModel.currencyPrefix +
66-
recurringExpenseViewModel.yearlyExpense.toCurrencyString(currencyCode)
67-
68-
RecurringExpenseOverview(
69-
weeklyExpense = weeklyExpense,
70-
monthlyExpense = monthlyExpense,
71-
yearlyExpense = yearlyExpense,
72-
recurringExpenseData = recurringExpenseViewModel.recurringExpenseData,
73-
isGridMode = isGridMode,
74-
onToggleGridMode = toggleGridMode,
75-
navController = navController,
76-
contentPadding =
77-
PaddingValues(
78-
top = 8.dp,
79-
start = 16.dp,
80-
end = 16.dp,
81-
),
82-
)
83-
}
84-
composable(UpcomingPane.ROUTE) {
85-
UpcomingPaymentsScreen(
86-
upcomingPaymentsViewModel = upcomingPaymentsViewModel,
87-
isGridMode = isGridMode,
88-
onToggleGridMode = toggleGridMode,
89-
navController = navController,
90-
contentPadding =
91-
PaddingValues(
92-
top = 8.dp,
93-
start = 16.dp,
94-
end = 16.dp,
95-
),
96-
)
97-
}
98-
composable(SettingsPane.ROUTE) {
99-
SettingsScreen(
100-
biometricsChecked = biometricSecurity,
101-
onClickBackup = onClickBackup,
102-
onClickRestore = onClickRestore,
103-
onBiometricCheckedChange = onBiometricSecurityChange,
104-
canUseBiometric = canUseBiometric,
105-
canUseNotifications = canUseNotifications,
106-
hasNotificationPermission = hasNotificationPermission,
107-
requestNotificationPermission = requestNotificationPermission,
108-
navigateToPermissionsSettings = navigateToPermissionsSettings,
74+
Scaffold(
75+
modifier = modifier,
76+
topBar = {
77+
mainNavigationViewModel.topAppBar()
78+
},
79+
bottomBar = {
80+
if (backStackEntry.value?.destination?.route in
81+
listOf(HomePane.ROUTE, UpcomingPane.ROUTE, SettingsPane.ROUTE)
82+
) {
83+
BottomNavBar(navController = navController)
84+
}
85+
},
86+
floatingActionButton = {
87+
if (backStackEntry.value?.destination?.route in listOf(HomePane.ROUTE, UpcomingPane.ROUTE)) {
88+
FloatingActionButton(
89+
onClick = {
90+
navController.navigate(EditExpensePane().destination)
91+
},
92+
) {
93+
Icon(
94+
imageVector = Icons.Rounded.Add,
95+
contentDescription =
96+
stringResource(Res.string.edit_expense_button_add),
97+
)
98+
}
99+
}
100+
},
101+
content = { paddingValues ->
102+
NavHost(
109103
navController = navController,
110-
)
111-
}
112-
composable(
113-
route = EditExpensePane.ROUTE,
114-
arguments = EditExpensePane.navArguments,
115-
) { backStackEntry ->
116-
EditRecurringExpenseScreen(
117-
expenseId = backStackEntry.getArgExpenseId(),
118-
canUseNotifications = canUseNotifications,
119-
onDismiss = {
120-
navController.navigateUp()
121-
updateWidget()
122-
},
123-
)
124-
}
125-
}
104+
startDestination = startRoute,
105+
modifier = Modifier.fillMaxSize(),
106+
) {
107+
composable(HomePane.ROUTE) {
108+
mainNavigationViewModel.topAppBar = {
109+
TopAppBar(
110+
title = {
111+
Text(
112+
text = stringResource(Res.string.home_title),
113+
)
114+
},
115+
actions = {
116+
ToggleGridModeButton(
117+
onToggleGridMode = toggleGridMode,
118+
isGridMode = isGridMode,
119+
)
120+
},
121+
)
122+
}
123+
124+
val weeklyExpense =
125+
recurringExpenseViewModel.currencyPrefix +
126+
recurringExpenseViewModel.weeklyExpense.toCurrencyString(currencyCode)
127+
val monthlyExpense =
128+
recurringExpenseViewModel.currencyPrefix +
129+
recurringExpenseViewModel.monthlyExpense.toCurrencyString(currencyCode)
130+
val yearlyExpense =
131+
recurringExpenseViewModel.currencyPrefix +
132+
recurringExpenseViewModel.yearlyExpense.toCurrencyString(currencyCode)
133+
134+
RecurringExpenseOverview(
135+
weeklyExpense = weeklyExpense,
136+
monthlyExpense = monthlyExpense,
137+
yearlyExpense = yearlyExpense,
138+
recurringExpenseData = recurringExpenseViewModel.recurringExpenseData,
139+
isGridMode = isGridMode,
140+
navController = navController,
141+
contentPadding =
142+
PaddingValues(
143+
top = 8.dp,
144+
start = 16.dp,
145+
end = 16.dp,
146+
),
147+
modifier = Modifier.padding(paddingValues),
148+
)
149+
}
150+
composable(UpcomingPane.ROUTE) {
151+
mainNavigationViewModel.topAppBar = {
152+
TopAppBar(
153+
title = {
154+
Text(
155+
text = stringResource(Res.string.upcoming_title),
156+
)
157+
},
158+
actions = {
159+
ToggleGridModeButton(
160+
onToggleGridMode = toggleGridMode,
161+
isGridMode = isGridMode,
162+
)
163+
},
164+
)
165+
}
166+
167+
UpcomingPaymentsScreen(
168+
upcomingPaymentsViewModel = upcomingPaymentsViewModel,
169+
isGridMode = isGridMode,
170+
navController = navController,
171+
contentPadding =
172+
PaddingValues(
173+
top = 8.dp,
174+
start = 16.dp,
175+
end = 16.dp,
176+
),
177+
modifier = Modifier.padding(paddingValues),
178+
)
179+
}
180+
composable(SettingsPane.ROUTE) {
181+
var topAppBar by remember { mutableStateOf<@Composable () -> Unit>({}) }
182+
SettingsScreen(
183+
biometricsChecked = biometricSecurity,
184+
onClickBackup = onClickBackup,
185+
onClickRestore = onClickRestore,
186+
onBiometricCheckedChange = onBiometricSecurityChange,
187+
canUseBiometric = canUseBiometric,
188+
canUseNotifications = canUseNotifications,
189+
hasNotificationPermission = hasNotificationPermission,
190+
requestNotificationPermission = requestNotificationPermission,
191+
navigateToPermissionsSettings = navigateToPermissionsSettings,
192+
setTopAppBar = {
193+
mainNavigationViewModel.topAppBar = it
194+
topAppBar = it
195+
},
196+
modifier = Modifier.padding(paddingValues),
197+
)
198+
mainNavigationViewModel.topAppBar = topAppBar
199+
}
200+
composable(
201+
route = EditExpensePane.ROUTE,
202+
arguments = EditExpensePane.navArguments,
203+
) { backStackEntry ->
204+
var topAppBar by remember { mutableStateOf<@Composable () -> Unit>({}) }
205+
EditRecurringExpenseScreen(
206+
expenseId = backStackEntry.getArgExpenseId(),
207+
canUseNotifications = canUseNotifications,
208+
onDismiss = {
209+
navController.navigateUp()
210+
updateWidget()
211+
},
212+
setTopAppBar = {
213+
mainNavigationViewModel.topAppBar = it
214+
topAppBar = it
215+
},
216+
modifier = Modifier.padding(paddingValues),
217+
)
218+
mainNavigationViewModel.topAppBar = topAppBar
219+
}
220+
}
221+
},
222+
)
126223
}
127224
}
128225

0 commit comments

Comments
 (0)