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