Skip to content

Commit

Permalink
Shared remove pagination for root topics section (#734)
Browse files Browse the repository at this point in the history
^ALTAPPS-987
  • Loading branch information
vladkash authored Nov 3, 2023
1 parent 0a12a1c commit 3c205a1
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ object FeatureKeys {
const val RECOMMENDATIONS_KOTLIN_PROJECTS = "recommendations.kotlin_projects"
const val RECOMMENDATIONS_PYTHON_PROJECTS = "recommendations.python_projects"
const val FREEMIUM_INCREASE_LIMITS_FOR_FIRST_STEP_COMPLETION = "freemium.increase_limits_for_first_step_completion"
const val LEARNING_PATH_DIVIDED_TRACK_TOPICS = "learning_path.divided_track_topics"
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ val FeaturesMap.isRecommendationsPythonProjectsFeatureEnabled: Boolean
get() = get(FeatureKeys.RECOMMENDATIONS_PYTHON_PROJECTS) ?: false

val FeaturesMap.isFreemiumIncreaseLimitsForFirstStepCompletionEnabled: Boolean
get() = get(FeatureKeys.FREEMIUM_INCREASE_LIMITS_FOR_FIRST_STEP_COMPLETION) ?: false
get() = get(FeatureKeys.FREEMIUM_INCREASE_LIMITS_FOR_FIRST_STEP_COMPLETION) ?: false

val FeaturesMap.isLearningPathDividedTrackTopicsEnabled: Boolean
get() = get(FeatureKeys.LEARNING_PATH_DIVIDED_TRACK_TOPICS) ?: false
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ object HyperskillSentryTransactionBuilder {
operation = HyperskillSentryTransactionOperation.API_LOAD
)

fun buildStudyPlanWidgetFetchProfile(): HyperskillSentryTransaction =
HyperskillSentryTransaction(
name = "study-plan-widget-feature-fetch-profile",
operation = HyperskillSentryTransactionOperation.API_LOAD
)

/**
* ProjectSelectionListFeature
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class StudyPlanWidgetComponentImpl(private val appGraph: AppGraph) : StudyPlanWi
trackInteractor = appGraph.buildTrackDataComponent().trackInteractor,
nextLearningActivityStateRepository = appGraph
.stateRepositoriesComponent.nextLearningActivityStateRepository,
currentProfileStateRepository = appGraph.profileDataComponent.currentProfileStateRepository,
sentryInteractor = appGraph.sentryComponent.sentryInteractor,
analyticInteractor = appGraph.analyticComponent.analyticInteractor
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import kotlinx.coroutines.delay
import org.hyperskill.app.analytic.domain.interactor.AnalyticInteractor
import org.hyperskill.app.core.presentation.ActionDispatcherOptions
import org.hyperskill.app.learning_activities.domain.repository.NextLearningActivityStateRepository
import org.hyperskill.app.profile.domain.repository.CurrentProfileStateRepository
import org.hyperskill.app.sentry.domain.interactor.SentryInteractor
import org.hyperskill.app.sentry.domain.model.transaction.HyperskillSentryTransactionBuilder
import org.hyperskill.app.sentry.domain.withTransaction
import org.hyperskill.app.study_plan.domain.interactor.StudyPlanInteractor
import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.Action
import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.InternalAction
Expand All @@ -18,6 +20,7 @@ class StudyPlanWidgetActionDispatcher(
private val studyPlanInteractor: StudyPlanInteractor,
private val trackInteractor: TrackInteractor,
private val nextLearningActivityStateRepository: NextLearningActivityStateRepository,
private val currentProfileStateRepository: CurrentProfileStateRepository,
private val sentryInteractor: SentryInteractor,
private val analyticInteractor: AnalyticInteractor
) : CoroutineActionDispatcher<Action, Message>(config.createConfig()) {
Expand Down Expand Up @@ -95,6 +98,18 @@ class StudyPlanWidgetActionDispatcher(
onNewMessage(StudyPlanWidgetFeature.TrackFetchResult.Failed)
}
}
is InternalAction.FetchProfile -> {
sentryInteractor.withTransaction(
HyperskillSentryTransactionBuilder.buildStudyPlanWidgetFetchProfile(),
onError = { StudyPlanWidgetFeature.ProfileFetchResult.Failed }
) {
currentProfileStateRepository
.getState()
.getOrThrow()
.let(StudyPlanWidgetFeature.ProfileFetchResult::Success)
}.let(::onNewMessage)
}

is InternalAction.UpdateNextLearningActivityState -> {
nextLearningActivityStateRepository.updateState(newState = action.learningActivity)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.hyperskill.app.learning_activities.domain.model.LearningActivity
import org.hyperskill.app.learning_activities.domain.model.LearningActivityState
import org.hyperskill.app.learning_activities.domain.model.LearningActivityType
import org.hyperskill.app.learning_activities.presentation.model.LearningActivityTargetViewAction
import org.hyperskill.app.profile.domain.model.Profile
import org.hyperskill.app.sentry.domain.model.transaction.HyperskillSentryTransaction
import org.hyperskill.app.study_plan.domain.model.StudyPlan
import org.hyperskill.app.study_plan.domain.model.StudyPlanSection
Expand Down Expand Up @@ -35,7 +36,12 @@ object StudyPlanWidgetFeature {
/**
* Pull to refresh flag
*/
val isRefreshing: Boolean = false
val isRefreshing: Boolean = false,

/**
* Divided track topics feature enabled flag
*/
val isLearningPathDividedTrackTopicsEnabled: Boolean = false
)

enum class ContentStatus {
Expand Down Expand Up @@ -107,6 +113,12 @@ object StudyPlanWidgetFeature {
object Failed : TrackFetchResult
}

internal sealed interface ProfileFetchResult : Message {
data class Success(val profile: Profile) : ProfileFetchResult

object Failed : ProfileFetchResult
}

sealed interface Action {
sealed interface ViewAction : Action {
sealed interface NavigateTo : ViewAction {
Expand Down Expand Up @@ -141,6 +153,8 @@ object StudyPlanWidgetFeature {

data class FetchTrack(val trackId: Long) : InternalAction

object FetchProfile : InternalAction

data class UpdateNextLearningActivityState(val learningActivity: LearningActivity?) : InternalAction

data class CaptureSentryException(val throwable: Throwable) : InternalAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlin.math.max
import kotlin.math.min
import org.hyperskill.app.analytic.domain.model.hyperskill.HyperskillAnalyticRoute
import org.hyperskill.app.learning_activities.presentation.mapper.LearningActivityTargetViewActionMapper
import org.hyperskill.app.profile.domain.model.isLearningPathDividedTrackTopicsEnabled
import org.hyperskill.app.sentry.domain.model.transaction.HyperskillSentryTransactionBuilder
import org.hyperskill.app.study_plan.domain.analytic.StudyPlanClickedActivityHyperskillAnalyticEvent
import org.hyperskill.app.study_plan.domain.analytic.StudyPlanClickedRetryActivitiesLoadingHyperskillAnalyticEvent
Expand Down Expand Up @@ -73,6 +74,15 @@ class StudyPlanWidgetReducer : StateReducer<State, Message, Action> {
is StudyPlanWidgetFeature.TrackFetchResult.Failed -> {
null
}
is StudyPlanWidgetFeature.ProfileFetchResult.Success -> {
state.copy(
isLearningPathDividedTrackTopicsEnabled =
message.profile.features.isLearningPathDividedTrackTopicsEnabled
) to emptySet()
}
is StudyPlanWidgetFeature.ProfileFetchResult.Failed -> {
null
}
is Message.SectionClicked ->
changeSectionExpanse(state, message.sectionId, shouldLogAnalyticEvent = true)
is Message.ActivityClicked ->
Expand Down Expand Up @@ -109,7 +119,7 @@ class StudyPlanWidgetReducer : StateReducer<State, Message, Action> {
state.sectionsStatus == StudyPlanWidgetFeature.ContentStatus.ERROR && message.forceUpdate
) {
State(sectionsStatus = StudyPlanWidgetFeature.ContentStatus.LOADING) to
setOf(InternalAction.FetchStudyPlan())
setOf(InternalAction.FetchStudyPlan(), InternalAction.FetchProfile)
} else {
state to emptySet()
}
Expand All @@ -133,7 +143,7 @@ class StudyPlanWidgetReducer : StateReducer<State, Message, Action> {
}

return if (message.showLoadingIndicators) {
State(
state.copy(
studyPlan = message.studyPlan,
sectionsStatus = StudyPlanWidgetFeature.ContentStatus.LOADING
) to actions
Expand Down Expand Up @@ -249,7 +259,10 @@ class StudyPlanWidgetReducer : StateReducer<State, Message, Action> {
) to setOf(
InternalAction.FetchActivities(
sectionId = message.sectionId,
activitiesIds = getPaginatedActivitiesIds(section),
activitiesIds = getPaginatedActivitiesIds(
section = section,
isLearningPathDividedTrackTopicsEnabled = state.isLearningPathDividedTrackTopicsEnabled
),
sentryTransaction = HyperskillSentryTransactionBuilder.buildStudyPlanWidgetFetchLearningActivities(
isCurrentSection = message.sectionId == state.getCurrentSection()?.id
)
Expand Down Expand Up @@ -294,7 +307,10 @@ class StudyPlanWidgetReducer : StateReducer<State, Message, Action> {
updateSectionState(StudyPlanWidgetFeature.ContentStatus.LOADING) to setOfNotNull(
InternalAction.FetchActivities(
sectionId = sectionId,
activitiesIds = getPaginatedActivitiesIds(section),
activitiesIds = getPaginatedActivitiesIds(
section = section,
isLearningPathDividedTrackTopicsEnabled = state.isLearningPathDividedTrackTopicsEnabled
),
sentryTransaction = sentryTransaction
),
logAnalyticEventAction
Expand All @@ -312,9 +328,13 @@ class StudyPlanWidgetReducer : StateReducer<State, Message, Action> {
}
}

internal fun getPaginatedActivitiesIds(section: StudyPlanWidgetFeature.StudyPlanSectionInfo): List<Long> =
internal fun getPaginatedActivitiesIds(
section: StudyPlanWidgetFeature.StudyPlanSectionInfo,
isLearningPathDividedTrackTopicsEnabled: Boolean
): List<Long> =
if (section.studyPlanSection.type == StudyPlanSectionType.ROOT_TOPICS &&
section.studyPlanSection.nextActivityId != null
section.studyPlanSection.nextActivityId != null &&
!isLearningPathDividedTrackTopicsEnabled
) {
val startIndex =
max(0, section.studyPlanSection.activities.indexOf(section.studyPlanSection.nextActivityId))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,10 @@ class StudyPlanWidgetTest {
contentStatus = StudyPlanWidgetFeature.ContentStatus.LOADED
)

assertEquals(expectedActivitiesIds, reducer.getPaginatedActivitiesIds(section))
assertEquals(
expectedActivitiesIds,
reducer.getPaginatedActivitiesIds(section, isLearningPathDividedTrackTopicsEnabled = false)
)
}

@Test
Expand All @@ -1110,7 +1113,10 @@ class StudyPlanWidgetTest {
contentStatus = StudyPlanWidgetFeature.ContentStatus.LOADED
)

assertEquals(expectedActivitiesIds, reducer.getPaginatedActivitiesIds(section))
assertEquals(
expectedActivitiesIds,
reducer.getPaginatedActivitiesIds(section, isLearningPathDividedTrackTopicsEnabled = false)
)
}

@Test
Expand All @@ -1127,7 +1133,10 @@ class StudyPlanWidgetTest {
contentStatus = StudyPlanWidgetFeature.ContentStatus.LOADED
)

assertEquals(expectedActivitiesIds, reducer.getPaginatedActivitiesIds(section))
assertEquals(
expectedActivitiesIds,
reducer.getPaginatedActivitiesIds(section, isLearningPathDividedTrackTopicsEnabled = false)
)
}

@Test
Expand All @@ -1144,7 +1153,10 @@ class StudyPlanWidgetTest {
contentStatus = StudyPlanWidgetFeature.ContentStatus.LOADED
)

assertEquals(expectedActivitiesIds, reducer.getPaginatedActivitiesIds(section))
assertEquals(
expectedActivitiesIds,
reducer.getPaginatedActivitiesIds(section, isLearningPathDividedTrackTopicsEnabled = false)
)
}

@Test
Expand All @@ -1161,7 +1173,30 @@ class StudyPlanWidgetTest {
contentStatus = StudyPlanWidgetFeature.ContentStatus.LOADED
)

assertEquals(expectedActivitiesIds, reducer.getPaginatedActivitiesIds(section))
assertEquals(
expectedActivitiesIds,
reducer.getPaginatedActivitiesIds(section, isLearningPathDividedTrackTopicsEnabled = false)
)
}

@Test
fun `Get not paginated activities ids in root topics section when DividedTrackTopics feature enabled`() {
val expectedActivitiesIds = (0L..50L).toList()
val section = StudyPlanWidgetFeature.StudyPlanSectionInfo(
studyPlanSection = studyPlanSectionStub(
id = 0,
type = StudyPlanSectionType.ROOT_TOPICS,
activities = expectedActivitiesIds,
nextActivityId = 5L
),
isExpanded = false,
contentStatus = StudyPlanWidgetFeature.ContentStatus.LOADED
)

assertEquals(
expectedActivitiesIds,
reducer.getPaginatedActivitiesIds(section, isLearningPathDividedTrackTopicsEnabled = true)
)
}

@Test
Expand Down

0 comments on commit 3c205a1

Please sign in to comment.