Skip to content

Commit

Permalink
Merge pull request #1167 from hyperskill/release/1.70
Browse files Browse the repository at this point in the history
Release 1.70
  • Loading branch information
XanderZhu authored Sep 3, 2024
2 parents ac33a4b + d4d9269 commit 920d4d2
Show file tree
Hide file tree
Showing 45 changed files with 1,459 additions and 550 deletions.
2 changes: 1 addition & 1 deletion androidHyperskillApp/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ source "https://rubygems.org"
ruby "3.3.0"

gem "fastlane", "2.222.0"
gem "rexml", ">= 3.3.3"
gem "rexml", ">= 3.3.6"

eval_gemfile("fastlane/Pluginfile")
17 changes: 9 additions & 8 deletions androidHyperskillApp/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ GEM
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.962.0)
aws-sdk-core (3.201.3)
aws-partitions (1.968.0)
aws-sdk-core (3.202.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
aws-sigv4 (~> 1.9)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.88.0)
aws-sdk-core (~> 3, >= 3.201.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.157.0)
aws-sdk-s3 (1.159.0)
aws-sdk-core (~> 3, >= 3.201.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
Expand Down Expand Up @@ -154,7 +154,7 @@ GEM
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.6)
http-cookie (1.0.7)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.6.2)
Expand All @@ -178,7 +178,7 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.3.4)
rexml (3.3.6)
strscan
rouge (2.0.7)
ruby2_keywords (0.0.5)
Expand All @@ -204,12 +204,13 @@ GEM
uber (0.1.0)
unicode-display_width (2.5.0)
word_wrap (1.0.0)
xcodeproj (1.19.0)
xcodeproj (1.25.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (>= 3.3.2, < 4.0)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
Expand All @@ -225,7 +226,7 @@ PLATFORMS
DEPENDENCIES
fastlane (= 2.222.0)
fastlane-plugin-firebase_app_distribution
rexml (>= 3.3.3)
rexml (>= 3.3.6)

RUBY VERSION
ruby 3.3.0p0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.hyperskill.app.android.study_plan.delegate

import android.content.Context
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.hyperskill.app.android.R
Expand All @@ -14,6 +12,7 @@ import org.hyperskill.app.android.study_plan.adapter.ActivityLoadingAdapterDeleg
import org.hyperskill.app.android.study_plan.adapter.StudyPlanActivityAdapterDelegate
import org.hyperskill.app.android.study_plan.adapter.StudyPlanItemAnimator
import org.hyperskill.app.android.study_plan.adapter.StudyPlanSectionAdapterDelegate
import org.hyperskill.app.android.study_plan.mapper.StudyPlanWidgetUIStateMapper
import org.hyperskill.app.android.study_plan.model.StudyPlanRecyclerItem
import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature
import org.hyperskill.app.study_plan.widget.view.model.StudyPlanWidgetViewState
Expand All @@ -27,11 +26,6 @@ class StudyPlanWidgetDelegate(
private val onNewMessage: (StudyPlanWidgetFeature.Message) -> Unit
) {

companion object {
private const val SECTIONS_LOADING_ITEMS_COUNT = 4
private const val ACTIVITIES_LOADING_ITEMS_COUNT = 3
}

private val studyPlanAdapter = DefaultDelegateAdapter<StudyPlanRecyclerItem>().apply {
addDelegate(StudyPlanSectionAdapterDelegate(onNewMessage))
addDelegate(
Expand All @@ -46,6 +40,7 @@ class StudyPlanWidgetDelegate(
)
addDelegate(sectionsLoadingAdapterDelegate())
addDelegate(loadAllTopicsButtonDelegate())
addDelegate(expandCompletedActivitiesButtonDelegate())
addDelegate(paywallAdapterDelegate())
addDelegate(ActivityLoadingAdapterDelegate())
addDelegate(
Expand All @@ -55,39 +50,15 @@ class StudyPlanWidgetDelegate(
)
}

@ColorInt private val inactiveSectionTextColor: Int =
ContextCompat.getColor(context, org.hyperskill.app.R.color.color_on_surface_alpha_60)

@ColorInt private val activeSectionTextColor: Int =
ContextCompat.getColor(context, org.hyperskill.app.R.color.color_on_surface)

@ColorInt private val activeActivityTextColor: Int =
ContextCompat.getColor(context, org.hyperskill.app.R.color.color_on_surface_alpha_87)

@ColorInt private val inactiveActivityTextColor: Int =
ContextCompat.getColor(context, org.hyperskill.app.R.color.color_on_surface_alpha_60)
private val uiStateMapper: StudyPlanWidgetUIStateMapper = StudyPlanWidgetUIStateMapper(context)

private val sectionTopMargin =
context.resources.getDimensionPixelOffset(R.dimen.study_plan_section_top_margin)
private val activityTopMargin =
context.resources.getDimensionPixelOffset(R.dimen.study_plan_activity_top_margin)

private val activeIcon =
ContextCompat.getDrawable(context, R.drawable.ic_home_screen_arrow_button)
private val skippedIcon =
ContextCompat.getDrawable(context, R.drawable.ic_topic_skipped)
private val completedIcon =
ContextCompat.getDrawable(context, R.drawable.ic_topic_completed)
private val lockedIcon =
ContextCompat.getDrawable(context, R.drawable.ic_activity_locked)

private var studyPlanViewStateDelegate: ViewStateDelegate<StudyPlanWidgetViewState>? = null

private val sectionsLoadingItems: List<StudyPlanRecyclerItem.SectionLoading> =
List(SECTIONS_LOADING_ITEMS_COUNT) { index ->
StudyPlanRecyclerItem.SectionLoading(index)
}

fun setup(recyclerView: RecyclerView, errorViewBinding: ErrorNoConnectionWithButtonBinding) {
studyPlanViewStateDelegate = ViewStateDelegate<StudyPlanWidgetViewState>().apply {
addState<StudyPlanWidgetViewState.Idle>()
Expand Down Expand Up @@ -138,7 +109,8 @@ class StudyPlanWidgetDelegate(
is StudyPlanRecyclerItem.ActivityLoading,
is StudyPlanRecyclerItem.Activity,
is StudyPlanRecyclerItem.ActivitiesError,
is StudyPlanRecyclerItem.LoadAllTopicsButton -> activityTopMargin
is StudyPlanRecyclerItem.LoadAllTopicsButton,
is StudyPlanRecyclerItem.ExpandCompletedActivitiesButton -> activityTopMargin
else -> 0
}

Expand All @@ -148,17 +120,7 @@ class StudyPlanWidgetDelegate(

fun render(state: StudyPlanWidgetViewState) {
studyPlanViewStateDelegate?.switchState(state)
when (state) {
StudyPlanWidgetViewState.Loading -> {
studyPlanAdapter.items = sectionsLoadingItems
}
is StudyPlanWidgetViewState.Content -> {
studyPlanAdapter.items = mapContentToRecyclerItems(state)
}
else -> {
// no op
}
}
studyPlanAdapter.items = uiStateMapper.map(state)
}

private fun sectionsLoadingAdapterDelegate() =
Expand Down Expand Up @@ -188,87 +150,17 @@ class StudyPlanWidgetDelegate(
}
}

private fun mapContentToRecyclerItems(
studyPlanContent: StudyPlanWidgetViewState.Content
): List<StudyPlanRecyclerItem> =
buildList {
if (studyPlanContent.isPaywallBannerShown) {
add(StudyPlanRecyclerItem.PaywallBanner)
}
studyPlanContent.sections.forEachIndexed { sectionIndex, section ->
add(mapSectionToRecyclerItem(sectionIndex, section))
when (val sectionContent = section.content) {
StudyPlanWidgetViewState.SectionContent.Collapsed -> {
// no op
}
StudyPlanWidgetViewState.SectionContent.Loading -> {
addAll(getActivitiesLoadingItems(section.id))
}
is StudyPlanWidgetViewState.SectionContent.Content -> {
addAll(mapSectionItemsToActivityItems(section.id, sectionContent.sectionItems))
if (sectionContent.isLoadAllTopicsButtonShown) {
add(StudyPlanRecyclerItem.LoadAllTopicsButton(section.id))
}
if (sectionContent.isNextPageLoadingShowed) {
addAll(getActivitiesLoadingItems(section.id))
}
}
StudyPlanWidgetViewState.SectionContent.Error -> {
add(StudyPlanRecyclerItem.ActivitiesError(section.id))
}
private fun expandCompletedActivitiesButtonDelegate() =
adapterDelegate<StudyPlanRecyclerItem, StudyPlanRecyclerItem.ExpandCompletedActivitiesButton>(
R.layout.item_study_plan_expand_completed_button
) {
itemView.setOnClickListener {
val sectionId = item?.sectionId
if (sectionId != null) {
onNewMessage(
StudyPlanWidgetFeature.Message.ExpandCompletedActivitiesClicked(sectionId)
)
}
}
}

private fun mapSectionToRecyclerItem(
index: Int,
section: StudyPlanWidgetViewState.Section
): StudyPlanRecyclerItem.Section =
StudyPlanRecyclerItem.Section(
id = section.id,
title = section.title,
titleTextColor = if (index == 0) {
activeSectionTextColor
} else {
inactiveSectionTextColor
},
subtitle = section.subtitle,
formattedTopicsCount = section.formattedTopicsCount,
formattedTimeToComplete = section.formattedTimeToComplete,
isExpanded = section.content !is StudyPlanWidgetViewState.SectionContent.Collapsed,
isCurrentBadgeShown = section.isCurrentBadgeShown
)

private fun mapSectionItemsToActivityItems(
sectionId: Long,
sectionItems: List<StudyPlanWidgetViewState.SectionItem>
): List<StudyPlanRecyclerItem.Activity> =
sectionItems.map { item ->
StudyPlanRecyclerItem.Activity(
id = item.id,
sectionId = sectionId,
title = item.title,
subtitle = item.subtitle,
titleTextColor = if (item.state == StudyPlanWidgetViewState.SectionItemState.NEXT) {
activeActivityTextColor
} else {
inactiveActivityTextColor
},
progress = item.progress,
formattedProgress = item.formattedProgress,
endIcon = when (item.state) {
StudyPlanWidgetViewState.SectionItemState.IDLE -> null
StudyPlanWidgetViewState.SectionItemState.NEXT -> activeIcon
StudyPlanWidgetViewState.SectionItemState.SKIPPED -> skippedIcon
StudyPlanWidgetViewState.SectionItemState.COMPLETED -> completedIcon
StudyPlanWidgetViewState.SectionItemState.LOCKED -> lockedIcon
},
isIdeRequired = item.isIdeRequired
)
}

private fun getActivitiesLoadingItems(sectionId: Long) =
List(ACTIVITIES_LOADING_ITEMS_COUNT) { index ->
StudyPlanRecyclerItem.ActivityLoading(sectionId, index)
}
}
Loading

0 comments on commit 920d4d2

Please sign in to comment.