From bf1d1cea0b7812a75f8099b4be8ecb6c466d9dff Mon Sep 17 00:00:00 2001 From: Aleksandr Zhukov Date: Wed, 28 Aug 2024 15:25:49 +0200 Subject: [PATCH 1/4] Hide Load More button after additional activities successful loading --- .../presentation/StudyPlanWidgetFeature.kt | 2 +- .../presentation/StudyPlanWidgetReducer.kt | 56 +++++++++++-------- .../mapper/StudyPlanWidgetViewStateMapper.kt | 4 +- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFeature.kt index 122480a548..d4671e02fd 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFeature.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFeature.kt @@ -65,8 +65,8 @@ object StudyPlanWidgetFeature { ERROR, FIRST_PAGE_LOADING, + FIRST_PAGE_LOADED, NEXT_PAGE_LOADING, - PAGE_LOADED, ALL_PAGES_LOADED } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetReducer.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetReducer.kt index 6ce719407c..393a8fc992 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetReducer.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetReducer.kt @@ -164,7 +164,7 @@ class StudyPlanWidgetReducer : StateReducer { studyPlanSection = studyPlanSection, isExpanded = studyPlanSection.id == currentSectionId, sectionContentStatus = if (studyPlanSection.id == currentSectionId) { - SectionContentStatus.PAGE_LOADED + SectionContentStatus.FIRST_PAGE_LOADED } else { SectionContentStatus.IDLE } @@ -245,29 +245,41 @@ class StudyPlanWidgetReducer : StateReducer { sectionId: Long, activities: List ): StudyPlanWidgetReducerResult { - val nextState = state.copy( - // ALTAPPS-786: We should hide sections without available activities to avoid blocking study plan - studyPlanSections = if (activities.isEmpty()) { - state.studyPlanSections.mutate { - remove(sectionId) + val sectionContentStatus = state.studyPlanSections[sectionId]?.sectionContentStatus + val nextState = + when { + // ALTAPPS-786: We should hide sections without available activities to avoid blocking study plan + activities.isEmpty() && sectionContentStatus == SectionContentStatus.FIRST_PAGE_LOADING -> { + state.copy( + studyPlanSections = state.studyPlanSections.mutate { + remove(sectionId) + } + ) } - } else { - state.studyPlanSections.update(sectionId) { sectionInfo -> - val canLoadMoreActivities = - sectionInfo - .studyPlanSection - .getActivitiesToBeLoaded(state.activities.values) - .isNotEmpty() - sectionInfo.copy( - sectionContentStatus = if (canLoadMoreActivities) { - SectionContentStatus.PAGE_LOADED - } else { - SectionContentStatus.ALL_PAGES_LOADED + else -> { + state.copy( + studyPlanSections = state.studyPlanSections.update(sectionId) { sectionInfo -> + sectionInfo.copy( + sectionContentStatus = when (sectionContentStatus) { + SectionContentStatus.FIRST_PAGE_LOADED -> { + val canLoadMoreActivities = + sectionInfo + .studyPlanSection + .getActivitiesToBeLoaded(state.activities.values) + .isNotEmpty() + if (canLoadMoreActivities) { + SectionContentStatus.FIRST_PAGE_LOADED + } else { + SectionContentStatus.ALL_PAGES_LOADED + } + } + else -> SectionContentStatus.ALL_PAGES_LOADED + } + ) } ) } } - ) val isFetchedActivitiesForCurrentSection = sectionId == state.getCurrentSection()?.id @@ -313,8 +325,8 @@ class StudyPlanWidgetReducer : StateReducer { SectionContentStatus.ERROR, SectionContentStatus.FIRST_PAGE_LOADING -> SectionContentStatus.ERROR SectionContentStatus.NEXT_PAGE_LOADING, - SectionContentStatus.PAGE_LOADED, - SectionContentStatus.ALL_PAGES_LOADED -> SectionContentStatus.PAGE_LOADED + SectionContentStatus.FIRST_PAGE_LOADED, + SectionContentStatus.ALL_PAGES_LOADED -> SectionContentStatus.FIRST_PAGE_LOADED } ) } @@ -408,7 +420,7 @@ class StudyPlanWidgetReducer : StateReducer { // activities are loading at the moment or already loaded SectionContentStatus.FIRST_PAGE_LOADING, SectionContentStatus.NEXT_PAGE_LOADING, - SectionContentStatus.PAGE_LOADED, + SectionContentStatus.FIRST_PAGE_LOADED, SectionContentStatus.ALL_PAGES_LOADED -> { updateSectionState(contentStatus) to setOfNotNull(logAnalyticEventAction) } diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt index 83f94adc56..9afea1c7e1 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt @@ -85,7 +85,7 @@ class StudyPlanWidgetViewStateMapper(private val dateFormatter: SharedDateFormat emptyActivitiesState = SectionContent.Loading ) } - SectionContentStatus.PAGE_LOADED, + SectionContentStatus.FIRST_PAGE_LOADED, SectionContentStatus.ALL_PAGES_LOADED -> { getContent( state = state, @@ -114,7 +114,7 @@ class StudyPlanWidgetViewStateMapper(private val dateFormatter: SharedDateFormat activities = loadedActivities, currentActivityId = currentActivityId, unlockedActivitiesCount = state.getUnlockedActivitiesCount(sectionId), - isLoadAllTopicsButtonVisible = sectionInfo.sectionContentStatus == SectionContentStatus.PAGE_LOADED, + isLoadAllTopicsButtonVisible = sectionInfo.sectionContentStatus == SectionContentStatus.FIRST_PAGE_LOADED, isNextPageLoadingShowed = sectionInfo.sectionContentStatus == SectionContentStatus.NEXT_PAGE_LOADING ) } From 3baec84cfa17b568bb96479e160e395f688c171c Mon Sep 17 00:00:00 2001 From: Aleksandr Zhukov Date: Wed, 28 Aug 2024 15:32:54 +0200 Subject: [PATCH 2/4] Fix ktlint --- .../mapper/StudyPlanWidgetViewStateMapper.kt | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt index 9afea1c7e1..b93ebb2811 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/view/mapper/StudyPlanWidgetViewStateMapper.kt @@ -6,7 +6,12 @@ import org.hyperskill.app.learning_activities.domain.model.LearningActivity import org.hyperskill.app.learning_activities.domain.model.LearningActivityState import org.hyperskill.app.learning_activities.view.mapper.LearningActivityTextsMapper import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature -import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus +import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus.ALL_PAGES_LOADED +import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus.ERROR +import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus.FIRST_PAGE_LOADED +import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus.FIRST_PAGE_LOADING +import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus.IDLE +import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionContentStatus.NEXT_PAGE_LOADING import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.SectionStatus import org.hyperskill.app.study_plan.widget.presentation.getCurrentActivity import org.hyperskill.app.study_plan.widget.presentation.getCurrentSection @@ -74,10 +79,10 @@ class StudyPlanWidgetViewStateMapper(private val dateFormatter: SharedDateFormat ): SectionContent = if (sectionInfo.isExpanded) { when (sectionInfo.sectionContentStatus) { - SectionContentStatus.IDLE -> SectionContent.Collapsed - SectionContentStatus.ERROR -> SectionContent.Error - SectionContentStatus.FIRST_PAGE_LOADING, - SectionContentStatus.NEXT_PAGE_LOADING -> { + IDLE -> SectionContent.Collapsed + ERROR -> SectionContent.Error + FIRST_PAGE_LOADING, + NEXT_PAGE_LOADING -> { getContent( state = state, sectionInfo = sectionInfo, @@ -85,8 +90,8 @@ class StudyPlanWidgetViewStateMapper(private val dateFormatter: SharedDateFormat emptyActivitiesState = SectionContent.Loading ) } - SectionContentStatus.FIRST_PAGE_LOADED, - SectionContentStatus.ALL_PAGES_LOADED -> { + FIRST_PAGE_LOADED, + ALL_PAGES_LOADED -> { getContent( state = state, sectionInfo = sectionInfo, @@ -114,8 +119,8 @@ class StudyPlanWidgetViewStateMapper(private val dateFormatter: SharedDateFormat activities = loadedActivities, currentActivityId = currentActivityId, unlockedActivitiesCount = state.getUnlockedActivitiesCount(sectionId), - isLoadAllTopicsButtonVisible = sectionInfo.sectionContentStatus == SectionContentStatus.FIRST_PAGE_LOADED, - isNextPageLoadingShowed = sectionInfo.sectionContentStatus == SectionContentStatus.NEXT_PAGE_LOADING + isLoadAllTopicsButtonVisible = sectionInfo.sectionContentStatus == FIRST_PAGE_LOADED, + isNextPageLoadingShowed = sectionInfo.sectionContentStatus == NEXT_PAGE_LOADING ) } } From 6be648c7dae585b7afd9f662a145afaff470bd00 Mon Sep 17 00:00:00 2001 From: Aleksandr Zhukov Date: Wed, 28 Aug 2024 16:01:21 +0200 Subject: [PATCH 3/4] Fix tests --- .../study_plan/widget/StudyPlanWidgetTest.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt b/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt index 4c024675d6..6ed3eff125 100644 --- a/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt +++ b/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt @@ -310,7 +310,7 @@ class StudyPlanWidgetTest { studyPlanSections = mapOf( currentSectionId to StudyPlanWidgetFeature.StudyPlanSectionInfo( studyPlanSection = studyPlanSectionStub(currentSectionId), - sectionContentStatus = SectionContentStatus.NEXT_PAGE_LOADING, + sectionContentStatus = SectionContentStatus.FIRST_PAGE_LOADING, isExpanded = true ), nextSectionId to StudyPlanWidgetFeature.StudyPlanSectionInfo( @@ -334,7 +334,7 @@ class StudyPlanWidgetTest { @Test fun `Not current section should be removed if no available activities loaded`() { val currentSectionId = 0L - val notCurrent = 1L + val notCurrentSectionId = 1L val initialState = StudyPlanWidgetFeature.State( studyPlanSections = mapOf( currentSectionId to StudyPlanWidgetFeature.StudyPlanSectionInfo( @@ -342,9 +342,9 @@ class StudyPlanWidgetTest { sectionContentStatus = SectionContentStatus.ALL_PAGES_LOADED, isExpanded = true ), - notCurrent to StudyPlanWidgetFeature.StudyPlanSectionInfo( - studyPlanSection = studyPlanSectionStub(notCurrent), - sectionContentStatus = SectionContentStatus.NEXT_PAGE_LOADING, + notCurrentSectionId to StudyPlanWidgetFeature.StudyPlanSectionInfo( + studyPlanSection = studyPlanSectionStub(notCurrentSectionId), + sectionContentStatus = SectionContentStatus.FIRST_PAGE_LOADING, isExpanded = false ) ) @@ -352,9 +352,9 @@ class StudyPlanWidgetTest { val (state, _) = reducer.reduce( initialState, - StudyPlanWidgetFeature.LearningActivitiesFetchResult.Success(sectionId = notCurrent, emptyList()) + StudyPlanWidgetFeature.LearningActivitiesFetchResult.Success(sectionId = notCurrentSectionId, emptyList()) ) - assertTrue(state.studyPlanSections.containsKey(notCurrent).not()) + assertTrue(state.studyPlanSections.containsKey(notCurrentSectionId).not()) } @Test From 92ff9443b5a1ccd6550513b6f2a5035525e2727c Mon Sep 17 00:00:00 2001 From: Aleksandr Zhukov Date: Wed, 28 Aug 2024 16:05:05 +0200 Subject: [PATCH 4/4] Fix ktlint --- .../org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt b/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt index 6ed3eff125..d185e87d6f 100644 --- a/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt +++ b/shared/src/commonTest/kotlin/org/hyperskill/study_plan/widget/StudyPlanWidgetTest.kt @@ -352,7 +352,10 @@ class StudyPlanWidgetTest { val (state, _) = reducer.reduce( initialState, - StudyPlanWidgetFeature.LearningActivitiesFetchResult.Success(sectionId = notCurrentSectionId, emptyList()) + StudyPlanWidgetFeature.LearningActivitiesFetchResult.Success( + sectionId = notCurrentSectionId, + activities = emptyList() + ) ) assertTrue(state.studyPlanSections.containsKey(notCurrentSectionId).not()) }