Skip to content

Commit

Permalink
Merge pull request openedx#314 from openedx/develop
Browse files Browse the repository at this point in the history
Develop to main v1.5.1
  • Loading branch information
volodymyr-chekyrta committed May 6, 2024
2 parents bccf5ed + 4d782ee commit 4d36310
Show file tree
Hide file tree
Showing 109 changed files with 4,983 additions and 3,369 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Generate mock files
run: ./gradlew generateMockedRawFile
- name: Run unit tests
run: ./gradlew testProdReleaseUnitTest $CI_GRADLE_ARG_PROPERTIES
run: ./gradlew testProdDebugUnitTest $CI_GRADLE_ARG_PROPERTIES

- name: Upload reports
uses: actions/upload-artifact@v3
Expand Down
6 changes: 2 additions & 4 deletions Documentation/ConfigurationManagement.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ MICROSOFT:
CLIENT_ID: 'microsoftClientID'
```
Also, all envirenment folders contain a `file_mappings.yaml` file that points to the config files to be parsed.
Also, all environment folders contain a `file_mappings.yaml` file that points to the config files to be parsed.

By modifying `file_mappings.yaml`, you can achieve splitting of the base `config.yaml` or add additional configuration files.

Expand All @@ -81,16 +81,14 @@ android:
- **Microsoft:** Sign in and Sign up via Microsoft
- **Facebook:** Sign in and Sign up via Facebook
- **Branch:** Deeplinks
- **Braze:** Could Messaging
- **Braze:** Cloud Messaging
- **SegmentIO:** Analytics

## Available Feature Flags
- **PRE_LOGIN_EXPERIENCE_ENABLED:** Enables the pre login courses discovery experience.
- **WHATS_NEW_ENABLED:** Enables the "What's New" feature to present the latest changes to the user.
- **SOCIAL_AUTH_ENABLED:** Enables SSO buttons on the SignIn and SignUp screens.
- **COURSE_NESTED_LIST_ENABLED:** Enables an alternative visual representation for the course structure.
- **COURSE_BANNER_ENABLED:** Enables the display of the course image on the Course Home screen.
- **COURSE_TOP_TAB_BAR_ENABLED:** Enables an alternative navigation on the Course Home screen.
- **COURSE_UNIT_PROGRESS_ENABLED:** Enables the display of the unit progress within the courseware.

## Future Support
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Modern vision of the mobile application for the Open edX platform from Raccoon G

3. Choose ``openedx-app-android``.

4. Configure `config_settings.yaml` inside `default_config` and `config.yaml` inside sub direcroties to point to your Open edX configuration. [Configuration Docuementation](./Documentation/ConfigurationManagement.md)
4. Configure `config_settings.yaml` inside `default_config` and `config.yaml` inside sub directories to point to your Open edX configuration. [Configuration Documentation](./Documentation/ConfigurationManagement.md)

5. Select the build variant ``develop``, ``stage``, or ``prod``.

Expand Down
38 changes: 26 additions & 12 deletions app/src/main/java/org/openedx/app/AppRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ import org.openedx.discussion.presentation.threads.DiscussionAddThreadFragment
import org.openedx.discussion.presentation.threads.DiscussionThreadsFragment
import org.openedx.profile.domain.model.Account
import org.openedx.profile.presentation.ProfileRouter
import org.openedx.profile.presentation.anothers_account.AnothersProfileFragment
import org.openedx.profile.presentation.anothersaccount.AnothersProfileFragment
import org.openedx.profile.presentation.delete.DeleteProfileFragment
import org.openedx.profile.presentation.edit.EditProfileFragment
import org.openedx.profile.presentation.manageaccount.ManageAccountFragment
import org.openedx.profile.presentation.profile.ProfileFragment
import org.openedx.profile.presentation.settings.video.VideoSettingsFragment
import org.openedx.profile.presentation.settings.SettingsFragment
import org.openedx.profile.presentation.video.VideoSettingsFragment
import org.openedx.whatsnew.WhatsNewRouter
import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment

Expand Down Expand Up @@ -328,22 +330,14 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
replaceFragmentWithBackStack(fm, EditProfileFragment.newInstance(account))
}

override fun navigateToVideoSettings(fm: FragmentManager) {
replaceFragmentWithBackStack(fm, VideoSettingsFragment())
}

override fun navigateToVideoQuality(fm: FragmentManager, videoQualityType: VideoQualityType) {
replaceFragmentWithBackStack(fm, VideoQualityFragment.newInstance(videoQualityType.name))
}

override fun navigateToDeleteAccount(fm: FragmentManager) {
replaceFragmentWithBackStack(fm, DeleteProfileFragment())
}

override fun navigateToWebContent(fm: FragmentManager, title: String, url: String) {
override fun navigateToSettings(fm: FragmentManager) {
replaceFragmentWithBackStack(
fm,
WebContentFragment.newInstance(title = title, url = url)
SettingsFragment()
)
}

Expand All @@ -357,6 +351,25 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
}
}
}

override fun navigateToVideoSettings(fm: FragmentManager) {
replaceFragmentWithBackStack(fm, VideoSettingsFragment())
}

override fun navigateToVideoQuality(fm: FragmentManager, videoQualityType: VideoQualityType) {
replaceFragmentWithBackStack(fm, VideoQualityFragment.newInstance(videoQualityType.name))
}

override fun navigateToWebContent(fm: FragmentManager, title: String, url: String) {
replaceFragmentWithBackStack(
fm,
WebContentFragment.newInstance(title = title, url = url)
)
}

override fun navigateToManageAccount(fm: FragmentManager) {
replaceFragmentWithBackStack(fm, ManageAccountFragment())
}
//endregion

private fun replaceFragmentWithBackStack(fm: FragmentManager, fragment: Fragment) {
Expand Down Expand Up @@ -384,4 +397,5 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
.replace(R.id.container, ProfileFragment())
.commit()
}
//endregion
}
3 changes: 3 additions & 0 deletions app/src/main/java/org/openedx/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.openedx.auth.presentation.sso.FacebookAuthHelper
import org.openedx.auth.presentation.sso.GoogleAuthHelper
import org.openedx.auth.presentation.sso.MicrosoftAuthHelper
import org.openedx.auth.presentation.sso.OAuthHelper
import org.openedx.core.ImageProcessor
import org.openedx.core.config.Config
import org.openedx.core.data.model.CourseEnrollments
import org.openedx.core.data.storage.CorePreferences
Expand Down Expand Up @@ -81,6 +82,8 @@ val appModule = module {
single { ReviewManagerFactory.create(get()) }
single { CalendarManager(get(), get(), get()) }

single { ImageProcessor(get()) }

single<Gson> {
GsonBuilder()
.registerTypeAdapter(CourseEnrollments::class.java, CourseEnrollments.Deserializer())
Expand Down
35 changes: 17 additions & 18 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ import org.openedx.discussion.presentation.topics.DiscussionTopicsViewModel
import org.openedx.profile.data.repository.ProfileRepository
import org.openedx.profile.domain.interactor.ProfileInteractor
import org.openedx.profile.domain.model.Account
import org.openedx.profile.presentation.anothers_account.AnothersProfileViewModel
import org.openedx.profile.presentation.anothersaccount.AnothersProfileViewModel
import org.openedx.profile.presentation.delete.DeleteProfileViewModel
import org.openedx.profile.presentation.edit.EditProfileViewModel
import org.openedx.profile.presentation.manageaccount.ManageAccountViewModel
import org.openedx.profile.presentation.profile.ProfileViewModel
import org.openedx.profile.presentation.settings.video.VideoSettingsViewModel
import org.openedx.profile.presentation.settings.SettingsViewModel
import org.openedx.profile.presentation.video.VideoSettingsViewModel
import org.openedx.whatsnew.presentation.whatsnew.WhatsNewViewModel

val screenModule = module {
Expand Down Expand Up @@ -134,24 +136,20 @@ val screenModule = module {
factory { ProfileInteractor(get()) }
viewModel {
ProfileViewModel(
appData = get(),
config = get(),
interactor = get(),
resourceManager = get(),
notifier = get(),
dispatcher = get(named("IODispatcher")),
cookieManager = get(),
workerController = get(),
analytics = get(),
appUpgradeNotifier = get(),
router = get(),
profileRouter = get(),
)
}
viewModel { (account: Account) -> EditProfileViewModel(get(), get(), get(), get(), account) }
viewModel { VideoSettingsViewModel(get(), get(), get(), get()) }
viewModel { (qualityType: String) -> VideoQualityViewModel(qualityType, get(), get(), get()) }
viewModel { DeleteProfileViewModel(get(), get(), get(), get(), get()) }
viewModel { (username: String) -> AnothersProfileViewModel(get(), get(), username) }
viewModel { SettingsViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { ManageAccountViewModel(get(), get(), get(), get(), get()) }

single { CourseRepository(get(), get(), get(), get()) }
factory { CourseInteractor(get()) }
Expand Down Expand Up @@ -195,11 +193,14 @@ val screenModule = module {
get(),
get(),
get(),
get(),
get()
)
}
viewModel { (courseId: String) ->
viewModel { (courseId: String, courseTitle: String) ->
CourseOutlineViewModel(
courseId,
courseTitle,
get(),
get(),
get(),
Expand Down Expand Up @@ -236,9 +237,10 @@ val screenModule = module {
get(),
)
}
viewModel { (courseId: String) ->
viewModel { (courseId: String, courseTitle: String) ->
CourseVideoViewModel(
courseId,
courseTitle,
get(),
get(),
get(),
Expand Down Expand Up @@ -277,11 +279,8 @@ val screenModule = module {
get(),
)
}
viewModel { (courseId: String, courseName: String, isSelfPaced: Boolean, enrollmentMode: String) ->
viewModel { (enrollmentMode: String) ->
CourseDatesViewModel(
courseId,
courseName,
isSelfPaced,
enrollmentMode,
get(),
get(),
Expand All @@ -290,7 +289,6 @@ val screenModule = module {
get(),
get(),
get(),
get(),
)
}
viewModel { (courseId: String, handoutsType: String) ->
Expand All @@ -307,13 +305,13 @@ val screenModule = module {

single { DiscussionRepository(get(), get(), get()) }
factory { DiscussionInteractor(get()) }
viewModel { (courseId: String) ->
viewModel {
DiscussionTopicsViewModel(
get(),
get(),
get(),
get(),
courseId
get()
)
}
viewModel { (courseId: String, topicId: String, threadType: String) ->
Expand Down Expand Up @@ -377,4 +375,5 @@ val screenModule = module {
viewModel { HtmlUnitViewModel(get(), get(), get(), get()) }

viewModel { ProgramViewModel(get(), get(), get(), get(), get(), get(), get()) }

}
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ buildscript {
}

plugins {
id 'com.android.application' version '8.3.0' apply false
id 'com.android.library' version '8.3.0' apply false
id 'com.android.application' version '8.4.0' apply false
id 'com.android.library' version '8.4.0' apply false
id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false
id 'com.google.gms.google-services' version '4.3.15' apply false
id "com.google.firebase.crashlytics" version "2.9.6" apply false
Expand Down
2 changes: 2 additions & 0 deletions catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ metadata:
- url: "https://github.com/openedx/openedx-app-android/tree/main/Documentation"
title: "Documentation"
icon: "PhoneAndroid"
annotations:
openedx.org/release: "main"
spec:
owner: group:openedx-mobile-maintainers
type: 'mobile'
Expand Down
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ dependencies {
// Koin DI
api "io.insert-koin:koin-core:$koin_version"
api "io.insert-koin:koin-android:$koin_version"
api "io.insert-koin:koin-androidx-compose:$koin_version"

api "io.coil-kt:coil-compose:$coil_version"
api "io.coil-kt:coil-gif:$coil_version"
Expand Down
57 changes: 57 additions & 0 deletions core/src/main/java/org/openedx/core/ImageProcessor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@file:Suppress("DEPRECATION")

package org.openedx.core

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.renderscript.Allocation
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import androidx.annotation.DrawableRes
import coil.ImageLoader
import coil.request.ImageRequest

class ImageProcessor(private val context: Context) {
fun loadImage(
@DrawableRes
defaultImage: Int,
imageUrl: String,
onComplete: (result: Drawable) -> Unit
) {
val loader = ImageLoader(context)
val request = ImageRequest.Builder(context)
.data(imageUrl)
.target { result ->
onComplete(result)
}
.error(defaultImage)
.placeholder(defaultImage)
.allowHardware(false)
.build()
loader.enqueue(request)
}

fun applyBlur(
bitmap: Bitmap,
blurRadio: Float
): Bitmap {
val renderScript = RenderScript.create(context)
val bitmapAlloc = Allocation.createFromBitmap(renderScript, bitmap)
ScriptIntrinsicBlur.create(renderScript, bitmapAlloc.element).apply {
setRadius(blurRadio)
setInput(bitmapAlloc)
repeat(3) {
forEach(bitmapAlloc)
}
}
val newBitmap: Bitmap = Bitmap.createBitmap(
bitmap.width,
bitmap.height,
Bitmap.Config.ARGB_8888
)
bitmapAlloc.copyTo(newBitmap)
renderScript.destroy()
return newBitmap
}
}
10 changes: 0 additions & 10 deletions core/src/main/java/org/openedx/core/config/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,6 @@ class Config(context: Context) {
return getBoolean(COURSE_NESTED_LIST_ENABLED, false)
}

fun isCourseBannerEnabled(): Boolean {
return getBoolean(COURSE_BANNER_ENABLED, true)
}

fun isCourseTopTabBarEnabled(): Boolean {
return getBoolean(COURSE_TOP_TAB_BAR_ENABLED, false)
}

fun isCourseUnitProgressEnabled(): Boolean {
return getBoolean(COURSE_UNIT_PROGRESS_ENABLED, false)
}
Expand Down Expand Up @@ -174,8 +166,6 @@ class Config(context: Context) {
private const val PROGRAM = "PROGRAM"
private const val BRANCH = "BRANCH"
private const val COURSE_NESTED_LIST_ENABLED = "COURSE_NESTED_LIST_ENABLED"
private const val COURSE_BANNER_ENABLED = "COURSE_BANNER_ENABLED"
private const val COURSE_TOP_TAB_BAR_ENABLED = "COURSE_TOP_TAB_BAR_ENABLED"
private const val COURSE_UNIT_PROGRESS_ENABLED = "COURSE_UNIT_PROGRESS_ENABLED"
private const val PLATFORM_NAME = "PLATFORM_NAME"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.openedx.core.module.download

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
Expand Down Expand Up @@ -41,8 +40,7 @@ abstract class BaseDownloadViewModel(
private val _downloadingModelsFlow = MutableSharedFlow<List<DownloadModel>>()
protected val downloadingModelsFlow = _downloadingModelsFlow.asSharedFlow()

override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
init {
viewModelScope.launch {
downloadDao.readAllData().map { list -> list.map { it.mapToDomain() } }
.collect { downloadModels ->
Expand Down Expand Up @@ -246,10 +244,7 @@ abstract class BaseDownloadViewModel(
logEvent(
CoreAnalyticsEvent.VIDEO_BULK_DOWNLOAD_TOGGLE,
buildMap {
put(
CoreAnalyticsKey.ACTION.key,
if (toggle) CoreAnalyticsKey.TRUE.key else CoreAnalyticsKey.FALSE.key
)
put(CoreAnalyticsKey.ACTION.key, toggle)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ enum class CoreAnalyticsKey(val key: String) {
OLD_VALUE("old_value"),
COURSE_ID("course_id"),
BLOCK_ID("block_id"),
TRUE("true"),
FALSE("false"),
NUMBER_OF_VIDEOS("number_of_videos"),
}

Expand Down
Loading

0 comments on commit 4d36310

Please sign in to comment.