Skip to content

Commit 29e1c8e

Browse files
feat: [FC-0047] Full-Bleed Header + Top Navigation (#278)
* feat: New header and navigation on CourseContainerFragment * feat: Changed logic of swipe to refresh, added blur for android <= 12, minor code refactoring * feat: removed COURSE_TOP_BAR_ENABLED and COURSE_BANNER_ENABLED feature flags * feat: special header style for android < 12 * fix: Fixed header image blur for android < 12. Added courseContainerTabClickedEvent * feat: auto scrolling header to collapsed and expanded states * fix: Fixed junit tests * fix: Fixed CourseContainerViewModelTest * fix: auto scroll fling fix * feat: CourseContainerFragment refactoring * fix: Removed expanded header content top padding * fix: Collapsing header and navigation tabs UI fixes * fix: Fixes according to PR feedback * refactor: Course home tabs layout * fix: Fixes according to PR feedback * fix: Fixes according to PR feedback * refactor: Refactored view models of course container screens * fix: Fixes according to PR feedback
1 parent 0494642 commit 29e1c8e

File tree

57 files changed

+2597
-1667
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2597
-1667
lines changed

Documentation/ConfigurationManagement.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ android:
8989
- **WHATS_NEW_ENABLED:** Enables the "What's New" feature to present the latest changes to the user.
9090
- **SOCIAL_AUTH_ENABLED:** Enables SSO buttons on the SignIn and SignUp screens.
9191
- **COURSE_NESTED_LIST_ENABLED:** Enables an alternative visual representation for the course structure.
92-
- **COURSE_BANNER_ENABLED:** Enables the display of the course image on the Course Home screen.
93-
- **COURSE_TOP_TAB_BAR_ENABLED:** Enables an alternative navigation on the Course Home screen.
9492
- **COURSE_UNIT_PROGRESS_ENABLED:** Enables the display of the unit progress within the courseware.
9593

9694
## Future Support

app/src/main/java/org/openedx/app/di/AppModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import org.openedx.auth.presentation.sso.FacebookAuthHelper
2525
import org.openedx.auth.presentation.sso.GoogleAuthHelper
2626
import org.openedx.auth.presentation.sso.MicrosoftAuthHelper
2727
import org.openedx.auth.presentation.sso.OAuthHelper
28+
import org.openedx.core.ImageProcessor
2829
import org.openedx.core.config.Config
2930
import org.openedx.core.data.model.CourseEnrollments
3031
import org.openedx.core.data.storage.CorePreferences
@@ -81,6 +82,8 @@ val appModule = module {
8182
single { ReviewManagerFactory.create(get()) }
8283
single { CalendarManager(get(), get(), get()) }
8384

85+
single { ImageProcessor(get()) }
86+
8487
single<Gson> {
8588
GsonBuilder()
8689
.registerTypeAdapter(CourseEnrollments::class.java, CourseEnrollments.Deserializer())

app/src/main/java/org/openedx/app/di/ScreenModule.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,14 @@ val screenModule = module {
193193
get(),
194194
get(),
195195
get(),
196+
get(),
197+
get()
196198
)
197199
}
198-
viewModel { (courseId: String) ->
200+
viewModel { (courseId: String, courseTitle: String) ->
199201
CourseOutlineViewModel(
200202
courseId,
203+
courseTitle,
201204
get(),
202205
get(),
203206
get(),
@@ -234,9 +237,10 @@ val screenModule = module {
234237
get(),
235238
)
236239
}
237-
viewModel { (courseId: String) ->
240+
viewModel { (courseId: String, courseTitle: String) ->
238241
CourseVideoViewModel(
239242
courseId,
243+
courseTitle,
240244
get(),
241245
get(),
242246
get(),
@@ -275,11 +279,8 @@ val screenModule = module {
275279
get(),
276280
)
277281
}
278-
viewModel { (courseId: String, courseName: String, isSelfPaced: Boolean, enrollmentMode: String) ->
282+
viewModel { (enrollmentMode: String) ->
279283
CourseDatesViewModel(
280-
courseId,
281-
courseName,
282-
isSelfPaced,
283284
enrollmentMode,
284285
get(),
285286
get(),
@@ -288,7 +289,6 @@ val screenModule = module {
288289
get(),
289290
get(),
290291
get(),
291-
get(),
292292
)
293293
}
294294
viewModel { (courseId: String, handoutsType: String) ->
@@ -305,13 +305,13 @@ val screenModule = module {
305305

306306
single { DiscussionRepository(get(), get(), get()) }
307307
factory { DiscussionInteractor(get()) }
308-
viewModel { (courseId: String) ->
308+
viewModel {
309309
DiscussionTopicsViewModel(
310310
get(),
311311
get(),
312312
get(),
313313
get(),
314-
courseId
314+
get()
315315
)
316316
}
317317
viewModel { (courseId: String, topicId: String, threadType: String) ->

core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ dependencies {
139139
// Koin DI
140140
api "io.insert-koin:koin-core:$koin_version"
141141
api "io.insert-koin:koin-android:$koin_version"
142+
api "io.insert-koin:koin-androidx-compose:$koin_version"
142143

143144
api "io.coil-kt:coil-compose:$coil_version"
144145
api "io.coil-kt:coil-gif:$coil_version"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
@file:Suppress("DEPRECATION")
2+
3+
package org.openedx.core
4+
5+
import android.content.Context
6+
import android.graphics.Bitmap
7+
import android.graphics.drawable.Drawable
8+
import android.renderscript.Allocation
9+
import android.renderscript.RenderScript
10+
import android.renderscript.ScriptIntrinsicBlur
11+
import androidx.annotation.DrawableRes
12+
import coil.ImageLoader
13+
import coil.request.ImageRequest
14+
15+
class ImageProcessor(private val context: Context) {
16+
fun loadImage(
17+
@DrawableRes
18+
defaultImage: Int,
19+
imageUrl: String,
20+
onComplete: (result: Drawable) -> Unit
21+
) {
22+
val loader = ImageLoader(context)
23+
val request = ImageRequest.Builder(context)
24+
.data(imageUrl)
25+
.target { result ->
26+
onComplete(result)
27+
}
28+
.error(defaultImage)
29+
.placeholder(defaultImage)
30+
.allowHardware(false)
31+
.build()
32+
loader.enqueue(request)
33+
}
34+
35+
fun applyBlur(
36+
bitmap: Bitmap,
37+
blurRadio: Float
38+
): Bitmap {
39+
val renderScript = RenderScript.create(context)
40+
val bitmapAlloc = Allocation.createFromBitmap(renderScript, bitmap)
41+
ScriptIntrinsicBlur.create(renderScript, bitmapAlloc.element).apply {
42+
setRadius(blurRadio)
43+
setInput(bitmapAlloc)
44+
repeat(3) {
45+
forEach(bitmapAlloc)
46+
}
47+
}
48+
val newBitmap: Bitmap = Bitmap.createBitmap(
49+
bitmap.width,
50+
bitmap.height,
51+
Bitmap.Config.ARGB_8888
52+
)
53+
bitmapAlloc.copyTo(newBitmap)
54+
renderScript.destroy()
55+
return newBitmap
56+
}
57+
}

core/src/main/java/org/openedx/core/config/Config.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,6 @@ class Config(context: Context) {
107107
return getBoolean(COURSE_NESTED_LIST_ENABLED, false)
108108
}
109109

110-
fun isCourseBannerEnabled(): Boolean {
111-
return getBoolean(COURSE_BANNER_ENABLED, true)
112-
}
113-
114-
fun isCourseTopTabBarEnabled(): Boolean {
115-
return getBoolean(COURSE_TOP_TAB_BAR_ENABLED, false)
116-
}
117-
118110
fun isCourseUnitProgressEnabled(): Boolean {
119111
return getBoolean(COURSE_UNIT_PROGRESS_ENABLED, false)
120112
}
@@ -174,8 +166,6 @@ class Config(context: Context) {
174166
private const val PROGRAM = "PROGRAM"
175167
private const val BRANCH = "BRANCH"
176168
private const val COURSE_NESTED_LIST_ENABLED = "COURSE_NESTED_LIST_ENABLED"
177-
private const val COURSE_BANNER_ENABLED = "COURSE_BANNER_ENABLED"
178-
private const val COURSE_TOP_TAB_BAR_ENABLED = "COURSE_TOP_TAB_BAR_ENABLED"
179169
private const val COURSE_UNIT_PROGRESS_ENABLED = "COURSE_UNIT_PROGRESS_ENABLED"
180170
private const val PLATFORM_NAME = "PLATFORM_NAME"
181171
}

core/src/main/java/org/openedx/core/module/download/BaseDownloadViewModel.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.openedx.core.module.download
22

3-
import androidx.lifecycle.LifecycleOwner
43
import androidx.lifecycle.viewModelScope
54
import kotlinx.coroutines.flow.MutableSharedFlow
65
import kotlinx.coroutines.flow.asSharedFlow
@@ -41,8 +40,7 @@ abstract class BaseDownloadViewModel(
4140
private val _downloadingModelsFlow = MutableSharedFlow<List<DownloadModel>>()
4241
protected val downloadingModelsFlow = _downloadingModelsFlow.asSharedFlow()
4342

44-
override fun onCreate(owner: LifecycleOwner) {
45-
super.onCreate(owner)
43+
init {
4644
viewModelScope.launch {
4745
downloadDao.readAllData().map { list -> list.map { it.mapToDomain() } }
4846
.collect { downloadModels ->
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.openedx.core.presentation.course
2+
3+
import androidx.annotation.StringRes
4+
import androidx.compose.material.icons.Icons
5+
import androidx.compose.material.icons.automirrored.filled.Chat
6+
import androidx.compose.material.icons.automirrored.filled.TextSnippet
7+
import androidx.compose.material.icons.filled.Home
8+
import androidx.compose.material.icons.outlined.CalendarMonth
9+
import androidx.compose.material.icons.rounded.PlayCircleFilled
10+
import androidx.compose.ui.graphics.vector.ImageVector
11+
import org.openedx.core.R
12+
import org.openedx.core.ui.TabItem
13+
14+
enum class CourseContainerTab(
15+
@StringRes
16+
override val labelResId: Int,
17+
override val icon: ImageVector
18+
) : TabItem {
19+
HOME(R.string.core_course_container_nav_home, Icons.Default.Home),
20+
VIDEOS(R.string.core_course_container_nav_videos, Icons.Rounded.PlayCircleFilled),
21+
DATES(R.string.core_course_container_nav_dates, Icons.Outlined.CalendarMonth),
22+
DISCUSSIONS(R.string.core_course_container_nav_discussions, Icons.AutoMirrored.Filled.Chat),
23+
MORE(R.string.core_course_container_nav_more, Icons.AutoMirrored.Filled.TextSnippet)
24+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.openedx.core.system.notifier
2+
3+
import org.openedx.core.domain.model.CourseStructure
4+
5+
data class CourseDataReady(val courseStructure: CourseStructure) : CourseEvent
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package org.openedx.core.system.notifier
2+
3+
object CourseDatesShifted : CourseEvent

0 commit comments

Comments
 (0)