UI fix 2/5: lifecycle-aware StateFlow collection in screens
Replace collectAsState() with collectAsStateWithLifecycle() so StateFlows stop collecting when the host is in background — prevents memory/CPU leaks on lifecycle transitions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.AddNewTaskWithResidenceDialog
|
||||
import com.tt.honeyDue.ui.components.ApiResultHandler
|
||||
import com.tt.honeyDue.ui.components.CompleteTaskDialog
|
||||
@@ -38,10 +39,10 @@ fun AllTasksScreen(
|
||||
onClearNavigateToTask: () -> Unit = {},
|
||||
onNavigateToCompleteTask: ((TaskDetail, String) -> Unit)? = null
|
||||
) {
|
||||
val tasksState by viewModel.tasksState.collectAsState()
|
||||
val completionState by taskCompletionViewModel.createCompletionState.collectAsState()
|
||||
val myResidencesState by residenceViewModel.myResidencesState.collectAsState()
|
||||
val createTaskState by viewModel.taskAddNewCustomTaskState.collectAsState()
|
||||
val tasksState by viewModel.tasksState.collectAsStateWithLifecycle()
|
||||
val completionState by taskCompletionViewModel.createCompletionState.collectAsStateWithLifecycle()
|
||||
val myResidencesState by residenceViewModel.myResidencesState.collectAsStateWithLifecycle()
|
||||
val createTaskState by viewModel.taskAddNewCustomTaskState.collectAsStateWithLifecycle()
|
||||
|
||||
var showCompleteDialog by remember { mutableStateOf(false) }
|
||||
var showNewTaskDialog by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import honeydue.composeapp.generated.resources.*
|
||||
import com.tt.honeyDue.models.TaskCompletionCreateRequest
|
||||
import com.tt.honeyDue.models.ContractorSummary
|
||||
@@ -55,7 +56,7 @@ fun CompleteTaskScreen(
|
||||
var showContractorPicker by remember { mutableStateOf(false) }
|
||||
var isSubmitting by remember { mutableStateOf(false) }
|
||||
|
||||
val contractorsState by contractorViewModel.contractorsState.collectAsState()
|
||||
val contractorsState by contractorViewModel.contractorsState.collectAsStateWithLifecycle()
|
||||
val hapticFeedback = rememberHapticFeedback()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
import com.tt.honeyDue.ui.components.AddContractorDialog
|
||||
import com.tt.honeyDue.ui.components.ApiResultHandler
|
||||
@@ -39,9 +40,9 @@ fun ContractorDetailScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
viewModel: ContractorViewModel = viewModel { ContractorViewModel() }
|
||||
) {
|
||||
val contractorState by viewModel.contractorDetailState.collectAsState()
|
||||
val deleteState by viewModel.deleteState.collectAsState()
|
||||
val toggleFavoriteState by viewModel.toggleFavoriteState.collectAsState()
|
||||
val contractorState by viewModel.contractorDetailState.collectAsStateWithLifecycle()
|
||||
val deleteState by viewModel.deleteState.collectAsStateWithLifecycle()
|
||||
val toggleFavoriteState by viewModel.toggleFavoriteState.collectAsStateWithLifecycle()
|
||||
|
||||
var showEditDialog by remember { mutableStateOf(false) }
|
||||
var showDeleteConfirmation by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.AddContractorDialog
|
||||
import com.tt.honeyDue.ui.components.ApiResultHandler
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
@@ -37,10 +38,10 @@ fun ContractorsScreen(
|
||||
onNavigateToContractorDetail: (Int) -> Unit,
|
||||
viewModel: ContractorViewModel = viewModel { ContractorViewModel() }
|
||||
) {
|
||||
val contractorsState by viewModel.contractorsState.collectAsState()
|
||||
val deleteState by viewModel.deleteState.collectAsState()
|
||||
val toggleFavoriteState by viewModel.toggleFavoriteState.collectAsState()
|
||||
val contractorSpecialties by LookupsRepository.contractorSpecialties.collectAsState()
|
||||
val contractorsState by viewModel.contractorsState.collectAsStateWithLifecycle()
|
||||
val deleteState by viewModel.deleteState.collectAsStateWithLifecycle()
|
||||
val toggleFavoriteState by viewModel.toggleFavoriteState.collectAsStateWithLifecycle()
|
||||
val contractorSpecialties by LookupsRepository.contractorSpecialties.collectAsStateWithLifecycle()
|
||||
|
||||
// Check if screen should be blocked (limit=0)
|
||||
val isBlocked = SubscriptionHelper.isContractorsBlocked()
|
||||
|
||||
@@ -33,6 +33,7 @@ import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import coil3.compose.SubcomposeAsyncImage
|
||||
import coil3.compose.SubcomposeAsyncImageContent
|
||||
import coil3.compose.AsyncImagePainter
|
||||
@@ -50,8 +51,8 @@ fun DocumentDetailScreen(
|
||||
onNavigateToEdit: (Int) -> Unit,
|
||||
documentViewModel: DocumentViewModel = viewModel { DocumentViewModel() }
|
||||
) {
|
||||
val documentState by documentViewModel.documentDetailState.collectAsState()
|
||||
val deleteState by documentViewModel.deleteState.collectAsState()
|
||||
val documentState by documentViewModel.documentDetailState.collectAsStateWithLifecycle()
|
||||
val deleteState by documentViewModel.deleteState.collectAsStateWithLifecycle()
|
||||
var showDeleteDialog by remember { mutableStateOf(false) }
|
||||
var showPhotoViewer by remember { mutableStateOf(false) }
|
||||
var selectedPhotoIndex by remember { mutableStateOf(0) }
|
||||
|
||||
@@ -18,6 +18,7 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import coil3.compose.AsyncImage
|
||||
import com.tt.honeyDue.ui.components.AuthenticatedImage
|
||||
import com.tt.honeyDue.viewmodel.DocumentViewModel
|
||||
@@ -83,12 +84,12 @@ fun DocumentFormScreen(
|
||||
var providerError by remember { mutableStateOf("") }
|
||||
var residenceError by remember { mutableStateOf("") }
|
||||
|
||||
val residencesState by residenceViewModel.residencesState.collectAsState()
|
||||
val documentDetailState by documentViewModel.documentDetailState.collectAsState()
|
||||
val residencesState by residenceViewModel.residencesState.collectAsStateWithLifecycle()
|
||||
val documentDetailState by documentViewModel.documentDetailState.collectAsStateWithLifecycle()
|
||||
val operationState by if (isEditMode) {
|
||||
documentViewModel.updateState.collectAsState()
|
||||
documentViewModel.updateState.collectAsStateWithLifecycle()
|
||||
} else {
|
||||
documentViewModel.createState.collectAsState()
|
||||
documentViewModel.createState.collectAsStateWithLifecycle()
|
||||
}
|
||||
|
||||
val isWarranty = selectedDocumentType == "warranty"
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.documents.DocumentsTabContent
|
||||
import com.tt.honeyDue.ui.subscription.UpgradeFeatureScreen
|
||||
import com.tt.honeyDue.utils.SubscriptionHelper
|
||||
@@ -37,7 +38,7 @@ fun DocumentsScreen(
|
||||
documentViewModel: DocumentViewModel = viewModel { DocumentViewModel() }
|
||||
) {
|
||||
var selectedTab by remember { mutableStateOf(DocumentTab.WARRANTIES) }
|
||||
val documentsState by documentViewModel.documentsState.collectAsState()
|
||||
val documentsState by documentViewModel.documentsState.collectAsStateWithLifecycle()
|
||||
|
||||
// Check if screen should be blocked (limit=0)
|
||||
val isBlocked = SubscriptionHelper.isDocumentsBlocked()
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.viewmodel.ResidenceViewModel
|
||||
import com.tt.honeyDue.repository.LookupsRepository
|
||||
@@ -43,10 +44,10 @@ fun EditTaskScreen(
|
||||
var frequencyExpanded by remember { mutableStateOf(false) }
|
||||
var priorityExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
val updateTaskState by viewModel.updateTaskState.collectAsState()
|
||||
val categories by LookupsRepository.taskCategories.collectAsState()
|
||||
val frequencies by LookupsRepository.taskFrequencies.collectAsState()
|
||||
val priorities by LookupsRepository.taskPriorities.collectAsState()
|
||||
val updateTaskState by viewModel.updateTaskState.collectAsStateWithLifecycle()
|
||||
val categories by LookupsRepository.taskCategories.collectAsStateWithLifecycle()
|
||||
val frequencies by LookupsRepository.taskFrequencies.collectAsStateWithLifecycle()
|
||||
val priorities by LookupsRepository.taskPriorities.collectAsStateWithLifecycle()
|
||||
|
||||
// Validation errors
|
||||
var titleError by remember { mutableStateOf("") }
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.components.auth.AuthHeader
|
||||
import com.tt.honeyDue.ui.components.common.ErrorCard
|
||||
@@ -30,8 +31,8 @@ fun ForgotPasswordScreen(
|
||||
viewModel: PasswordResetViewModel
|
||||
) {
|
||||
var email by remember { mutableStateOf("") }
|
||||
val forgotPasswordState by viewModel.forgotPasswordState.collectAsState()
|
||||
val currentStep by viewModel.currentStep.collectAsState()
|
||||
val forgotPasswordState by viewModel.forgotPasswordState.collectAsStateWithLifecycle()
|
||||
val currentStep by viewModel.currentStep.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for forgot password
|
||||
forgotPasswordState.HandleErrors(
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.ResidenceViewModel
|
||||
@@ -29,8 +30,8 @@ fun HomeScreen(
|
||||
viewModel: ResidenceViewModel = viewModel { ResidenceViewModel() },
|
||||
taskViewModel: TaskViewModel = viewModel { TaskViewModel() }
|
||||
) {
|
||||
val summaryState by viewModel.myResidencesState.collectAsState()
|
||||
val totalSummary by DataManager.totalSummary.collectAsState()
|
||||
val summaryState by viewModel.myResidencesState.collectAsStateWithLifecycle()
|
||||
val totalSummary by DataManager.totalSummary.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.loadMyResidences()
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.components.auth.AuthHeader
|
||||
import com.tt.honeyDue.ui.components.auth.GoogleSignInButton
|
||||
@@ -44,8 +45,8 @@ fun LoginScreen(
|
||||
var password by remember { mutableStateOf("") }
|
||||
var passwordVisible by remember { mutableStateOf(false) }
|
||||
var googleSignInError by remember { mutableStateOf<String?>(null) }
|
||||
val loginState by viewModel.loginState.collectAsState()
|
||||
val googleSignInState by viewModel.googleSignInState.collectAsState()
|
||||
val loginState by viewModel.loginState.collectAsStateWithLifecycle()
|
||||
val googleSignInState by viewModel.googleSignInState.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for login
|
||||
loginState.HandleErrors(
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.analytics.AnalyticsEvents
|
||||
import com.tt.honeyDue.analytics.PostHogAnalytics
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
@@ -57,8 +58,8 @@ fun NotificationPreferencesScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
viewModel: NotificationPreferencesViewModel = viewModel { NotificationPreferencesViewModel() },
|
||||
) {
|
||||
val preferencesState by viewModel.preferencesState.collectAsState()
|
||||
val categoryState by viewModel.categoryState.collectAsState()
|
||||
val preferencesState by viewModel.preferencesState.collectAsStateWithLifecycle()
|
||||
val categoryState by viewModel.categoryState.collectAsStateWithLifecycle()
|
||||
|
||||
// Platform-specific wiring: Android provides real controller + settings
|
||||
// launcher; every other target returns null and the matching section
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.tt.honeyDue.network.APILayer
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
import com.tt.honeyDue.ui.subscription.UpgradePromptDialog
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.analytics.PostHogAnalytics
|
||||
import com.tt.honeyDue.analytics.AnalyticsEvents
|
||||
import com.tt.honeyDue.platform.BiometricResult
|
||||
@@ -64,11 +65,11 @@ fun ProfileScreen(
|
||||
val isBiometricAvailable = remember { biometricAuth.isBiometricAvailable() }
|
||||
var isBiometricEnabled by remember { mutableStateOf(BiometricPreference.isBiometricEnabled()) }
|
||||
|
||||
val updateState by viewModel.updateProfileState.collectAsState()
|
||||
val deleteAccountState by viewModel.deleteAccountState.collectAsState()
|
||||
val updateState by viewModel.updateProfileState.collectAsStateWithLifecycle()
|
||||
val deleteAccountState by viewModel.deleteAccountState.collectAsStateWithLifecycle()
|
||||
val currentTheme by remember { derivedStateOf { ThemeManager.currentTheme } }
|
||||
val currentSubscription by DataManager.subscription.collectAsState()
|
||||
val currentUser by DataManager.currentUser.collectAsState()
|
||||
val currentSubscription by DataManager.subscription.collectAsStateWithLifecycle()
|
||||
val currentUser by DataManager.currentUser.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for profile update
|
||||
updateState.HandleErrors(
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.components.auth.AuthHeader
|
||||
import com.tt.honeyDue.ui.components.auth.RequirementItem
|
||||
@@ -41,7 +42,7 @@ fun RegisterScreen(
|
||||
var errorMessage by remember { mutableStateOf("") }
|
||||
var isLoading by remember { mutableStateOf(false) }
|
||||
|
||||
val createState by viewModel.registerState.collectAsState()
|
||||
val createState by viewModel.registerState.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for registration
|
||||
createState.HandleErrors(
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.components.auth.AuthHeader
|
||||
import com.tt.honeyDue.ui.components.auth.RequirementItem
|
||||
@@ -35,9 +36,9 @@ fun ResetPasswordScreen(
|
||||
var newPasswordVisible by remember { mutableStateOf(false) }
|
||||
var confirmPasswordVisible by remember { mutableStateOf(false) }
|
||||
|
||||
val resetPasswordState by viewModel.resetPasswordState.collectAsState()
|
||||
val loginState by viewModel.loginState.collectAsState()
|
||||
val currentStep by viewModel.currentStep.collectAsState()
|
||||
val resetPasswordState by viewModel.resetPasswordState.collectAsStateWithLifecycle()
|
||||
val loginState by viewModel.loginState.collectAsStateWithLifecycle()
|
||||
val currentStep by viewModel.currentStep.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for password reset
|
||||
resetPasswordState.HandleErrors(
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.AddNewTaskDialog
|
||||
import com.tt.honeyDue.ui.components.ApiResultHandler
|
||||
import com.tt.honeyDue.ui.components.CompleteTaskDialog
|
||||
@@ -57,13 +58,13 @@ fun ResidenceDetailScreen(
|
||||
taskViewModel: TaskViewModel = viewModel { TaskViewModel() }
|
||||
) {
|
||||
var residenceState by remember { mutableStateOf<ApiResult<Residence>>(ApiResult.Loading) }
|
||||
val tasksState by residenceViewModel.residenceTasksState.collectAsState()
|
||||
val contractorsState by residenceViewModel.residenceContractorsState.collectAsState()
|
||||
val completionState by taskCompletionViewModel.createCompletionState.collectAsState()
|
||||
val taskAddNewTaskState by taskViewModel.taskAddNewCustomTaskState.collectAsState()
|
||||
val cancelTaskState by residenceViewModel.cancelTaskState.collectAsState()
|
||||
val uncancelTaskState by residenceViewModel.uncancelTaskState.collectAsState()
|
||||
val generateReportState by residenceViewModel.generateReportState.collectAsState()
|
||||
val tasksState by residenceViewModel.residenceTasksState.collectAsStateWithLifecycle()
|
||||
val contractorsState by residenceViewModel.residenceContractorsState.collectAsStateWithLifecycle()
|
||||
val completionState by taskCompletionViewModel.createCompletionState.collectAsStateWithLifecycle()
|
||||
val taskAddNewTaskState by taskViewModel.taskAddNewCustomTaskState.collectAsStateWithLifecycle()
|
||||
val cancelTaskState by residenceViewModel.cancelTaskState.collectAsStateWithLifecycle()
|
||||
val uncancelTaskState by residenceViewModel.uncancelTaskState.collectAsStateWithLifecycle()
|
||||
val generateReportState by residenceViewModel.generateReportState.collectAsStateWithLifecycle()
|
||||
|
||||
var showCompleteDialog by remember { mutableStateOf(false) }
|
||||
var selectedTask by remember { mutableStateOf<TaskDetail?>(null) }
|
||||
@@ -77,12 +78,12 @@ fun ResidenceDetailScreen(
|
||||
var showArchiveTaskConfirmation by remember { mutableStateOf(false) }
|
||||
var taskToCancel by remember { mutableStateOf<TaskDetail?>(null) }
|
||||
var taskToArchive by remember { mutableStateOf<TaskDetail?>(null) }
|
||||
val deleteState by residenceViewModel.deleteResidenceState.collectAsState()
|
||||
val deleteState by residenceViewModel.deleteResidenceState.collectAsStateWithLifecycle()
|
||||
var showUpgradePrompt by remember { mutableStateOf(false) }
|
||||
var upgradeTriggerKey by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
// Get current user for ownership checks
|
||||
val currentUser by DataManager.currentUser.collectAsState()
|
||||
val currentUser by DataManager.currentUser.collectAsStateWithLifecycle()
|
||||
|
||||
// Residence sharing state and function
|
||||
val (shareState, shareResidence) = rememberShareResidence()
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.viewmodel.ResidenceViewModel
|
||||
import com.tt.honeyDue.repository.LookupsRepository
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
@@ -59,12 +60,12 @@ fun ResidenceFormScreen(
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
val operationState by if (isEditMode) {
|
||||
viewModel.updateResidenceState.collectAsState()
|
||||
viewModel.updateResidenceState.collectAsStateWithLifecycle()
|
||||
} else {
|
||||
viewModel.createResidenceState.collectAsState()
|
||||
viewModel.createResidenceState.collectAsStateWithLifecycle()
|
||||
}
|
||||
val propertyTypes by LookupsRepository.residenceTypes.collectAsState()
|
||||
val currentUser by DataManager.currentUser.collectAsState()
|
||||
val propertyTypes by LookupsRepository.residenceTypes.collectAsStateWithLifecycle()
|
||||
val currentUser by DataManager.currentUser.collectAsStateWithLifecycle()
|
||||
|
||||
// Check if current user is the owner
|
||||
val isCurrentUserOwner = remember(existingResidence, currentUser) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.ApiResultHandler
|
||||
import com.tt.honeyDue.ui.components.common.StatItem
|
||||
import com.tt.honeyDue.ui.components.residence.TaskStatChip
|
||||
@@ -51,8 +52,8 @@ fun ResidencesScreen(
|
||||
viewModel: ResidenceViewModel = viewModel { ResidenceViewModel() },
|
||||
taskViewModel: TaskViewModel = viewModel { TaskViewModel() }
|
||||
) {
|
||||
val myResidencesState by viewModel.myResidencesState.collectAsState()
|
||||
val totalSummary by DataManager.totalSummary.collectAsState()
|
||||
val myResidencesState by viewModel.myResidencesState.collectAsStateWithLifecycle()
|
||||
val totalSummary by DataManager.totalSummary.collectAsStateWithLifecycle()
|
||||
var isRefreshing by remember { mutableStateOf(false) }
|
||||
var showUpgradePrompt by remember { mutableStateOf(false) }
|
||||
var upgradeTriggerKey by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.CompleteTaskDialog
|
||||
import com.tt.honeyDue.ui.components.ErrorDialog
|
||||
import com.tt.honeyDue.ui.components.task.TaskCard
|
||||
@@ -35,8 +36,8 @@ fun TasksScreen(
|
||||
viewModel: TaskViewModel = viewModel { TaskViewModel() },
|
||||
taskCompletionViewModel: TaskCompletionViewModel = viewModel { TaskCompletionViewModel() }
|
||||
) {
|
||||
val tasksState by viewModel.tasksState.collectAsState()
|
||||
val completionState by taskCompletionViewModel.createCompletionState.collectAsState()
|
||||
val tasksState by viewModel.tasksState.collectAsStateWithLifecycle()
|
||||
val completionState by taskCompletionViewModel.createCompletionState.collectAsStateWithLifecycle()
|
||||
var expandedColumns by remember { mutableStateOf(setOf<String>()) }
|
||||
var showCompleteDialog by remember { mutableStateOf(false) }
|
||||
var selectedTask by remember { mutableStateOf<com.tt.honeyDue.models.TaskDetail?>(null) }
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.components.auth.AuthHeader
|
||||
import com.tt.honeyDue.ui.components.common.ErrorCard
|
||||
@@ -35,7 +36,7 @@ fun VerifyEmailScreen(
|
||||
var errorMessage by remember { mutableStateOf("") }
|
||||
var isLoading by remember { mutableStateOf(false) }
|
||||
|
||||
val verifyState by viewModel.verifyEmailState.collectAsState()
|
||||
val verifyState by viewModel.verifyEmailState.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for email verification
|
||||
verifyState.HandleErrors(
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.components.HandleErrors
|
||||
import com.tt.honeyDue.ui.components.auth.AuthHeader
|
||||
import com.tt.honeyDue.ui.components.common.ErrorCard
|
||||
@@ -30,9 +31,9 @@ fun VerifyResetCodeScreen(
|
||||
viewModel: PasswordResetViewModel
|
||||
) {
|
||||
var code by remember { mutableStateOf("") }
|
||||
val email by viewModel.email.collectAsState()
|
||||
val verifyCodeState by viewModel.verifyCodeState.collectAsState()
|
||||
val currentStep by viewModel.currentStep.collectAsState()
|
||||
val email by viewModel.email.collectAsStateWithLifecycle()
|
||||
val verifyCodeState by viewModel.verifyCodeState.collectAsStateWithLifecycle()
|
||||
val currentStep by viewModel.currentStep.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle errors for code verification
|
||||
verifyCodeState.HandleErrors(
|
||||
|
||||
@@ -19,6 +19,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
import com.tt.honeyDue.ui.components.auth.RequirementItem
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
@@ -39,7 +40,7 @@ fun OnboardingCreateAccountContent(
|
||||
var showLoginDialog by remember { mutableStateOf(false) }
|
||||
var localErrorMessage by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
val registerState by viewModel.registerState.collectAsState()
|
||||
val registerState by viewModel.registerState.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(registerState) {
|
||||
when (registerState) {
|
||||
@@ -327,7 +328,7 @@ private fun OnboardingLoginDialog(
|
||||
) {
|
||||
var username by remember { mutableStateOf("") }
|
||||
var password by remember { mutableStateOf("") }
|
||||
val loginState by viewModel.loginState.collectAsState()
|
||||
val loginState by viewModel.loginState.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(loginState) {
|
||||
when (loginState) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.analytics.AnalyticsEvents
|
||||
import com.tt.honeyDue.analytics.PostHogAnalytics
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
@@ -71,9 +72,9 @@ fun OnboardingFirstTaskContent(
|
||||
var isCreatingTasks by remember { mutableStateOf(false) }
|
||||
var selectedTabIndex by remember { mutableStateOf(0) }
|
||||
|
||||
val createTasksState by viewModel.createTasksState.collectAsState()
|
||||
val suggestionsState by viewModel.suggestionsState.collectAsState()
|
||||
val templatesGroupedState by viewModel.templatesGroupedState.collectAsState()
|
||||
val createTasksState by viewModel.createTasksState.collectAsStateWithLifecycle()
|
||||
val suggestionsState by viewModel.suggestionsState.collectAsStateWithLifecycle()
|
||||
val templatesGroupedState by viewModel.templatesGroupedState.collectAsStateWithLifecycle()
|
||||
|
||||
// Kick off both network calls on mount. Suggestions needs a residence;
|
||||
// the grouped catalog is user-independent and safe to load immediately.
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.models.HomeProfileOptions
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.OnboardingViewModel
|
||||
@@ -27,20 +28,20 @@ fun OnboardingHomeProfileContent(
|
||||
onContinue: () -> Unit,
|
||||
onSkip: () -> Unit
|
||||
) {
|
||||
val heatingType by viewModel.heatingType.collectAsState()
|
||||
val coolingType by viewModel.coolingType.collectAsState()
|
||||
val waterHeaterType by viewModel.waterHeaterType.collectAsState()
|
||||
val roofType by viewModel.roofType.collectAsState()
|
||||
val hasPool by viewModel.hasPool.collectAsState()
|
||||
val hasSprinklerSystem by viewModel.hasSprinklerSystem.collectAsState()
|
||||
val hasSeptic by viewModel.hasSeptic.collectAsState()
|
||||
val hasFireplace by viewModel.hasFireplace.collectAsState()
|
||||
val hasGarage by viewModel.hasGarage.collectAsState()
|
||||
val hasBasement by viewModel.hasBasement.collectAsState()
|
||||
val hasAttic by viewModel.hasAttic.collectAsState()
|
||||
val exteriorType by viewModel.exteriorType.collectAsState()
|
||||
val flooringPrimary by viewModel.flooringPrimary.collectAsState()
|
||||
val landscapingType by viewModel.landscapingType.collectAsState()
|
||||
val heatingType by viewModel.heatingType.collectAsStateWithLifecycle()
|
||||
val coolingType by viewModel.coolingType.collectAsStateWithLifecycle()
|
||||
val waterHeaterType by viewModel.waterHeaterType.collectAsStateWithLifecycle()
|
||||
val roofType by viewModel.roofType.collectAsStateWithLifecycle()
|
||||
val hasPool by viewModel.hasPool.collectAsStateWithLifecycle()
|
||||
val hasSprinklerSystem by viewModel.hasSprinklerSystem.collectAsStateWithLifecycle()
|
||||
val hasSeptic by viewModel.hasSeptic.collectAsStateWithLifecycle()
|
||||
val hasFireplace by viewModel.hasFireplace.collectAsStateWithLifecycle()
|
||||
val hasGarage by viewModel.hasGarage.collectAsStateWithLifecycle()
|
||||
val hasBasement by viewModel.hasBasement.collectAsStateWithLifecycle()
|
||||
val hasAttic by viewModel.hasAttic.collectAsStateWithLifecycle()
|
||||
val exteriorType by viewModel.exteriorType.collectAsStateWithLifecycle()
|
||||
val flooringPrimary by viewModel.flooringPrimary.collectAsStateWithLifecycle()
|
||||
val landscapingType by viewModel.landscapingType.collectAsStateWithLifecycle()
|
||||
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
LazyColumn(
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.OnboardingViewModel
|
||||
@@ -27,7 +28,7 @@ fun OnboardingJoinResidenceContent(
|
||||
var shareCode by remember { mutableStateOf("") }
|
||||
var localErrorMessage by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
val joinState by viewModel.joinResidenceState.collectAsState()
|
||||
val joinState by viewModel.joinResidenceState.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(joinState) {
|
||||
when (joinState) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.OnboardingViewModel
|
||||
import honeydue.composeapp.generated.resources.*
|
||||
@@ -22,7 +23,7 @@ fun OnboardingNameResidenceContent(
|
||||
viewModel: OnboardingViewModel,
|
||||
onContinue: () -> Unit
|
||||
) {
|
||||
val residenceName by viewModel.residenceName.collectAsState()
|
||||
val residenceName by viewModel.residenceName.collectAsStateWithLifecycle()
|
||||
var localName by remember { mutableStateOf(residenceName) }
|
||||
|
||||
WarmGradientBackground(
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.OnboardingStep
|
||||
import com.tt.honeyDue.viewmodel.OnboardingViewModel
|
||||
@@ -26,9 +27,9 @@ fun OnboardingScreen(
|
||||
onLoginSuccess: (Boolean) -> Unit, // Boolean = isVerified
|
||||
viewModel: OnboardingViewModel = viewModel { OnboardingViewModel() }
|
||||
) {
|
||||
val currentStep by viewModel.currentStep.collectAsState()
|
||||
val userIntent by viewModel.userIntent.collectAsState()
|
||||
val isComplete by viewModel.isComplete.collectAsState()
|
||||
val currentStep by viewModel.currentStep.collectAsStateWithLifecycle()
|
||||
val userIntent by viewModel.userIntent.collectAsStateWithLifecycle()
|
||||
val isComplete by viewModel.isComplete.collectAsStateWithLifecycle()
|
||||
|
||||
// Handle onboarding completion
|
||||
LaunchedEffect(isComplete) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.OnboardingViewModel
|
||||
@@ -27,7 +28,7 @@ fun OnboardingVerifyEmailContent(
|
||||
var code by remember { mutableStateOf("") }
|
||||
var localErrorMessage by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
val verifyState by viewModel.verifyEmailState.collectAsState()
|
||||
val verifyState by viewModel.verifyEmailState.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(verifyState) {
|
||||
when (verifyState) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.ui.theme.*
|
||||
import com.tt.honeyDue.viewmodel.AuthViewModel
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
@@ -152,7 +153,7 @@ private fun LoginDialog(
|
||||
val authViewModel: AuthViewModel = viewModel { AuthViewModel() }
|
||||
var username by remember { mutableStateOf("") }
|
||||
var password by remember { mutableStateOf("") }
|
||||
val loginState by authViewModel.loginState.collectAsState()
|
||||
val loginState by authViewModel.loginState.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(loginState) {
|
||||
when (loginState) {
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -39,6 +38,7 @@ import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
import com.tt.honeyDue.ui.components.common.StandardCard
|
||||
import com.tt.honeyDue.ui.components.forms.FormTextField
|
||||
@@ -62,9 +62,9 @@ fun JoinResidenceScreen(
|
||||
onJoined: (Int) -> Unit,
|
||||
viewModel: JoinResidenceViewModel = viewModel { JoinResidenceViewModel() },
|
||||
) {
|
||||
val code by viewModel.code.collectAsState()
|
||||
val error by viewModel.errorMessage.collectAsState()
|
||||
val submitState by viewModel.submitState.collectAsState()
|
||||
val code by viewModel.code.collectAsStateWithLifecycle()
|
||||
val error by viewModel.errorMessage.collectAsStateWithLifecycle()
|
||||
val submitState by viewModel.submitState.collectAsStateWithLifecycle()
|
||||
|
||||
val isLoading = submitState is ApiResult.Loading
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.analytics.AnalyticsEvents
|
||||
import com.tt.honeyDue.analytics.PostHogAnalytics
|
||||
import com.tt.honeyDue.data.DataManager
|
||||
@@ -71,7 +71,7 @@ fun FeatureComparisonScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToUpgrade: () -> Unit,
|
||||
) {
|
||||
val benefits by DataManager.featureBenefits.collectAsState()
|
||||
val benefits by DataManager.featureBenefits.collectAsStateWithLifecycle()
|
||||
val rows = FeatureComparisonScreenState.resolveFeatureRows(benefits)
|
||||
|
||||
Scaffold(
|
||||
|
||||
@@ -28,13 +28,13 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
import com.tt.honeyDue.repository.LookupsRepository
|
||||
import com.tt.honeyDue.ui.components.common.StandardCard
|
||||
@@ -65,20 +65,20 @@ fun AddTaskWithResidenceScreen(
|
||||
AddTaskWithResidenceViewModel(residenceId = residenceId)
|
||||
}
|
||||
) {
|
||||
val title by viewModel.title.collectAsState()
|
||||
val description by viewModel.description.collectAsState()
|
||||
val priorityId by viewModel.priorityId.collectAsState()
|
||||
val categoryId by viewModel.categoryId.collectAsState()
|
||||
val frequencyId by viewModel.frequencyId.collectAsState()
|
||||
val dueDate by viewModel.dueDate.collectAsState()
|
||||
val estimatedCost by viewModel.estimatedCost.collectAsState()
|
||||
val titleError by viewModel.titleError.collectAsState()
|
||||
val canSubmit by viewModel.canSubmit.collectAsState()
|
||||
val submitState by viewModel.submitState.collectAsState()
|
||||
val title by viewModel.title.collectAsStateWithLifecycle()
|
||||
val description by viewModel.description.collectAsStateWithLifecycle()
|
||||
val priorityId by viewModel.priorityId.collectAsStateWithLifecycle()
|
||||
val categoryId by viewModel.categoryId.collectAsStateWithLifecycle()
|
||||
val frequencyId by viewModel.frequencyId.collectAsStateWithLifecycle()
|
||||
val dueDate by viewModel.dueDate.collectAsStateWithLifecycle()
|
||||
val estimatedCost by viewModel.estimatedCost.collectAsStateWithLifecycle()
|
||||
val titleError by viewModel.titleError.collectAsStateWithLifecycle()
|
||||
val canSubmit by viewModel.canSubmit.collectAsStateWithLifecycle()
|
||||
val submitState by viewModel.submitState.collectAsStateWithLifecycle()
|
||||
|
||||
val priorities by LookupsRepository.taskPriorities.collectAsState()
|
||||
val categories by LookupsRepository.taskCategories.collectAsState()
|
||||
val frequencies by LookupsRepository.taskFrequencies.collectAsState()
|
||||
val priorities by LookupsRepository.taskPriorities.collectAsStateWithLifecycle()
|
||||
val categories by LookupsRepository.taskCategories.collectAsStateWithLifecycle()
|
||||
val frequencies by LookupsRepository.taskFrequencies.collectAsStateWithLifecycle()
|
||||
|
||||
val isSubmitting = submitState is ApiResult.Loading
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -45,6 +44,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.models.TaskSuggestionResponse
|
||||
import com.tt.honeyDue.network.ApiResult
|
||||
import com.tt.honeyDue.ui.components.common.StandardCard
|
||||
@@ -76,8 +76,8 @@ fun TaskSuggestionsScreen(
|
||||
TaskSuggestionsViewModel(residenceId = residenceId)
|
||||
}
|
||||
) {
|
||||
val suggestionsState by viewModel.suggestionsState.collectAsState()
|
||||
val acceptState by viewModel.acceptState.collectAsState()
|
||||
val suggestionsState by viewModel.suggestionsState.collectAsStateWithLifecycle()
|
||||
val acceptState by viewModel.acceptState.collectAsStateWithLifecycle()
|
||||
var isRefreshing by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
||||
@@ -38,6 +38,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tt.honeyDue.analytics.AnalyticsEvents
|
||||
import com.tt.honeyDue.analytics.PostHogAnalytics
|
||||
import com.tt.honeyDue.models.TaskTemplate
|
||||
@@ -90,10 +91,10 @@ fun TaskTemplatesBrowserScreen(
|
||||
)
|
||||
}
|
||||
) {
|
||||
val templatesState by viewModel.templatesState.collectAsState()
|
||||
val selectedIds by viewModel.selectedTemplateIds.collectAsState()
|
||||
val selectedCategory by viewModel.selectedCategory.collectAsState()
|
||||
val applyState by viewModel.applyState.collectAsState()
|
||||
val templatesState by viewModel.templatesState.collectAsStateWithLifecycle()
|
||||
val selectedIds by viewModel.selectedTemplateIds.collectAsStateWithLifecycle()
|
||||
val selectedCategory by viewModel.selectedCategory.collectAsStateWithLifecycle()
|
||||
val applyState by viewModel.applyState.collectAsStateWithLifecycle()
|
||||
var isRefreshing by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
||||
Reference in New Issue
Block a user