Skip to content

Commit

Permalink
Merge pull request #230 from openedx/develop
Browse files Browse the repository at this point in the history
Develop to main v1.4
  • Loading branch information
volodymyr-chekyrta authored Feb 12, 2024
2 parents c736918 + e6876be commit 8c57627
Show file tree
Hide file tree
Showing 356 changed files with 18,791 additions and 4,594 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ jobs:
uses: gradle/[email protected]
with:
cache-read-only: ${{ github.ref != 'refs/heads/develop' }}

- name: Generate mock files
run: ./gradlew generateMockedRawFile
- name: Run unit tests
run: ./gradlew testProdReleaseUnitTest $CI_GRADLE_ARG_PROPERTIES

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
.cxx
local.properties
/.idea/
*.log
*.log
/config_settings.yaml
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@ Modern vision of the mobile application for the Open EdX platform from Raccoon G
[Documentation](Documentation/Documentation.md)

## Building

1. Check out the source code:

git clone https://github.com/raccoongang/educationx-app-ios.git
git clone https://github.com/openedx/openedx-app-android.git

2. Open Android Studio and choose Open an Existing Android Studio Project.

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

4. Configure the [config.yaml](config.yaml) with URLs and OAuth credentials for your Open edX instance.
4. Configure the [config.yaml](default_config/dev/config.yaml) with URLs and OAuth credentials for your Open edX instance.

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

6. Click the **Run** button.

## API plugin

This project uses custom APIs to improve performance and reduce the number of requests to the server.

