diff --git a/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreen.kt index 5806579..d6bc6c7 100644 --- a/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreen.kt @@ -107,7 +107,8 @@ import com.byteutility.dev.leetcode.plus.network.responseVo.Contest import com.byteutility.dev.leetcode.plus.ui.common.ProgressIndicator import com.byteutility.dev.leetcode.plus.ui.model.YouTubeVideo import com.byteutility.dev.leetcode.plus.ui.screens.home.model.DifficultyStatistics -import com.byteutility.dev.leetcode.plus.ui.screens.home.model.UserDetailsUiState +import com.byteutility.dev.leetcode.plus.ui.screens.home.model.LeetcodeUpcomingContestsState +import com.byteutility.dev.leetcode.plus.ui.screens.home.model.UserSubmissionState import com.byteutility.dev.leetcode.plus.ui.screens.home.model.VideosByPlayListState import com.byteutility.dev.leetcode.plus.ui.theme.EasyText import com.byteutility.dev.leetcode.plus.ui.theme.HardText @@ -139,7 +140,15 @@ fun HomeScreen( onLogout: () -> Unit = {} ) { val viewModel: HomeScreenViewModel = hiltViewModel() - val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val isWeeklyGoalSet by viewModel.isWeeklyGoalSet.collectAsStateWithLifecycle() + val userBasicInfo by viewModel.userBasicInfo.collectAsStateWithLifecycle() + val syncInterval by viewModel.syncInterval.collectAsStateWithLifecycle() + val userContestInfo by viewModel.userContestInfo.collectAsStateWithLifecycle() + val userProblemSolvedInfo by viewModel.userProblemSolvedInfo.collectAsStateWithLifecycle() + val userSubmissionState by viewModel.userSubmissionState.collectAsStateWithLifecycle() + val videosByPlayListState by viewModel.videosByPlayListState.collectAsStateWithLifecycle() + val leetcodeUpcomingContestsState by viewModel.leetcodeUpcomingContestsState.collectAsStateWithLifecycle() + val difficultyStat by viewModel.difficultyStat.collectAsStateWithLifecycle() val dailyProblem by viewModel.dailyProblem.collectAsStateWithLifecycle() val dailyProblemSolved by viewModel.dailyProblemSolved.collectAsStateWithLifecycle() LifecycleResumeEffect(Unit) { @@ -147,7 +156,15 @@ fun HomeScreen( onPauseOrDispose { } } HomeLayout( - uiState = uiState, + isWeeklyGoalSet = isWeeklyGoalSet, + userBasicInfo = userBasicInfo, + syncInterval = syncInterval, + userContestInfo = userContestInfo, + userProblemSolvedInfo = userProblemSolvedInfo, + userSubmissionState = userSubmissionState, + videosByPlayListState = videosByPlayListState, + leetcodeUpcomingContestsState = leetcodeUpcomingContestsState, + difficultyStat = difficultyStat, dailyProblem = dailyProblem, dailyProblemSolved = dailyProblemSolved, onSetGoal = onSetGoal, @@ -179,7 +196,15 @@ fun HomeScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeLayout( - uiState: UserDetailsUiState, + isWeeklyGoalSet: Boolean, + userBasicInfo: UserBasicInfo, + syncInterval: Long, + userContestInfo: UserContestInfo, + userProblemSolvedInfo: UserProblemSolvedInfo, + userSubmissionState: UserSubmissionState, + videosByPlayListState: VideosByPlayListState, + leetcodeUpcomingContestsState: LeetcodeUpcomingContestsState, + difficultyStat: DifficultyStatistics, dailyProblem: LeetCodeProblem, dailyProblemSolved: Boolean, onSetGoal: () -> Unit, @@ -213,49 +238,18 @@ fun HomeLayout( Scaffold( topBar = { - TopAppBar( - title = { - /** - * 5 times click in a shorter period will open troubleshoot page - */ - Text( - text = "Home", - fontWeight = FontWeight.Bold, - modifier = Modifier.clickable { - val currentTime = System.currentTimeMillis() - if (currentTime - lastClickTime <= 1000) { - clickCount++ - if (clickCount == 5) { - onTroubleShoot.invoke() - clickCount = 0 - } - } else { - clickCount = 1 - } - lastClickTime = currentTime - scope.launch { - delay(2000) - clickCount = 0 - } - }) - }, - actions = { - MainTopActions( - isWeeklyGoalSet = uiState.isWeeklyGoalSet, - avatarUrl = uiState.userBasicInfo.avatar, - onSetGoal = onSetGoal, - onGoalStatus = onGoalStatus, - onLogoutClick = { - showLogoutDialog = true - }, - modifier = Modifier.testTag("main_top_actions") - ) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color(0xFFABDEF5).copy( - alpha = 0.1f - ) - ) + HomeTopBar( + isWeeklyGoalSet = isWeeklyGoalSet, + avatarUrl = userBasicInfo.avatar, + clickCount = clickCount, + lastClickTime = lastClickTime, + onClickCountChange = { clickCount = it }, + onLastClickTimeChange = { lastClickTime = it }, + scope = scope, + onSetGoal = onSetGoal, + onGoalStatus = onGoalStatus, + onTroubleShoot = onTroubleShoot, + onLogoutClick = { showLogoutDialog = true } ) } ) { paddingValues -> @@ -269,8 +263,15 @@ fun HomeLayout( .fillMaxWidth() .weight(1f) ) { - UserProfileContent( - uiState = uiState, + HomeContent( + userBasicInfo = userBasicInfo, + syncInterval = syncInterval, + userContestInfo = userContestInfo, + userProblemSolvedInfo = userProblemSolvedInfo, + userSubmissionState = userSubmissionState, + videosByPlayListState = videosByPlayListState, + leetcodeUpcomingContestsState = leetcodeUpcomingContestsState, + difficultyStat = difficultyStat, dailyProblem = dailyProblem, dailyProblemSolved = dailyProblemSolved, onNavigateToProblemDetails = onNavigateToProblemDetails, @@ -334,6 +335,62 @@ fun HomeLayout( } } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun HomeTopBar( + isWeeklyGoalSet: Boolean, + avatarUrl: String, + clickCount: Int, + lastClickTime: Long, + onClickCountChange: (Int) -> Unit, + onLastClickTimeChange: (Long) -> Unit, + scope: kotlinx.coroutines.CoroutineScope, + onSetGoal: () -> Unit, + onGoalStatus: () -> Unit, + onTroubleShoot: () -> Unit, + onLogoutClick: () -> Unit +) { + TopAppBar( + title = { + Text( + text = "Home", + fontWeight = FontWeight.Bold, + modifier = Modifier.clickable { + val currentTime = System.currentTimeMillis() + if (currentTime - lastClickTime <= 1000) { + val nextClickCount = clickCount + 1 + onClickCountChange(nextClickCount) + if (nextClickCount == 5) { + onTroubleShoot.invoke() + onClickCountChange(0) + } + } else { + onClickCountChange(1) + } + onLastClickTimeChange(currentTime) + scope.launch { + delay(2000) + onClickCountChange(0) + } + } + ) + }, + actions = { + MainTopActions( + isWeeklyGoalSet = isWeeklyGoalSet, + avatarUrl = avatarUrl, + onSetGoal = onSetGoal, + onGoalStatus = onGoalStatus, + onLogoutClick = onLogoutClick, + modifier = Modifier.testTag("main_top_actions") + ) + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = Color(0xFFABDEF5).copy(alpha = 0.1f) + ) + ) +} + @Composable fun MainTopActions( isWeeklyGoalSet: Boolean, @@ -364,9 +421,59 @@ fun MainTopActions( } } +@Composable +private fun HomeContent( + userBasicInfo: UserBasicInfo, + syncInterval: Long, + userContestInfo: UserContestInfo, + userProblemSolvedInfo: UserProblemSolvedInfo, + userSubmissionState: UserSubmissionState, + videosByPlayListState: VideosByPlayListState, + leetcodeUpcomingContestsState: LeetcodeUpcomingContestsState, + difficultyStat: DifficultyStatistics, + dailyProblem: LeetCodeProblem, + dailyProblemSolved: Boolean, + onNavigateToProblemDetails: (String) -> Unit, + onLoadMoreSubmission: () -> Unit, + onLoadMoreVideos: () -> Unit, + onSearchClick: () -> Unit, + onSetInAppReminder: (Contest) -> Unit, + checkInAppContestReminderStatus: suspend (Contest) -> Boolean, + onNavigateToContestDetail: (Contest) -> Unit = {}, + modifier: Modifier = Modifier, +) { + UserProfileContent( + userBasicInfo = userBasicInfo, + syncInterval = syncInterval, + userContestInfo = userContestInfo, + userProblemSolvedInfo = userProblemSolvedInfo, + userSubmissionState = userSubmissionState, + videosByPlayListState = videosByPlayListState, + leetcodeUpcomingContestsState = leetcodeUpcomingContestsState, + difficultyStat = difficultyStat, + dailyProblem = dailyProblem, + dailyProblemSolved = dailyProblemSolved, + onNavigateToProblemDetails = onNavigateToProblemDetails, + onLoadMoreSubmission = onLoadMoreSubmission, + onLoadMoreVideos = onLoadMoreVideos, + onSearchClick = onSearchClick, + onSetInAppReminder = onSetInAppReminder, + checkInAppContestReminderStatus = checkInAppContestReminderStatus, + onNavigateToContestDetail = onNavigateToContestDetail, + modifier = modifier + ) +} + @Composable fun UserProfileContent( - uiState: UserDetailsUiState, + userBasicInfo: UserBasicInfo, + syncInterval: Long, + userContestInfo: UserContestInfo, + userProblemSolvedInfo: UserProblemSolvedInfo, + userSubmissionState: UserSubmissionState, + videosByPlayListState: VideosByPlayListState, + leetcodeUpcomingContestsState: LeetcodeUpcomingContestsState, + difficultyStat: DifficultyStatistics, dailyProblem: LeetCodeProblem, dailyProblemSolved: Boolean, onNavigateToProblemDetails: (String) -> Unit, @@ -390,7 +497,7 @@ fun UserProfileContent( .fillMaxSize(), verticalArrangement = Arrangement.spacedBy(10.dp) ) { - UserProfileCard(uiState.userBasicInfo) + UserProfileCard(userBasicInfo) // Data sync info message Row( @@ -408,7 +515,7 @@ fun UserProfileContent( ) Spacer(modifier = Modifier.width(6.dp)) Text( - text = "Data updated every ${uiState.syncInterval} min", + text = "Data updated every $syncInterval min", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), fontSize = 12.sp @@ -422,9 +529,9 @@ fun UserProfileContent( difficulty = dailyProblem.difficulty, onNavigateToProblemDetails = onNavigateToProblemDetails ) - UserStatisticsCard(uiState.userContestInfo) + UserStatisticsCard(userContestInfo) YouTubeVideoRowContent( - uiState.videosByPlayListState, + videosByPlayListState, onLoadMoreVideos, onSearchClick ) @@ -434,14 +541,17 @@ fun UserProfileContent( modifier = Modifier.padding(start = 8.dp) ) AutoScrollingContestList( - contests = uiState.leetcodeUpcomingContestsState.contests, + contests = leetcodeUpcomingContestsState.contests, onSetInAppReminder = onSetInAppReminder, checkInAppContestReminderStatus = checkInAppContestReminderStatus, onNavigateToContestDetail = onNavigateToContestDetail ) - UserProblemCategoryStats(userProblemSolvedInfo = uiState.userProblemSolvedInfo, diffStat = uiState.difficultyStat) + UserProblemCategoryStats( + userProblemSolvedInfo = userProblemSolvedInfo, + diffStat = difficultyStat + ) - if (uiState.userSubmissionState.submissions.isEmpty()) { + if (userSubmissionState.submissions.isEmpty()) { Text( text = "You have no recent submissions", modifier = Modifier.fillMaxWidth(), @@ -460,9 +570,9 @@ fun UserProfileContent( } } - items(uiState.userSubmissionState.submissions.size) { index -> - val item = uiState.userSubmissionState.submissions[index] - if (index >= uiState.userSubmissionState.submissions.size - 1 && !uiState.userSubmissionState.endReached && !uiState.userSubmissionState.isLoading) { + items(userSubmissionState.submissions.size) { index -> + val item = userSubmissionState.submissions[index] + if (index >= userSubmissionState.submissions.size - 1 && !userSubmissionState.endReached && !userSubmissionState.isLoading) { onLoadMoreSubmission() } SubmissionItem( @@ -472,7 +582,7 @@ fun UserProfileContent( } item { - if (uiState.userSubmissionState.isLoading) { + if (userSubmissionState.isLoading) { Row( modifier = Modifier .fillMaxWidth() @@ -1412,80 +1522,44 @@ private fun calculateRemainingTime(): String { @Preview(showBackground = true) @Composable fun PreviewUserDetails() { - val submissions = listOf( - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" - ), - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" + UserProfileContent( + userBasicInfo = UserBasicInfo( + name = "Mindy Shannon", + userName = "Annette Jones", + avatar = "venenatis", + ranking = 8869, + country = "Gambia, The" ), - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" + syncInterval = 30L, + userContestInfo = UserContestInfo( + rating = 14.15, + globalRanking = 3679, + attend = 7232 ), - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" + userProblemSolvedInfo = UserProblemSolvedInfo( + easy = 4592, + medium = 5761, + hard = 6990 ), - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" - ), - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" - ), - UserSubmission( - lang = "volumus", - statusDisplay = "veri", - timestamp = "eu", - title = "reformidans" - ), - ) - HomeLayout( - uiState = UserDetailsUiState( - userBasicInfo = UserBasicInfo( - name = "Mindy Shannon", - userName = "Annette Jones", - avatar = "venenatis", - ranking = 8869, - country = "Gambia, The" - ), - userContestInfo = UserContestInfo( - rating = 14.15, - globalRanking = 3679, - attend = 7232 - ), - userProblemSolvedInfo = UserProblemSolvedInfo( - easy = 4592, - medium = 5761, - hard = 6990 - ), + userSubmissionState = com.byteutility.dev.leetcode.plus.ui.screens.home.model.UserSubmissionState( + submissions = List(7) { + UserSubmission( + lang = "Kotlin", + statusDisplay = "Accepted", + timestamp = "Today", + title = "reformidans" + ) + } ), - LeetCodeProblem("Two Sum", "", ""), - false, - onSetGoal = {}, - onGoalStatus = {}, - onTroubleShoot = {}, + videosByPlayListState = VideosByPlayListState(), + leetcodeUpcomingContestsState = com.byteutility.dev.leetcode.plus.ui.screens.home.model.LeetcodeUpcomingContestsState(), + difficultyStat = DifficultyStatistics(), + dailyProblem = LeetCodeProblem("Two Sum", "", ""), + dailyProblemSolved = false, onNavigateToProblemDetails = {}, onLoadMoreSubmission = {}, onLoadMoreVideos = {}, onSearchClick = {}, - onLogout = {}, onSetInAppReminder = {}, checkInAppContestReminderStatus = { false }, onNavigateToContestDetail = {} diff --git a/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreenViewModel.kt b/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreenViewModel.kt index 32f44a2..1a5d4c4 100644 --- a/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreenViewModel.kt +++ b/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/HomeScreenViewModel.kt @@ -30,17 +30,19 @@ import com.byteutility.dev.leetcode.plus.network.responseVo.Contest import com.byteutility.dev.leetcode.plus.network.responseVo.sortByStartTime import com.byteutility.dev.leetcode.plus.ui.screens.home.model.DifficultyStatistics import com.byteutility.dev.leetcode.plus.ui.screens.home.model.LeetcodeUpcomingContestsState -import com.byteutility.dev.leetcode.plus.ui.screens.home.model.UserDetailsUiState import com.byteutility.dev.leetcode.plus.ui.screens.home.model.UserSubmissionState import com.byteutility.dev.leetcode.plus.ui.screens.home.model.VideosByPlayListState import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -64,36 +66,66 @@ class HomeScreenViewModel @Inject constructor( ) : ViewModel() { // Submissions - private val userSubmissionState = + private val _userSubmissionState = MutableStateFlow(UserSubmissionState()) + val userSubmissionState = _userSubmissionState.asStateFlow() private val userSubmissionPagination = getUserSubmissionPaginator() // Videos - private val videosByPlayListState = MutableStateFlow(VideosByPlayListState()) + private val _videosByPlayListState = MutableStateFlow(VideosByPlayListState()) + val videosByPlayListState = _videosByPlayListState.asStateFlow() private var pageTokenForPlayList: String? = null private val videosByPlayListPagination = getVideosPaginator() private val _leetcodeUpcomingContestsState = MutableStateFlow(LeetcodeUpcomingContestsState()) + val leetcodeUpcomingContestsState = _leetcodeUpcomingContestsState.asStateFlow() - private val userBasicInfo = - MutableStateFlow(UserBasicInfo()) + val userBasicInfo: StateFlow = flow { + emitAll(userDetailsRepository.getUserBasicInfo().filterNotNull()) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = UserBasicInfo() + ) - private val syncInterval = + private val _syncInterval = MutableStateFlow(IntervalConfigurations.DATA_SYNC_DEFAULT_INTERVAL.minutes) + val syncInterval = _syncInterval.asStateFlow() - private val userContestInfo = - MutableStateFlow(UserContestInfo()) + val userContestInfo: StateFlow = flow { + emitAll(userDetailsRepository.getUserContestInfo().filterNotNull()) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = UserContestInfo() + ) - private val userProblemSolvedInfo = - MutableStateFlow(UserProblemSolvedInfo()) + val userProblemSolvedInfo: StateFlow = flow { + emitAll(userDetailsRepository.getUserProblemSolvedInfo().filterNotNull()) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = UserProblemSolvedInfo() + ) - private val isWeeklyGoalSet = MutableStateFlow(false) + val isWeeklyGoalSet: StateFlow = goalRepository.weeklyGoal + .map { it != null } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = false + ) - private val _dailyProblem = - MutableStateFlow(LeetCodeProblem("", "", "")) - val dailyProblem = _dailyProblem.asStateFlow() + val dailyProblem: StateFlow = flow { + emitAll(userDetailsRepository.getDailyProblem().filterNotNull()) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = LeetCodeProblem("", "", "") + ) - private val diffStat = MutableStateFlow(DifficultyStatistics()) + private val _difficultyStat = MutableStateFlow(DifficultyStatistics()) + val difficultyStat = _difficultyStat.asStateFlow() val dailyProblemSolved = dailyProblemStatusMonitor.dailyProblemSolved.stateIn( scope = viewModelScope, @@ -101,72 +133,11 @@ class HomeScreenViewModel @Inject constructor( initialValue = false ) - val uiState: StateFlow = - combine( - listOf( - userBasicInfo, - userContestInfo, - userProblemSolvedInfo, - userSubmissionState, - isWeeklyGoalSet, - videosByPlayListState, - _leetcodeUpcomingContestsState, - syncInterval, - diffStat - ) - ) { values -> - UserDetailsUiState( - userBasicInfo = values[0] as UserBasicInfo, - userContestInfo = values[1] as UserContestInfo, - userProblemSolvedInfo = values[2] as UserProblemSolvedInfo, - userSubmissionState = values[3] as UserSubmissionState, - isWeeklyGoalSet = values[4] as Boolean, - videosByPlayListState = values[5] as VideosByPlayListState, - leetcodeUpcomingContestsState = values[6] as LeetcodeUpcomingContestsState, - syncInterval = values[7] as Long, - difficultyStat = values[8] as DifficultyStatistics - ) - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5000), - initialValue = UserDetailsUiState() - ) - init { loadNextAcSubmissions() viewModelScope.launch { - userDetailsRepository - .getUserBasicInfo() - .collect { - if (it != null) { - userBasicInfo.value = it - } - } - } - - viewModelScope.launch { - syncInterval.value = userDatastore.getSyncInterval() - } - - viewModelScope.launch { - userDetailsRepository - .getUserContestInfo() - .collect { - if (it != null) { - userContestInfo.value = it - } - } - } - - viewModelScope.launch { - userDetailsRepository - .getUserProblemSolvedInfo() - .collect { - if (it != null) { - userProblemSolvedInfo.value = it - } - } + _syncInterval.value = userDatastore.getSyncInterval() } viewModelScope.launch(Dispatchers.IO) { @@ -181,14 +152,6 @@ class HomeScreenViewModel @Inject constructor( } } - viewModelScope.launch(Dispatchers.IO) { - userDetailsRepository.getDailyProblem().collect { - if (it != null) { - _dailyProblem.value = it - } - } - } - viewModelScope.launch(Dispatchers.IO) { _leetcodeUpcomingContestsState.update { it.copy(isLoading = true) @@ -209,8 +172,6 @@ class HomeScreenViewModel @Inject constructor( scheduleBackgroundTasks() - getWeeklyGoalStatus() - getRemoteProblems() getDifficultyStat() @@ -218,21 +179,12 @@ class HomeScreenViewModel @Inject constructor( fun refreshUiState() { refreshUserSettings() - getWeeklyGoalStatus() - } - - private fun getWeeklyGoalStatus() { - viewModelScope.launch(Dispatchers.IO) { - goalRepository.weeklyGoal.collect { - isWeeklyGoalSet.value = (it != null) - } - } } private fun getUserSubmissionPaginator() = DefaultPaginator( - initialKey = userSubmissionState.value.page, + initialKey = _userSubmissionState.value.page, onLoadUpdated = { isLoading -> - userSubmissionState.update { + _userSubmissionState.update { it.copy(isLoading = isLoading) } }, @@ -240,15 +192,15 @@ class HomeScreenViewModel @Inject constructor( userDetailsRepository.getUserRecentAcSubmissionsPaginated(nextPage, 5) }, getNextKey = { - userSubmissionState.value.page + 1 + _userSubmissionState.value.page + 1 }, onError = { error -> - userSubmissionState.update { + _userSubmissionState.update { it.copy(error = error?.message) } }, onSuccess = { items, newKey -> - userSubmissionState.update { + _userSubmissionState.update { it.copy( submissions = it.submissions + items, page = newKey, @@ -261,7 +213,7 @@ class HomeScreenViewModel @Inject constructor( private fun getVideosPaginator() = DefaultPaginator( initialKey = pageTokenForPlayList, onLoadUpdated = { isLoading -> - videosByPlayListState.update { + _videosByPlayListState.update { it.copy(isLoading = isLoading) } }, @@ -281,12 +233,12 @@ class HomeScreenViewModel @Inject constructor( pageTokenForPlayList }, onError = { error -> - videosByPlayListState.update { + _videosByPlayListState.update { it.copy(error = error?.message) } }, onSuccess = { items, newKey -> - videosByPlayListState.update { + _videosByPlayListState.update { it.copy( videos = it.videos + items, endReached = items.isEmpty() @@ -316,7 +268,7 @@ class HomeScreenViewModel @Inject constructor( private fun refreshUserSettings() { viewModelScope.launch { - syncInterval.value = userDatastore.getSyncInterval() + _syncInterval.value = userDatastore.getSyncInterval() } } @@ -394,7 +346,7 @@ class HomeScreenViewModel @Inject constructor( private fun getDifficultyStat() = viewModelScope.launch(Dispatchers.IO) { val stat = localProblemRepo.difficultyStat() if (stat.first != 0 && stat.second != 0 && stat.third != 0) { - diffStat.value = DifficultyStatistics( + _difficultyStat.value = DifficultyStatistics( easyProblemCount = stat.first, mediumProblemCount = stat.second, hardProblemCount = stat.third diff --git a/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/model/UserDetailsUiState.kt b/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/model/UserDetailsUiState.kt index 9fe4872..448956d 100644 --- a/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/model/UserDetailsUiState.kt +++ b/app/src/main/kotlin/com/byteutility/dev/leetcode/plus/ui/screens/home/model/UserDetailsUiState.kt @@ -1,28 +1,9 @@ package com.byteutility.dev.leetcode.plus.ui.screens.home.model -import com.byteutility.dev.leetcode.plus.core.settings.config.IntervalConfigurations -import com.byteutility.dev.leetcode.plus.data.model.UserBasicInfo -import com.byteutility.dev.leetcode.plus.data.model.UserContestInfo -import com.byteutility.dev.leetcode.plus.data.model.UserProblemSolvedInfo import com.byteutility.dev.leetcode.plus.data.model.UserSubmission import com.byteutility.dev.leetcode.plus.network.responseVo.Contest import com.google.api.services.youtube.model.Video -/** - * Created by Shuvo on 11/06/2025. - */ -data class UserDetailsUiState( - val userBasicInfo: UserBasicInfo = UserBasicInfo(), - val userContestInfo: UserContestInfo = UserContestInfo(), - val userProblemSolvedInfo: UserProblemSolvedInfo = UserProblemSolvedInfo(), - val userSubmissionState: UserSubmissionState = UserSubmissionState(), - val isWeeklyGoalSet: Boolean = false, - val syncInterval: Long = IntervalConfigurations.DATA_SYNC_DEFAULT_INTERVAL.minutes, - val videosByPlayListState: VideosByPlayListState = VideosByPlayListState(), - val leetcodeUpcomingContestsState: LeetcodeUpcomingContestsState = LeetcodeUpcomingContestsState(), - val difficultyStat: DifficultyStatistics = DifficultyStatistics() -) - data class LeetcodeUpcomingContestsState( val isLoading: Boolean = false, val contests: List = emptyList(),