From 3e1809eafe6f5cb21afe4ad2c5304d8478fd9942 Mon Sep 17 00:00:00 2001 From: Joseph Eng Date: Wed, 5 Jul 2023 18:41:24 -0700 Subject: [PATCH] Adjust view model storage Store ScoutingScheduleManager and view models in AppContainer Access view models through parameters Remove getViewModel() Add and use composableContext Make composable parameter order consistent --- .../java/com/scouting/app/AppContainer.kt | 15 +++++++ .../java/com/scouting/app/MainActivity.kt | 36 +++++++++------- .../com/scouting/app/utilities/Utilities.kt | 9 ++-- .../com/scouting/app/view/HomePageView.kt | 18 ++++---- .../app/view/scouting/FinishScoutingView.kt | 8 ++-- .../app/view/scouting/NoTemplateDialog.kt | 2 +- .../app/view/scouting/ScoutingView.kt | 5 +-- .../app/view/scouting/StartMatchView.kt | 14 +++--- .../app/view/scouting/StartPitScoutingView.kt | 17 +++++--- .../app/view/settings/DevicePositionDialog.kt | 7 ++- .../app/view/settings/SettingsView.kt | 14 +++--- .../app/view/template/EditCSVOrderView.kt | 5 +-- .../app/view/template/EditTemplateDialog.kt | 8 ++-- .../app/view/template/TemplateEditorView.kt | 7 +-- .../app/view/template/TemplateSaveView.kt | 43 ++++++++++--------- .../app/view/template/TemplateTypeDialog.kt | 6 +-- .../app/viewmodel/TemplateEditorViewModel.kt | 8 ++-- 17 files changed, 117 insertions(+), 105 deletions(-) create mode 100644 app/src/main/java/com/scouting/app/AppContainer.kt diff --git a/app/src/main/java/com/scouting/app/AppContainer.kt b/app/src/main/java/com/scouting/app/AppContainer.kt new file mode 100644 index 0000000..bd4cecc --- /dev/null +++ b/app/src/main/java/com/scouting/app/AppContainer.kt @@ -0,0 +1,15 @@ +package com.scouting.app + +import com.scouting.app.misc.ScoutingScheduleManager +import com.scouting.app.viewmodel.HomePageViewModel +import com.scouting.app.viewmodel.ScoutingViewModel +import com.scouting.app.viewmodel.SettingsViewModel +import com.scouting.app.viewmodel.TemplateEditorViewModel + +class AppContainer { + val scheduleManager = ScoutingScheduleManager() + val homePageViewModel = HomePageViewModel() + val scoutingViewModel = ScoutingViewModel() + val settingsViewModel = SettingsViewModel() + val templateEditorViewModel = TemplateEditorViewModel() +} \ No newline at end of file diff --git a/app/src/main/java/com/scouting/app/MainActivity.kt b/app/src/main/java/com/scouting/app/MainActivity.kt index 50d0550..65ab0ff 100755 --- a/app/src/main/java/com/scouting/app/MainActivity.kt +++ b/app/src/main/java/com/scouting/app/MainActivity.kt @@ -30,9 +30,7 @@ import com.scouting.app.misc.RequestCode.PIT_SCOUTING_SCHEDULE_FILE_PICK import com.scouting.app.misc.RequestCode.PIT_TEMPLATE_FILE_PICK import com.scouting.app.misc.RequestCode.TEMPLATE_EDITOR_IMAGE_FILE_PICK import com.scouting.app.misc.RequestCode.TEMPLATE_EDITOR_IMPORT_FILE_PICK -import com.scouting.app.misc.ScoutingScheduleManager import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel import com.scouting.app.view.HomePageView import com.scouting.app.view.scouting.FinishScoutingView import com.scouting.app.view.scouting.ScoutingView @@ -42,8 +40,6 @@ import com.scouting.app.view.settings.SettingsView import com.scouting.app.view.template.EditCSVOrderView import com.scouting.app.view.template.TemplateEditorView import com.scouting.app.view.template.TemplateSaveView -import com.scouting.app.viewmodel.SettingsViewModel -import com.scouting.app.viewmodel.TemplateEditorViewModel import com.tencent.mmkv.MMKV import java.io.File @@ -51,13 +47,14 @@ import java.io.File class MainActivity : ComponentActivity() { private lateinit var navigationController: NavHostController - private val scoutingScheduleManager = ScoutingScheduleManager() + lateinit var appContainer: AppContainer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) MMKV.initialize(this) configureStorage() - scoutingScheduleManager.apply { + appContainer = AppContainer() + appContainer.scheduleManager.apply { loadCachedSchedule(true) loadCachedSchedule(false) } @@ -72,6 +69,11 @@ class MainActivity : ComponentActivity() { @OptIn(ExperimentalAnimationApi::class) fun NavigationHost() { navigationController = rememberAnimatedNavController() + val scheduleManager = appContainer.scheduleManager + val homePageViewModel = appContainer.homePageViewModel + val scoutingViewModel = appContainer.scoutingViewModel + val settingsViewModel = appContainer.settingsViewModel + val templateEditorViewModel = appContainer.templateEditorViewModel AnimatedNavHost( navController = navigationController, startDestination = NavDestination.HomePage, @@ -87,7 +89,7 @@ class MainActivity : ComponentActivity() { }, builder = { composable(NavDestination.HomePage) { - HomePageView(navigationController, scoutingScheduleManager) + HomePageView(navigationController, scheduleManager, homePageViewModel, settingsViewModel) } composable( route = "${NavDestination.TemplateEditor}/{type}", @@ -95,23 +97,24 @@ class MainActivity : ComponentActivity() { ) { TemplateEditorView( navController = navigationController, + viewModel = templateEditorViewModel, type = it.arguments?.getString("type", "match")!! ) } composable(NavDestination.TemplateEditor) { - TemplateEditorView(navigationController) + TemplateEditorView(navigationController, templateEditorViewModel) } composable(NavDestination.EditCSVOrder) { - EditCSVOrderView(navigationController) + EditCSVOrderView(navigationController, templateEditorViewModel) } composable(NavDestination.TemplateSave) { - TemplateSaveView(navigationController) + TemplateSaveView(navigationController, templateEditorViewModel, settingsViewModel) } composable(NavDestination.StartMatchScouting) { - StartMatchView(navigationController, scoutingScheduleManager) + StartMatchView(navigationController, scheduleManager, scoutingViewModel) } composable(NavDestination.StartPitScouting) { - StartPitScoutingView(navigationController, scoutingScheduleManager) + StartPitScoutingView(navigationController, scheduleManager, scoutingViewModel) } composable( route = "${NavDestination.Scouting}/{type}", @@ -119,14 +122,15 @@ class MainActivity : ComponentActivity() { ) { ScoutingView( navController = navigationController, + viewModel = scoutingViewModel, scoutingMatch = it.arguments?.getBoolean("type", true) ?: false ) } composable(NavDestination.Settings) { - SettingsView(navigationController, scoutingScheduleManager) + SettingsView(navigationController, scheduleManager, settingsViewModel) } composable(NavDestination.FinishScouting) { - FinishScoutingView(navigationController) + FinishScoutingView(navigationController, scoutingViewModel) } } ) @@ -184,8 +188,8 @@ class MainActivity : ComponentActivity() { super.onActivityResult(requestCode, resultCode, resultData) if (resultCode == RESULT_OK) { resultData?.let { data -> - val settingsViewModel = getViewModel(SettingsViewModel::class.java) - val templateEditorViewModel = getViewModel(TemplateEditorViewModel::class.java) + val settingsViewModel = appContainer.settingsViewModel + val templateEditorViewModel = appContainer.templateEditorViewModel when (requestCode) { MATCH_TEMPLATE_FILE_PICK, PIT_TEMPLATE_FILE_PICK -> { settingsViewModel.processTemplateFilePickerResult( diff --git a/app/src/main/java/com/scouting/app/utilities/Utilities.kt b/app/src/main/java/com/scouting/app/utilities/Utilities.kt index 99e72a9..3c29db5 100755 --- a/app/src/main/java/com/scouting/app/utilities/Utilities.kt +++ b/app/src/main/java/com/scouting/app/utilities/Utilities.kt @@ -1,18 +1,16 @@ package com.scouting.app.utilities -import android.content.Context -import androidx.activity.ComponentActivity import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.zIndex -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider import androidx.navigation.NavController import androidx.navigation.navOptions +import com.scouting.app.MainActivity /** * Returns a [MutableState] that will be initialized with [value] during the first composition and when a different @@ -21,8 +19,7 @@ import androidx.navigation.navOptions @Composable fun rememberInitial(value: T) = remember(value) { mutableStateOf(value) } -fun Context.getViewModel(type: Class): T = - ViewModelProvider(this as ComponentActivity)[type] +val composableContext @Composable get() = LocalContext.current as MainActivity fun Modifier.longPressEffect(offset: Float?): Modifier = this diff --git a/app/src/main/java/com/scouting/app/view/HomePageView.kt b/app/src/main/java/com/scouting/app/view/HomePageView.kt index 6657876..46dd2aa 100644 --- a/app/src/main/java/com/scouting/app/view/HomePageView.kt +++ b/app/src/main/java/com/scouting/app/view/HomePageView.kt @@ -18,7 +18,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.LargeButton import com.scouting.app.misc.AllianceType @@ -27,7 +26,6 @@ import com.scouting.app.misc.ScoutingScheduleManager import com.scouting.app.theme.AffirmativeGreenDark import com.scouting.app.theme.ErrorRedDark import com.scouting.app.theme.SecondaryPurpleDark -import com.scouting.app.utilities.getViewModel import com.scouting.app.view.settings.DevicePositionDialog import com.scouting.app.view.template.TemplateTypeDialog import com.scouting.app.viewmodel.HomePageViewModel @@ -35,11 +33,12 @@ import com.scouting.app.viewmodel.SettingsViewModel import com.tencent.mmkv.MMKV @Composable -fun HomePageView(navController: NavController, scoutingScheduleManager: ScoutingScheduleManager) { - val context = navController.context as MainActivity - val viewModel = context.getViewModel(HomePageViewModel::class.java) - val settingsViewModel = - context.getViewModel(SettingsViewModel::class.java) // might be bad practice lolz +fun HomePageView( + navController: NavController, + scoutingScheduleManager: ScoutingScheduleManager, + viewModel: HomePageViewModel, + settingsViewModel: SettingsViewModel +) { val preferences = MMKV.defaultMMKV() LaunchedEffect(true) { settingsViewModel.loadSavedPreferences() @@ -203,10 +202,9 @@ fun HomePageView(navController: NavController, scoutingScheduleManager: Scouting } } } - TemplateTypeDialog(viewModel, navController) + TemplateTypeDialog(navController, viewModel) DevicePositionDialog( - viewModel = settingsViewModel, - navController = navController + viewModel = settingsViewModel ) } } diff --git a/app/src/main/java/com/scouting/app/view/scouting/FinishScoutingView.kt b/app/src/main/java/com/scouting/app/view/scouting/FinishScoutingView.kt index 9ea769e..1daf1e8 100644 --- a/app/src/main/java/com/scouting/app/view/scouting/FinishScoutingView.kt +++ b/app/src/main/java/com/scouting/app/view/scouting/FinishScoutingView.kt @@ -11,7 +11,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.BasicInputField import com.scouting.app.components.LargeHeaderBar @@ -20,14 +19,13 @@ import com.scouting.app.components.SpacedRow import com.scouting.app.misc.NavDestination import com.scouting.app.theme.AffirmativeGreen import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel +import com.scouting.app.utilities.composableContext import com.scouting.app.utilities.returnTo import com.scouting.app.viewmodel.ScoutingViewModel @Composable -fun FinishScoutingView(navController: NavController) { - val context = navController.context as MainActivity - val viewModel = context.getViewModel(ScoutingViewModel::class.java) +fun FinishScoutingView(navController: NavController, viewModel: ScoutingViewModel) { + val context = composableContext ScoutingTheme { Surface(modifier = Modifier.fillMaxSize()) { Column { diff --git a/app/src/main/java/com/scouting/app/view/scouting/NoTemplateDialog.kt b/app/src/main/java/com/scouting/app/view/scouting/NoTemplateDialog.kt index ea9c9df..38e52bd 100644 --- a/app/src/main/java/com/scouting/app/view/scouting/NoTemplateDialog.kt +++ b/app/src/main/java/com/scouting/app/view/scouting/NoTemplateDialog.kt @@ -18,7 +18,7 @@ import com.scouting.app.theme.ScoutingTheme import com.scouting.app.viewmodel.ScoutingViewModel @Composable -fun NoTemplateDialog(viewModel: ScoutingViewModel, navController: NavController) { +fun NoTemplateDialog(navController: NavController, viewModel: ScoutingViewModel) { if (viewModel.showingNoTemplateDialog) { ScoutingTheme { DialogScaffold( diff --git a/app/src/main/java/com/scouting/app/view/scouting/ScoutingView.kt b/app/src/main/java/com/scouting/app/view/scouting/ScoutingView.kt index 82d7b0b..773c092 100644 --- a/app/src/main/java/com/scouting/app/view/scouting/ScoutingView.kt +++ b/app/src/main/java/com/scouting/app/view/scouting/ScoutingView.kt @@ -13,7 +13,6 @@ import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle @@ -28,13 +27,11 @@ import com.scouting.app.model.TemplateItem import com.scouting.app.theme.AffirmativeGreen import com.scouting.app.theme.ScoutingTheme import com.scouting.app.theme.SecondaryPurple -import com.scouting.app.utilities.getViewModel import com.scouting.app.viewmodel.ScoutingViewModel @OptIn(ExperimentalAnimationApi::class) @Composable -fun ScoutingView(navController: NavController, scoutingMatch: Boolean) { - val viewModel = LocalContext.current.getViewModel(ScoutingViewModel::class.java) +fun ScoutingView(navController: NavController, viewModel: ScoutingViewModel, scoutingMatch: Boolean) { ScoutingTheme { Surface(modifier = Modifier.fillMaxSize()) { Column { diff --git a/app/src/main/java/com/scouting/app/view/scouting/StartMatchView.kt b/app/src/main/java/com/scouting/app/view/scouting/StartMatchView.kt index e7d8a9d..dfa5e35 100644 --- a/app/src/main/java/com/scouting/app/view/scouting/StartMatchView.kt +++ b/app/src/main/java/com/scouting/app/view/scouting/StartMatchView.kt @@ -14,21 +14,23 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.* import com.scouting.app.misc.* import com.scouting.app.theme.AffirmativeGreen import com.scouting.app.theme.AffirmativeGreenDark import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel +import com.scouting.app.utilities.composableContext import com.scouting.app.viewmodel.ScoutingViewModel import com.tencent.mmkv.MMKV @Composable -fun StartMatchView(navController: NavController, scoutingScheduleManager: ScoutingScheduleManager) { - val context = navController.context as MainActivity - val viewModel = context.getViewModel(ScoutingViewModel::class.java) +fun StartMatchView( + navController: NavController, + scoutingScheduleManager: ScoutingScheduleManager, + viewModel: ScoutingViewModel +) { + val context = composableContext var managedMatch by remember { mutableStateOf(false) } LaunchedEffect(true) { viewModel.apply { @@ -129,5 +131,5 @@ fun StartMatchView(navController: NavController, scoutingScheduleManager: Scouti } } } - NoTemplateDialog(viewModel, navController) + NoTemplateDialog(navController, viewModel) } \ No newline at end of file diff --git a/app/src/main/java/com/scouting/app/view/scouting/StartPitScoutingView.kt b/app/src/main/java/com/scouting/app/view/scouting/StartPitScoutingView.kt index 8c8b3df..b135c00 100644 --- a/app/src/main/java/com/scouting/app/view/scouting/StartPitScoutingView.kt +++ b/app/src/main/java/com/scouting/app/view/scouting/StartPitScoutingView.kt @@ -8,13 +8,13 @@ import androidx.compose.foundation.layout.width import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.BasicInputField import com.scouting.app.components.LargeButton @@ -26,13 +26,16 @@ import com.scouting.app.misc.ScoutingType import com.scouting.app.theme.AffirmativeGreen import com.scouting.app.theme.AffirmativeGreenDark import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel +import com.scouting.app.utilities.composableContext import com.scouting.app.viewmodel.ScoutingViewModel @Composable -fun StartPitScoutingView(navController: NavController, scoutingScheduleManager: ScoutingScheduleManager) { - val context = navController.context as MainActivity - val viewModel = context.getViewModel(ScoutingViewModel::class.java) +fun StartPitScoutingView( + navController: NavController, + scoutingScheduleManager: ScoutingScheduleManager, + viewModel: ScoutingViewModel +) { + val context = composableContext LaunchedEffect(true) { viewModel.apply { this.scoutingScheduleManager = scoutingScheduleManager @@ -108,5 +111,5 @@ fun StartPitScoutingView(navController: NavController, scoutingScheduleManager: } } } - NoTemplateDialog(viewModel, navController) + NoTemplateDialog(navController, viewModel) } \ No newline at end of file diff --git a/app/src/main/java/com/scouting/app/view/settings/DevicePositionDialog.kt b/app/src/main/java/com/scouting/app/view/settings/DevicePositionDialog.kt index 9c8682e..54d5014 100644 --- a/app/src/main/java/com/scouting/app/view/settings/DevicePositionDialog.kt +++ b/app/src/main/java/com/scouting/app/view/settings/DevicePositionDialog.kt @@ -9,19 +9,18 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.DialogScaffold import com.scouting.app.components.RatingBar import com.scouting.app.components.SmallButton import com.scouting.app.components.SpacedRow import com.scouting.app.misc.AllianceType +import com.scouting.app.utilities.composableContext import com.scouting.app.viewmodel.SettingsViewModel @Composable -fun DevicePositionDialog(viewModel: SettingsViewModel, navController: NavController) { - val context = navController.context as MainActivity +fun DevicePositionDialog(viewModel: SettingsViewModel) { + val context = composableContext if (viewModel.showingDevicePositionDialog) { DialogScaffold( icon = painterResource(id = R.drawable.ic_machine_learning), diff --git a/app/src/main/java/com/scouting/app/view/settings/SettingsView.kt b/app/src/main/java/com/scouting/app/view/settings/SettingsView.kt index 1d9a9ee..ee5a7c6 100644 --- a/app/src/main/java/com/scouting/app/view/settings/SettingsView.kt +++ b/app/src/main/java/com/scouting/app/view/settings/SettingsView.kt @@ -13,7 +13,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.LargeHeaderBar import com.scouting.app.components.MediumButton @@ -25,14 +24,17 @@ import com.scouting.app.misc.ScoutingScheduleManager import com.scouting.app.misc.ScoutingType import com.scouting.app.theme.NeutralGrayLight import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel +import com.scouting.app.utilities.composableContext import com.scouting.app.viewmodel.SettingsViewModel import com.tencent.mmkv.MMKV @Composable -fun SettingsView(navController: NavController, scoutingScheduleManager: ScoutingScheduleManager) { - val context = navController.context as MainActivity - val viewModel = context.getViewModel(SettingsViewModel::class.java) +fun SettingsView( + navController: NavController, + scoutingScheduleManager: ScoutingScheduleManager, + viewModel: SettingsViewModel +) { + val context = composableContext val preferences = MMKV.defaultMMKV() LaunchedEffect(true) { viewModel.apply { @@ -272,7 +274,7 @@ fun SettingsView(navController: NavController, scoutingScheduleManager: Scouting } } FileNameDialog(viewModel) - DevicePositionDialog(viewModel, navController) + DevicePositionDialog(viewModel) CompetitionModeDialog(viewModel) } } diff --git a/app/src/main/java/com/scouting/app/view/template/EditCSVOrderView.kt b/app/src/main/java/com/scouting/app/view/template/EditCSVOrderView.kt index f431db0..3446390 100644 --- a/app/src/main/java/com/scouting/app/view/template/EditCSVOrderView.kt +++ b/app/src/main/java/com/scouting/app/view/template/EditCSVOrderView.kt @@ -12,7 +12,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle @@ -27,7 +26,6 @@ import com.scouting.app.misc.NavDestination import com.scouting.app.misc.TemplateTypes import com.scouting.app.theme.NeutralGrayMedium import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel import com.scouting.app.utilities.longPressEffect import com.scouting.app.viewmodel.TemplateEditorViewModel import org.burnoutcrew.reorderable.detectReorderAfterLongPress @@ -36,8 +34,7 @@ import org.burnoutcrew.reorderable.rememberReorderState import org.burnoutcrew.reorderable.reorderable @Composable -fun EditCSVOrderView(navController: NavController) { - val viewModel = LocalContext.current.getViewModel(TemplateEditorViewModel::class.java) +fun EditCSVOrderView(navController: NavController, viewModel: TemplateEditorViewModel) { val listReorderState = rememberReorderState() ScoutingTheme { Surface(modifier = Modifier.fillMaxSize()) { diff --git a/app/src/main/java/com/scouting/app/view/template/EditTemplateDialog.kt b/app/src/main/java/com/scouting/app/view/template/EditTemplateDialog.kt index 4a0e479..7ac44a3 100644 --- a/app/src/main/java/com/scouting/app/view/template/EditTemplateDialog.kt +++ b/app/src/main/java/com/scouting/app/view/template/EditTemplateDialog.kt @@ -1,6 +1,5 @@ package com.scouting.app.view.template -import android.content.Context import androidx.compose.foundation.layout.* import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.* @@ -10,7 +9,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.BasicInputField import com.scouting.app.components.DialogScaffold @@ -20,10 +18,12 @@ import com.scouting.app.misc.RequestCode import com.scouting.app.misc.TemplateTypes import com.scouting.app.theme.NeutralGrayDark import com.scouting.app.theme.NeutralGrayMedium +import com.scouting.app.utilities.composableContext import com.scouting.app.viewmodel.TemplateEditorViewModel @Composable -fun EditTemplateDialog(viewModel: TemplateEditorViewModel, context: Context) { +fun EditTemplateDialog(viewModel: TemplateEditorViewModel) { + val context = composableContext if (viewModel.showingEditDialog) { DialogScaffold( icon = painterResource(id = R.drawable.ic_edit_pen), @@ -167,7 +167,7 @@ fun EditTemplateDialog(viewModel: TemplateEditorViewModel, context: Context) { LargeButton( text = stringResource(id = R.string.template_edit_image_edit_hint_text), onClick = { - (context as MainActivity).requestFilePicker( + context.requestFilePicker( code = RequestCode.TEMPLATE_EDITOR_IMAGE_FILE_PICK, type = arrayOf("png", "jpeg", "jpg") ) diff --git a/app/src/main/java/com/scouting/app/view/template/TemplateEditorView.kt b/app/src/main/java/com/scouting/app/view/template/TemplateEditorView.kt index 45e8009..7bb5f15 100644 --- a/app/src/main/java/com/scouting/app/view/template/TemplateEditorView.kt +++ b/app/src/main/java/com/scouting/app/view/template/TemplateEditorView.kt @@ -31,7 +31,6 @@ import com.scouting.app.misc.NavDestination import com.scouting.app.misc.ScoutingType import com.scouting.app.misc.TemplateTypes import com.scouting.app.model.TemplateItem -import com.scouting.app.utilities.getViewModel import com.scouting.app.utilities.longPressEffect import com.scouting.app.viewmodel.TemplateEditorViewModel import kotlinx.coroutines.launch @@ -42,8 +41,7 @@ import org.burnoutcrew.reorderable.reorderable @Composable @OptIn(ExperimentalPagerApi::class, ExperimentalMaterialApi::class) -fun TemplateEditorView(navController: NavController, type: String? = null) { - val viewModel = navController.context.getViewModel(TemplateEditorViewModel::class.java) +fun TemplateEditorView(navController: NavController, viewModel: TemplateEditorViewModel, type: String? = null) { val bottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden) val pagerState = rememberPagerState(initialPage = 0) type?.let { viewModel.currentTemplateType = ScoutingType.valueOf(it) } @@ -99,8 +97,7 @@ fun TemplateEditorView(navController: NavController, type: String? = null) { } } EditTemplateDialog( - viewModel = viewModel, - context = navController.context + viewModel = viewModel ) } } diff --git a/app/src/main/java/com/scouting/app/view/template/TemplateSaveView.kt b/app/src/main/java/com/scouting/app/view/template/TemplateSaveView.kt index 56f66b0..f80b2d5 100644 --- a/app/src/main/java/com/scouting/app/view/template/TemplateSaveView.kt +++ b/app/src/main/java/com/scouting/app/view/template/TemplateSaveView.kt @@ -3,27 +3,30 @@ package com.scouting.app.view.template import android.widget.Toast import androidx.compose.foundation.layout.* import androidx.compose.material3.* -import androidx.compose.runtime.Composable import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.BasicInputField import com.scouting.app.components.LargeHeaderBar import com.scouting.app.components.MediumButton import com.scouting.app.misc.NavDestination import com.scouting.app.theme.ScoutingTheme -import com.scouting.app.utilities.getViewModel +import com.scouting.app.utilities.composableContext import com.scouting.app.utilities.returnTo +import com.scouting.app.viewmodel.SettingsViewModel import com.scouting.app.viewmodel.TemplateEditorViewModel @Composable -fun TemplateSaveView(navController: NavController) { - val viewModel = navController.context.getViewModel(TemplateEditorViewModel::class.java) +fun TemplateSaveView( + navController: NavController, + viewModel: TemplateEditorViewModel, + settingsViewModel: SettingsViewModel +) { + val context = composableContext var setAsDefaultTemplate by remember { mutableStateOf(false) } ScoutingTheme { Surface { @@ -80,22 +83,20 @@ fun TemplateSaveView(navController: NavController) { icon = painterResource(id = R.drawable.ic_document_export), contentDescription = stringResource(id = R.string.ic_document_export_content_desc), onClick = { - navController.apply { - if (viewModel.finalFileName.text.isBlank()) { - Toast.makeText( - context, - context.getString(R.string.template_edit_save_fail_toast), - Toast.LENGTH_SHORT - ).show() - } else { - viewModel.writeTemplateToFile(context as MainActivity, setAsDefaultTemplate) - returnTo(NavDestination.HomePage) - Toast.makeText( - context, - context.getString(R.string.template_edit_save_success_toast), - Toast.LENGTH_LONG - ).show() - } + if (viewModel.finalFileName.text.isBlank()) { + Toast.makeText( + context, + context.getString(R.string.template_edit_save_fail_toast), + Toast.LENGTH_SHORT + ).show() + } else { + viewModel.writeTemplateToFile(context, settingsViewModel, setAsDefaultTemplate) + navController.returnTo(NavDestination.HomePage) + Toast.makeText( + context, + context.getString(R.string.template_edit_save_success_toast), + Toast.LENGTH_LONG + ).show() } }, color = MaterialTheme.colorScheme.secondary diff --git a/app/src/main/java/com/scouting/app/view/template/TemplateTypeDialog.kt b/app/src/main/java/com/scouting/app/view/template/TemplateTypeDialog.kt index 8bb4236..cf059a7 100644 --- a/app/src/main/java/com/scouting/app/view/template/TemplateTypeDialog.kt +++ b/app/src/main/java/com/scouting/app/view/template/TemplateTypeDialog.kt @@ -8,7 +8,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.scouting.app.MainActivity import com.scouting.app.R import com.scouting.app.components.DialogScaffold import com.scouting.app.components.LargeButton @@ -16,11 +15,12 @@ import com.scouting.app.misc.NavDestination import com.scouting.app.misc.RequestCode import com.scouting.app.theme.NeutralGrayDark import com.scouting.app.theme.NeutralGrayMedium +import com.scouting.app.utilities.composableContext import com.scouting.app.viewmodel.HomePageViewModel @Composable -fun TemplateTypeDialog(viewModel: HomePageViewModel, navController: NavController) { - val context = navController.context as MainActivity +fun TemplateTypeDialog(navController: NavController, viewModel: HomePageViewModel) { + val context = composableContext if (viewModel.showingTemplateTypeDialog) { DialogScaffold( icon = painterResource(id = R.drawable.ic_server_wired), diff --git a/app/src/main/java/com/scouting/app/viewmodel/TemplateEditorViewModel.kt b/app/src/main/java/com/scouting/app/viewmodel/TemplateEditorViewModel.kt index ccaba95..dcfa31c 100755 --- a/app/src/main/java/com/scouting/app/viewmodel/TemplateEditorViewModel.kt +++ b/app/src/main/java/com/scouting/app/viewmodel/TemplateEditorViewModel.kt @@ -20,7 +20,6 @@ import com.scouting.app.misc.TemplateTypes import com.scouting.app.model.TemplateFormatMatch import com.scouting.app.model.TemplateFormatPit import com.scouting.app.model.TemplateItem -import com.scouting.app.utilities.getViewModel import org.json.JSONObject import java.io.ByteArrayOutputStream import java.io.File @@ -76,7 +75,11 @@ class TemplateEditorViewModel : ViewModel() { * @param context - MainActivity context needed to use ContentResolver * to write to a file efficiently */ - fun writeTemplateToFile(context: MainActivity, setTemplateAsDefault: Boolean = false) { + fun writeTemplateToFile( + context: MainActivity, + settingsViewModel: SettingsViewModel, + setTemplateAsDefault: Boolean = false + ) { val outputFile = File(FilePaths.TEMPLATE_DIRECTORY, processFinalFileName()) val template: Any = if (currentTemplateType == MATCH) { TemplateFormatMatch( @@ -98,7 +101,6 @@ class TemplateEditorViewModel : ViewModel() { it.close() } if (setTemplateAsDefault) { - val settingsViewModel = context.getViewModel(SettingsViewModel::class.java) settingsViewModel.processTemplateFilePickerResult(outputFile.path, context, currentTemplateType == MATCH) } resetInstanceData()