1
1
package org.hyperskill.app.android.study_plan.delegate
2
2
3
3
import android.content.Context
4
- import androidx.annotation.ColorInt
5
- import androidx.core.content.ContextCompat
6
4
import androidx.recyclerview.widget.LinearLayoutManager
7
5
import androidx.recyclerview.widget.RecyclerView
8
6
import org.hyperskill.app.android.R
@@ -14,6 +12,7 @@ import org.hyperskill.app.android.study_plan.adapter.ActivityLoadingAdapterDeleg
14
12
import org.hyperskill.app.android.study_plan.adapter.StudyPlanActivityAdapterDelegate
15
13
import org.hyperskill.app.android.study_plan.adapter.StudyPlanItemAnimator
16
14
import org.hyperskill.app.android.study_plan.adapter.StudyPlanSectionAdapterDelegate
15
+ import org.hyperskill.app.android.study_plan.mapper.StudyPlanWidgetUIStateMapper
17
16
import org.hyperskill.app.android.study_plan.model.StudyPlanRecyclerItem
18
17
import org.hyperskill.app.study_plan.widget.presentation.StudyPlanWidgetFeature
19
18
import org.hyperskill.app.study_plan.widget.view.model.StudyPlanWidgetViewState
@@ -27,11 +26,6 @@ class StudyPlanWidgetDelegate(
27
26
private val onNewMessage : (StudyPlanWidgetFeature .Message ) -> Unit
28
27
) {
29
28
30
- companion object {
31
- private const val SECTIONS_LOADING_ITEMS_COUNT = 4
32
- private const val ACTIVITIES_LOADING_ITEMS_COUNT = 3
33
- }
34
-
35
29
private val studyPlanAdapter = DefaultDelegateAdapter <StudyPlanRecyclerItem >().apply {
36
30
addDelegate(StudyPlanSectionAdapterDelegate (onNewMessage))
37
31
addDelegate(
@@ -46,6 +40,7 @@ class StudyPlanWidgetDelegate(
46
40
)
47
41
addDelegate(sectionsLoadingAdapterDelegate())
48
42
addDelegate(loadAllTopicsButtonDelegate())
43
+ addDelegate(expandCompletedActivitiesButtonDelegate())
49
44
addDelegate(paywallAdapterDelegate())
50
45
addDelegate(ActivityLoadingAdapterDelegate ())
51
46
addDelegate(
@@ -55,39 +50,15 @@ class StudyPlanWidgetDelegate(
55
50
)
56
51
}
57
52
58
- @ColorInt private val inactiveSectionTextColor: Int =
59
- ContextCompat .getColor(context, org.hyperskill.app.R .color.color_on_surface_alpha_60)
60
-
61
- @ColorInt private val activeSectionTextColor: Int =
62
- ContextCompat .getColor(context, org.hyperskill.app.R .color.color_on_surface)
63
-
64
- @ColorInt private val activeActivityTextColor: Int =
65
- ContextCompat .getColor(context, org.hyperskill.app.R .color.color_on_surface_alpha_87)
66
-
67
- @ColorInt private val inactiveActivityTextColor: Int =
68
- ContextCompat .getColor(context, org.hyperskill.app.R .color.color_on_surface_alpha_60)
53
+ private val uiStateMapper: StudyPlanWidgetUIStateMapper = StudyPlanWidgetUIStateMapper (context)
69
54
70
55
private val sectionTopMargin =
71
56
context.resources.getDimensionPixelOffset(R .dimen.study_plan_section_top_margin)
72
57
private val activityTopMargin =
73
58
context.resources.getDimensionPixelOffset(R .dimen.study_plan_activity_top_margin)
74
59
75
- private val activeIcon =
76
- ContextCompat .getDrawable(context, R .drawable.ic_home_screen_arrow_button)
77
- private val skippedIcon =
78
- ContextCompat .getDrawable(context, R .drawable.ic_topic_skipped)
79
- private val completedIcon =
80
- ContextCompat .getDrawable(context, R .drawable.ic_topic_completed)
81
- private val lockedIcon =
82
- ContextCompat .getDrawable(context, R .drawable.ic_activity_locked)
83
-
84
60
private var studyPlanViewStateDelegate: ViewStateDelegate <StudyPlanWidgetViewState >? = null
85
61
86
- private val sectionsLoadingItems: List <StudyPlanRecyclerItem .SectionLoading > =
87
- List (SECTIONS_LOADING_ITEMS_COUNT ) { index ->
88
- StudyPlanRecyclerItem .SectionLoading (index)
89
- }
90
-
91
62
fun setup (recyclerView : RecyclerView , errorViewBinding : ErrorNoConnectionWithButtonBinding ) {
92
63
studyPlanViewStateDelegate = ViewStateDelegate <StudyPlanWidgetViewState >().apply {
93
64
addState<StudyPlanWidgetViewState .Idle >()
@@ -138,7 +109,8 @@ class StudyPlanWidgetDelegate(
138
109
is StudyPlanRecyclerItem .ActivityLoading ,
139
110
is StudyPlanRecyclerItem .Activity ,
140
111
is StudyPlanRecyclerItem .ActivitiesError ,
141
- is StudyPlanRecyclerItem .LoadAllTopicsButton -> activityTopMargin
112
+ is StudyPlanRecyclerItem .LoadAllTopicsButton ,
113
+ is StudyPlanRecyclerItem .ExpandCompletedActivitiesButton -> activityTopMargin
142
114
else -> 0
143
115
}
144
116
@@ -148,17 +120,7 @@ class StudyPlanWidgetDelegate(
148
120
149
121
fun render (state : StudyPlanWidgetViewState ) {
150
122
studyPlanViewStateDelegate?.switchState(state)
151
- when (state) {
152
- StudyPlanWidgetViewState .Loading -> {
153
- studyPlanAdapter.items = sectionsLoadingItems
154
- }
155
- is StudyPlanWidgetViewState .Content -> {
156
- studyPlanAdapter.items = mapContentToRecyclerItems(state)
157
- }
158
- else -> {
159
- // no op
160
- }
161
- }
123
+ studyPlanAdapter.items = uiStateMapper.map(state)
162
124
}
163
125
164
126
private fun sectionsLoadingAdapterDelegate () =
@@ -188,87 +150,17 @@ class StudyPlanWidgetDelegate(
188
150
}
189
151
}
190
152
191
- private fun mapContentToRecyclerItems (
192
- studyPlanContent : StudyPlanWidgetViewState .Content
193
- ): List <StudyPlanRecyclerItem > =
194
- buildList {
195
- if (studyPlanContent.isPaywallBannerShown) {
196
- add(StudyPlanRecyclerItem .PaywallBanner )
197
- }
198
- studyPlanContent.sections.forEachIndexed { sectionIndex, section ->
199
- add(mapSectionToRecyclerItem(sectionIndex, section))
200
- when (val sectionContent = section.content) {
201
- StudyPlanWidgetViewState .SectionContent .Collapsed -> {
202
- // no op
203
- }
204
- StudyPlanWidgetViewState .SectionContent .Loading -> {
205
- addAll(getActivitiesLoadingItems(section.id))
206
- }
207
- is StudyPlanWidgetViewState .SectionContent .Content -> {
208
- addAll(mapSectionItemsToActivityItems(section.id, sectionContent.sectionItems))
209
- if (sectionContent.isLoadAllTopicsButtonShown) {
210
- add(StudyPlanRecyclerItem .LoadAllTopicsButton (section.id))
211
- }
212
- if (sectionContent.isNextPageLoadingShowed) {
213
- addAll(getActivitiesLoadingItems(section.id))
214
- }
215
- }
216
- StudyPlanWidgetViewState .SectionContent .Error -> {
217
- add(StudyPlanRecyclerItem .ActivitiesError (section.id))
218
- }
153
+ private fun expandCompletedActivitiesButtonDelegate () =
154
+ adapterDelegate<StudyPlanRecyclerItem , StudyPlanRecyclerItem .ExpandCompletedActivitiesButton >(
155
+ R .layout.item_study_plan_expand_completed_button
156
+ ) {
157
+ itemView.setOnClickListener {
158
+ val sectionId = item?.sectionId
159
+ if (sectionId != null ) {
160
+ onNewMessage(
161
+ StudyPlanWidgetFeature .Message .ExpandCompletedActivitiesClicked (sectionId)
162
+ )
219
163
}
220
164
}
221
165
}
222
-
223
- private fun mapSectionToRecyclerItem (
224
- index : Int ,
225
- section : StudyPlanWidgetViewState .Section
226
- ): StudyPlanRecyclerItem .Section =
227
- StudyPlanRecyclerItem .Section (
228
- id = section.id,
229
- title = section.title,
230
- titleTextColor = if (index == 0 ) {
231
- activeSectionTextColor
232
- } else {
233
- inactiveSectionTextColor
234
- },
235
- subtitle = section.subtitle,
236
- formattedTopicsCount = section.formattedTopicsCount,
237
- formattedTimeToComplete = section.formattedTimeToComplete,
238
- isExpanded = section.content !is StudyPlanWidgetViewState .SectionContent .Collapsed ,
239
- isCurrentBadgeShown = section.isCurrentBadgeShown
240
- )
241
-
242
- private fun mapSectionItemsToActivityItems (
243
- sectionId : Long ,
244
- sectionItems : List <StudyPlanWidgetViewState .SectionItem >
245
- ): List <StudyPlanRecyclerItem .Activity > =
246
- sectionItems.map { item ->
247
- StudyPlanRecyclerItem .Activity (
248
- id = item.id,
249
- sectionId = sectionId,
250
- title = item.title,
251
- subtitle = item.subtitle,
252
- titleTextColor = if (item.state == StudyPlanWidgetViewState .SectionItemState .NEXT ) {
253
- activeActivityTextColor
254
- } else {
255
- inactiveActivityTextColor
256
- },
257
- progress = item.progress,
258
- formattedProgress = item.formattedProgress,
259
- endIcon = when (item.state) {
260
- StudyPlanWidgetViewState .SectionItemState .IDLE -> null
261
- StudyPlanWidgetViewState .SectionItemState .NEXT -> activeIcon
262
- StudyPlanWidgetViewState .SectionItemState .SKIPPED -> skippedIcon
263
- StudyPlanWidgetViewState .SectionItemState .COMPLETED -> completedIcon
264
- StudyPlanWidgetViewState .SectionItemState .LOCKED -> lockedIcon
265
- },
266
- isIdeRequired = item.isIdeRequired
267
- )
268
- }
269
-
270
- private fun getActivitiesLoadingItems (sectionId : Long ) =
271
- List (ACTIVITIES_LOADING_ITEMS_COUNT ) { index ->
272
- StudyPlanRecyclerItem .ActivityLoading (sectionId, index)
273
- }
274
166
}
0 commit comments