You can find the plugin with the API and installation guide [here](https://github.com/raccoongang/mobile-api-extensions).

## License

The code in this repository is licensed under the Apache-2.0 license unless otherwise noted.

Please see [LICENSE](https://github.com/raccoongang/educationx-app-android/blob/main/LICENSE) file for details.
Please see [LICENSE](https://github.com/openedx/openedx-app-android/blob/main/LICENSE) file for details.
27 changes: 24 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,22 @@ plugins {
id 'org.jetbrains.kotlin.android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
id "com.google.firebase.crashlytics"
id 'com.google.firebase.crashlytics'
}

def config = configHelper.fetchConfig()
def appId = config.getOrDefault("APPLICATION_ID", "org.openedx.app")
def platformName = config.getOrDefault("PLATFORM_NAME", "OpenEdx").toLowerCase()

android {
compileSdk 34

defaultConfig {
applicationId "org.openedx.app"
applicationId appId
minSdk 24
targetSdk 34
versionCode 1
versionName "1.0"
versionName "1.0.0"

resourceConfigurations += ["en", "uk"]

Expand All @@ -36,10 +40,26 @@ android {
}
}

sourceSets {
prod {
res.srcDirs = ["src/$platformName/res"]
}
develop {
res.srcDirs = ["src/$platformName/res"]
}
stage {
res.srcDirs = ["src/$platformName/res"]
}
}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

firebaseCrashlytics {
mappingFileUploadEnabled false
}
}
}
compileOptions {
Expand Down Expand Up @@ -80,6 +100,7 @@ dependencies {
implementation project(path: ':discovery')
implementation project(path: ':profile')
implementation project(path: ':discussion')
implementation project(path: ':whatsnew')

kapt "androidx.room:room-compiler:$room_version"

Expand Down
18 changes: 17 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
-keep class org.openedx.*.data.model.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
Expand All @@ -93,3 +93,19 @@
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

##---------------End: proguard configuration for Gson ----------

-keepclassmembers class * extends java.lang.Enum {
<fields>;
public static **[] values();
public static ** valueOf(java.lang.String);
}

-dontwarn org.bouncycastle.jsse.BCSSLParameters
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
-dontwarn org.conscrypt.Conscrypt$Version
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
20 changes: 16 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

<queries>
<intent>
Expand All @@ -15,19 +16,20 @@
android:name=".OpenEdXApp"
android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:localeConfig="@xml/locales_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:screenOrientation="sensor"
android:supportsRtl="true"
android:theme="@style/Theme.App.Starting"
tools:targetApi="tiramisu">
<activity
android:name=".AppActivity"
android:exported="true"
android:fitsSystemWindows="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.App.Starting"
android:windowSoftInputMode="adjustPan">
<intent-filter>
Expand All @@ -47,10 +49,20 @@
android:resource="@xml/file_provider_paths" />
</provider>

<provider android:authorities="${applicationId}.firebaseinitprovider"
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="${applicationId}.firebaseinitprovider"
android:exported="false"
tools:node="remove"/>
tools:node="remove" />

<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="androidx.media3.cast.DefaultCastOptionsProvider" />

<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />
</application>

</manifest>
</manifest>
57 changes: 51 additions & 6 deletions app/src/main/java/org/openedx/app/AnalyticsManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,45 @@ package org.openedx.app
import android.content.Context
import android.os.Bundle
import androidx.core.os.bundleOf
import com.google.firebase.analytics.FirebaseAnalytics
import org.openedx.app.analytics.Analytics
import org.openedx.app.analytics.FirebaseAnalytics
import org.openedx.auth.presentation.AuthAnalytics
import org.openedx.core.config.Config
import org.openedx.course.presentation.CourseAnalytics
import org.openedx.dashboard.presentation.DashboardAnalytics
import org.openedx.dashboard.presentation.dashboard.DashboardAnalytics
import org.openedx.discovery.presentation.DiscoveryAnalytics
import org.openedx.discussion.presentation.DiscussionAnalytics
import org.openedx.profile.presentation.ProfileAnalytics

class AnalyticsManager(context: Context) : DashboardAnalytics, AuthAnalytics, AppAnalytics,
class AnalyticsManager(
context: Context,
config: Config,
) : DashboardAnalytics, AuthAnalytics, AppAnalytics,
DiscoveryAnalytics, ProfileAnalytics, CourseAnalytics, DiscussionAnalytics {

private val analytics = FirebaseAnalytics.getInstance(context)
private val services: ArrayList<Analytics> = arrayListOf()

init {
// Initialise all the analytics libraries here
if (config.getFirebaseConfig().projectId.isNotEmpty()) {
addAnalyticsTracker(FirebaseAnalytics(context = context))
}
}

private fun addAnalyticsTracker(analytic: Analytics) {
services.add(analytic)
}

private fun logEvent(event: Event, params: Bundle = bundleOf()) {
analytics.logEvent(event.eventName, params)
services.forEach { analytics ->
analytics.logEvent(event.eventName, params)
}
}

private fun setUserId(userId: Long) {
analytics.setUserId(userId.toString())
services.forEach { analytics ->
analytics.logUserId(userId)
}
}

override fun dashboardCourseClickedEvent(courseId: String, courseName: String) {
Expand Down Expand Up @@ -143,10 +163,22 @@ class AnalyticsManager(context: Context) : DashboardAnalytics, AuthAnalytics, Ap
logEvent(Event.PRIVACY_POLICY_CLICKED)
}

override fun termsOfUseClickedEvent() {
logEvent(Event.TERMS_OF_USE_CLICKED)
}

override fun cookiePolicyClickedEvent() {
logEvent(Event.COOKIE_POLICY_CLICKED)
}

override fun dataSellClickedEvent() {
logEvent(Event.DATE_SELL_CLICKED)
}

override fun faqClickedEvent() {
logEvent(Event.FAQ_CLICKED)
}

override fun emailSupportClickedEvent() {
logEvent(Event.EMAIL_SUPPORT_CLICKED)
}
Expand Down Expand Up @@ -320,6 +352,15 @@ class AnalyticsManager(context: Context) : DashboardAnalytics, AuthAnalytics, Ap
)
}

override fun datesTabClickedEvent(courseId: String, courseName: String) {
logEvent(
Event.DATES_TAB_CLICKED, bundleOf(
Key.COURSE_ID.keyName to courseId,
Key.COURSE_NAME.keyName to courseName
)
)
}

override fun handoutsTabClickedEvent(courseId: String, courseName: String) {
logEvent(
Event.HANDOUTS_TAB_CLICKED, bundleOf(
Expand Down Expand Up @@ -386,7 +427,10 @@ private enum class Event(val eventName: String) {
PROFILE_DELETE_ACCOUNT_CLICKED("Profile_Delete_Account_Clicked"),
PROFILE_VIDEO_SETTINGS_CLICKED("Profile_Video_settings_Clicked"),
PRIVACY_POLICY_CLICKED("Privacy_Policy_Clicked"),
TERMS_OF_USE_CLICKED("Terms_Of_Use_Clicked"),
COOKIE_POLICY_CLICKED("Cookie_Policy_Clicked"),
DATE_SELL_CLICKED("Data_Sell_Clicked"),
FAQ_CLICKED("FAQ_Clicked"),
EMAIL_SUPPORT_CLICKED("Email_Support_Clicked"),
COURSE_ENROLL_CLICKED("Course_Enroll_Clicked"),
COURSE_ENROLL_SUCCESS("Course_Enroll_Success"),
Expand All @@ -402,6 +446,7 @@ private enum class Event(val eventName: String) {
COURSE_TAB_CLICKED("Course_Outline_Course_tab_Clicked"),
VIDEO_TAB_CLICKED("Course_Outline_Videos_tab_Clicked"),
DISCUSSION_TAB_CLICKED("Course_Outline_Discussion_tab_Clicked"),
DATES_TAB_CLICKED("Course_Outline_Dates_tab_Clicked"),
HANDOUTS_TAB_CLICKED("Course_Outline_Handouts_tab_Clicked"),
DISCUSSION_ALL_POSTS_CLICKED("Discussion_All_Posts_Clicked"),
DISCUSSION_FOLLOWING_CLICKED("Discussion_Following_Clicked"),
Expand Down
Loading

0 comments on commit 8c57627

Please sign in to comment.