diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index c76142ec8..060397f70 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -72,7 +72,6 @@ LongMethod:StepQuizCodeBlanksReducer.kt$StepQuizCodeBlanksReducer$private fun handleSuggestionClicked( state: State, message: Message.SuggestionClicked ): StepQuizCodeBlanksReducerResult? LongMethod:StepQuizCodeBlanksViewStateMapper.kt$StepQuizCodeBlanksViewStateMapper$private fun mapContentState( state: StepQuizCodeBlanksFeature.State.Content ): StepQuizCodeBlanksViewState.Content LongMethod:StreakFreezeDialogFragment.kt$StreakFreezeDialogFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?) - LongMethod:StudyPlanWidgetReducer.kt$StudyPlanWidgetReducer$private fun handleLearningActivitiesWithSectionsFetchSuccess( state: State, message: StudyPlanWidgetFeature.LearningActivitiesWithSectionsFetchResult.Success ): StudyPlanWidgetReducerResult LongMethod:TrackProgressContent.kt$@Composable fun TrackProgressContent( viewState: ProgressScreenViewState.TrackProgressViewState.Content, onNewMessage: (ProgressScreenFeature.Message) -> Unit, modifier: Modifier = Modifier ) LongParameterList:AppInteractor.kt$AppInteractor$( private val appRepository: AppRepository, private val authInteractor: AuthInteractor, private val currentProfileStateRepository: CurrentProfileStateRepository, private val userStorageInteractor: UserStorageInteractor, private val analyticInteractor: AnalyticInteractor, private val progressesRepository: ProgressesRepository, private val trackRepository: TrackRepository, private val providersRepository: ProvidersRepository, private val projectsRepository: ProjectsRepository, private val shareStreakRepository: ShareStreakRepository, private val pushNotificationsInteractor: PushNotificationsInteractor ) LongParameterList:AuthRemoteDataSourceImpl.kt$AuthRemoteDataSourceImpl$( private val authCacheMutex: Mutex, private val deauthorizationFlow: Flow<UserDeauthorized>, private val authSocialHttpClient: HttpClient, private val authCredentialsHttpClient: HttpClient, private val networkEndpointConfigInfo: NetworkEndpointConfigInfo, private val json: Json, private val settings: Settings ) diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Extensions/SwiftUI/View/View+OnTapWhenDisabled.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Extensions/SwiftUI/View/View+OnTapWhenDisabled.swift index 0ffff8035..484584dd6 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Extensions/SwiftUI/View/View+OnTapWhenDisabled.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Extensions/SwiftUI/View/View+OnTapWhenDisabled.swift @@ -15,31 +15,31 @@ extension View { } } -#if DEBUG -@available(iOS 17.0, *) -#Preview { - @Previewable @State var isButtonDisabled = true - - VStack { - Button( - action: { - print("Button tapped!") - }, - label: { - Text("Submit") - .padding() - .background(isButtonDisabled ? Color.gray : Color.blue) - .foregroundColor(.white) - .cornerRadius(8) - } - ) - .disabled(isButtonDisabled) - .onTapWhenDisabled(isDisabled: isButtonDisabled) { - print("Button is disabled!") - } - - Toggle("Disable View", isOn: $isButtonDisabled) - .padding() - } -} -#endif +// #if DEBUG +// @available(iOS 17.0, *) +// #Preview { +// @Previewable @State var isButtonDisabled = true +// +// VStack { +// Button( +// action: { +// print("Button tapped!") +// }, +// label: { +// Text("Submit") +// .padding() +// .background(isButtonDisabled ? Color.gray : Color.blue) +// .foregroundColor(.white) +// .cornerRadius(8) +// } +// ) +// .disabled(isButtonDisabled) +// .onTapWhenDisabled(isDisabled: isButtonDisabled) { +// print("Button is disabled!") +// } +// +// Toggle("Disable View", isOn: $isButtonDisabled) +// .padding() +// } +// } +// #endif diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/BounceEffect.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/BounceEffect.swift index 333a2765c..1409ff05d 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/BounceEffect.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/BounceEffect.swift @@ -29,18 +29,18 @@ extension View { } } -#if DEBUG -@available(iOS 17.0, *) -#Preview { - @Previewable @State var isBouncing = false - - Button { - isBouncing.toggle() - } label: { - Text("Retry") - } - .buttonStyle(RoundedRectangleButtonStyle(style: .violet)) - .bounceEffect(isActive: isBouncing) - .padding() -} -#endif +// #if DEBUG +// @available(iOS 17.0, *) +// #Preview { +// @Previewable @State var isBouncing = false +// +// Button { +// isBouncing.toggle() +// } label: { +// Text("Retry") +// } +// .buttonStyle(RoundedRectangleButtonStyle(style: .violet)) +// .bounceEffect(isActive: isBouncing) +// .padding() +// } +// #endif diff --git a/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/JiggleEffect.swift b/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/JiggleEffect.swift index 14fe2b947..1b0020f47 100644 --- a/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/JiggleEffect.swift +++ b/iosHyperskillApp/iosHyperskillApp/Sources/Views/SwiftUI/Effects/JiggleEffect.swift @@ -39,18 +39,18 @@ extension View { } } -#if DEBUG -@available(iOS 17.0, *) -#Preview { - @Previewable @State var isJiggling = false - - Button { - isJiggling.toggle() - } label: { - Text("Retry") - } - .buttonStyle(RoundedRectangleButtonStyle(style: .violet)) - .jiggleEffect(amount: 2, isActive: isJiggling) - .padding() -} -#endif +// #if DEBUG +// @available(iOS 17.0, *) +// #Preview { +// @Previewable @State var isJiggling = false +// +// Button { +// isJiggling.toggle() +// } label: { +// Text("Retry") +// } +// .buttonStyle(RoundedRectangleButtonStyle(style: .violet)) +// .jiggleEffect(amount: 2, isActive: isJiggling) +// .padding() +// } +// #endif diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFakeTopicsFeature.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFakeTopicsFeature.kt deleted file mode 100644 index bcf324d0f..000000000 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetFakeTopicsFeature.kt +++ /dev/null @@ -1,73 +0,0 @@ -package org.hyperskill.app.study_plan.widget.presentation - -import org.hyperskill.app.core.domain.model.ContentType -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.subscriptions.domain.model.Subscription -import org.hyperskill.app.subscriptions.domain.model.SubscriptionType -import org.hyperskill.app.subscriptions.domain.model.isFreemium - -internal object StudyPlanWidgetFakeTopicsFeature { - private const val PYTHON_MOBILE_ADOPTED_TRACK_ID = 139L - - private val topicsTitles: List = - listOf( - "Advanced conditions", - "Comments", - "Boolean data type", - "Lists", - "List comprehension", - "Nested lists", - "Indexes and slicing", - "While loop", - "For loop", - "Loop control", - "Advanced strings", - "Declaring functions", - "Invoking functions", - "Lambda functions", - "Tuples", - "Sets", - "Dictionaries", - "Global vs local scopes", - "Immutability", - "Objects", - "Classes", - "Class instances", - "Class methods", - "Methods and attributes", - "Magic methods", - "Inheritance", - "Polymorphism", - "Method overriding", - "Errors and exceptions", - "Exception handling", - "User-defined exceptions", - "Modules", - "Random module", - "File modes and permissions", - "Files in Python", - "Reading files", - "Writing files" - ) - - val topics: List by lazy { - topicsTitles.mapIndexed { index, title -> - LearningActivity( - id = -index - 1L, - stateValue = LearningActivityState.TODO.value, - targetId = null, - targetType = ContentType.UNKNOWN, - typeValue = LearningActivityType.LEARN_TOPIC.value, - title = title, - topicId = null - ) - } - } - val topicsIds: Set by lazy { topics.map { it.id }.toSet() } - - fun isFakeTopicsFeatureAvailable(trackId: Long?, subscription: Subscription): Boolean = - trackId == PYTHON_MOBILE_ADOPTED_TRACK_ID && - (subscription.isFreemium || subscription.type == SubscriptionType.MOBILE_CONTENT_TRIAL) -} \ No newline at end of file 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 447120786..d0dfda961 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 @@ -145,42 +145,8 @@ class StudyPlanWidgetReducer : StateReducer { state: State, message: StudyPlanWidgetFeature.LearningActivitiesWithSectionsFetchResult.Success ): StudyPlanWidgetReducerResult { - val isFakeTopicsFeatureAvailable = - StudyPlanWidgetFakeTopicsFeature.isFakeTopicsFeatureAvailable( - trackId = state.profile?.trackId, - subscription = message.subscription - ) - val fakeTopics = if (isFakeTopicsFeatureAvailable) { - StudyPlanWidgetFakeTopicsFeature.topics - } else { - emptyList() - } - - val studyPlanSections = - if (isFakeTopicsFeatureAvailable) { - message.studyPlanSections.map { section -> - if (section.type == StudyPlanSectionType.ROOT_TOPICS) { - section.copy( - isVisible = true, - activities = section.activities + fakeTopics.map { it.id } - ) - } else { - section - } - } - } else { - message.studyPlanSections - } - - val learningActivities = - if (isFakeTopicsFeatureAvailable) { - message.learningActivities + fakeTopics - } else { - message.learningActivities - } - val learningActivitiesIds = learningActivities.map { it.id }.toSet() - - val visibleSections = getVisibleSections(studyPlanSections, learningActivitiesIds) + val learningActivitiesIds = message.learningActivities.map { it.id }.toSet() + val visibleSections = getVisibleSections(message.studyPlanSections, learningActivitiesIds) val currentSectionId = visibleSections.firstOrNull()?.id ?: return state.copy( studyPlanSections = emptyMap(), sectionsStatus = ContentStatus.LOADED, @@ -190,18 +156,15 @@ class StudyPlanWidgetReducer : StateReducer { val supportedSections = visibleSections .filter { studyPlanSection -> - when (studyPlanSection.type) { - StudyPlanSectionType.NEXT_PROJECT -> - // ALTAPPS-1186: We should hide next project section for freemium users - message.subscription.type.isProjectSelectionEnabled - StudyPlanSectionType.NEXT_TRACK -> - // ALTAPPS-1355: We should hide next track section for freemium users - !isFakeTopicsFeatureAvailable - else -> true + // ALTAPPS-1186: We should hide next project section for freemium users + if (!message.subscription.type.isProjectSelectionEnabled) { + studyPlanSection.type != StudyPlanSectionType.NEXT_PROJECT + } else { + true } } - val resultStudyPlanSections = supportedSections.associate { studyPlanSection -> + val studyPlanSections = supportedSections.associate { studyPlanSection -> studyPlanSection.id to StudyPlanWidgetFeature.StudyPlanSectionInfo( studyPlanSection = studyPlanSection, isExpanded = studyPlanSection.id == currentSectionId, @@ -216,11 +179,11 @@ class StudyPlanWidgetReducer : StateReducer { } val loadedSectionsState = state.copy( - studyPlanSections = resultStudyPlanSections, + studyPlanSections = studyPlanSections, sectionsStatus = ContentStatus.LOADED, isRefreshing = false, learnedTopicsCount = message.learnedTopicsCount, - activities = learningActivities.associateBy { it.id }, + activities = message.learningActivities.associateBy { it.id }, subscriptionLimitType = message.subscriptionLimitType ) @@ -228,7 +191,7 @@ class StudyPlanWidgetReducer : StateReducer { handleNewActivities( loadedSectionsState, sectionId = currentSectionId, - activities = learningActivities, + activities = message.learningActivities, targetPage = SectionPage.MAIN ) } else { diff --git a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetStateExtensions.kt b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetStateExtensions.kt index ea5fc568b..6fa4b2486 100644 --- a/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetStateExtensions.kt +++ b/shared/src/commonMain/kotlin/org/hyperskill/app/study_plan/widget/presentation/StudyPlanWidgetStateExtensions.kt @@ -109,17 +109,13 @@ internal fun StudyPlanWidgetFeature.State.isActivityLocked( sectionId: Long, activityId: Long, ): Boolean { - if (StudyPlanWidgetFakeTopicsFeature.topicsIds.contains(activityId)) { - return true - } else { - val unlockedActivitiesCount = getUnlockedActivitiesCount(sectionId) - return unlockedActivitiesCount != null && - getLoadedSectionActivities(sectionId) - .take(unlockedActivitiesCount) - .map { it.id } - .contains(activityId) - .not() - } + val unlockedActivitiesCount = getUnlockedActivitiesCount(sectionId) + return unlockedActivitiesCount != null && + getLoadedSectionActivities(sectionId) + .take(unlockedActivitiesCount) + .map { it.id } + .contains(activityId) + .not() } /** 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 b6b0a8348..88b4c1734 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 @@ -5,7 +5,6 @@ import org.hyperskill.app.core.view.mapper.date.SharedDateFormatter 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.StudyPlanWidgetFakeTopicsFeature import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.ContentStatus import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature.PageContentStatus @@ -107,15 +106,12 @@ class StudyPlanWidgetViewStateMapper(private val dateFormatter: SharedDateFormat emptyActivitiesState } else { val unlockedActivitiesCount = state.getUnlockedActivitiesCount(sectionId) - val fakeTopicsIds = StudyPlanWidgetFakeTopicsFeature.topicsIds SectionContent.Content( sectionItems = loadedActivities.mapIndexed { index, activity -> - val isLocked = fakeTopicsIds.contains(activity.id) || - (unlockedActivitiesCount != null && index + 1 > unlockedActivitiesCount) mapSectionItem( activity = activity, currentActivityId = currentActivityId, - isLocked = isLocked + isLocked = unlockedActivitiesCount != null && index + 1 > unlockedActivitiesCount ) }, nextPageLoadingState = mapPageContentStatusToViewState(sectionInfo.nextPageContentStatus),