Skip to content

Commit

Permalink
feat: [FC-0047] Calendar synchronization (openedx#330)
Browse files Browse the repository at this point in the history
* feat: Created calendar setting screen

* feat: CalendarAccessDialog

* feat: NewCalendarDialog

* fix: Fixes according to PR feedback

* feat: Create calendar

* fix: Fixes according to PR feedback

* feat: Creating calendar

* feat: Creating a calendar, tryToSyncCalendar logic, CalendarUIState, start CalendarSyncService

* feat: CalendarSettingsView

* feat: Removed calendar logic from course home, edit calendar dialog

* feat: Add events to calendar

* fix: Save CourseCalendarEventEntity to DB

* feat: CoursesToSyncFragment UI

* feat: All Calendar sync logic

* feat: DisableCalendarSyncDialogFragment

* refactor: Calendar repository refactoring, minor UI fixes

* refactor: Calendar Manager refactor

* fix: Fixes according to code review feedback

* feat: Save calendar on logout, remove on different user login

* feat: Notification for CalendarSyncWorker, junit test fix

* feat: removeUnenrolledCourseEvents

* feat: Calendar sync state on CourseDatesScreen

* fix: Crash CoursesToSyncFragment in offline mode

* fix: Fixes according to QA feedback

* fix: Calendar Permission crash

* fix: Fixes according to PR feedback
  • Loading branch information
PavloNetrebchuk authored Jul 18, 2024
1 parent 6efdd76 commit 559c7e4
Show file tree
Hide file tree
Showing 88 changed files with 2,826 additions and 882 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>

</application>

</manifest>
4 changes: 4 additions & 0 deletions app/src/main/java/org/openedx/app/AppActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.openedx.core.presentation.global.WindowSizeHolder
import org.openedx.core.ui.WindowSize
import org.openedx.core.ui.WindowType
import org.openedx.core.utils.Logger
import org.openedx.core.worker.CalendarSyncScheduler
import org.openedx.profile.presentation.ProfileRouter
import org.openedx.whatsnew.WhatsNewManager
import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment
Expand All @@ -50,6 +51,7 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder {
private val whatsNewManager by inject<WhatsNewManager>()
private val corePreferencesManager by inject<CorePreferences>()
private val profileRouter by inject<ProfileRouter>()
private val calendarSyncScheduler by inject<CalendarSyncScheduler>()

private val branchLogger = Logger(BRANCH_TAG)

Expand Down Expand Up @@ -160,6 +162,8 @@ class AppActivity : AppCompatActivity(), InsetHolder, WindowSizeHolder {
viewModel.logoutUser.observe(this) {
profileRouter.restartApp(supportFragmentManager, viewModel.isLogistrationEnabled)
}

calendarSyncScheduler.scheduleDailySync()
}

override fun onStart() {
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/java/org/openedx/app/AppRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.openedx.auth.presentation.logistration.LogistrationFragment
import org.openedx.auth.presentation.restore.RestorePasswordFragment
import org.openedx.auth.presentation.signin.SignInFragment
import org.openedx.auth.presentation.signup.SignUpFragment
import org.openedx.core.CalendarRouter
import org.openedx.core.FragmentViewType
import org.openedx.core.presentation.course.CourseViewMode
import org.openedx.core.presentation.global.app_upgrade.AppUpgradeRouter
Expand Down Expand Up @@ -46,6 +47,7 @@ import org.openedx.profile.domain.model.Account
import org.openedx.profile.presentation.ProfileRouter
import org.openedx.profile.presentation.anothersaccount.AnothersProfileFragment
import org.openedx.profile.presentation.calendar.CalendarFragment
import org.openedx.profile.presentation.calendar.CoursesToSyncFragment
import org.openedx.profile.presentation.delete.DeleteProfileFragment
import org.openedx.profile.presentation.edit.EditProfileFragment
import org.openedx.profile.presentation.manageaccount.ManageAccountFragment
Expand All @@ -56,7 +58,7 @@ import org.openedx.whatsnew.WhatsNewRouter
import org.openedx.whatsnew.presentation.whatsnew.WhatsNewFragment

class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, DiscussionRouter,
ProfileRouter, AppUpgradeRouter, WhatsNewRouter {
ProfileRouter, AppUpgradeRouter, WhatsNewRouter, CalendarRouter {

//region AuthRouter
override fun navigateToMain(
Expand Down Expand Up @@ -411,6 +413,10 @@ class AppRouter : AuthRouter, DiscoveryRouter, DashboardRouter, CourseRouter, Di
override fun navigateToCalendarSettings(fm: FragmentManager) {
replaceFragmentWithBackStack(fm, CalendarFragment())
}

override fun navigateToCoursesToSync(fm: FragmentManager) {
replaceFragmentWithBackStack(fm, CoursesToSyncFragment())
}
//endregion

fun getVisibleFragment(fm: FragmentManager): Fragment? {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/org/openedx/app/AppViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class AppViewModel(
if (System.currentTimeMillis() - logoutHandledAt > 5000) {
if (event.isForced) {
logoutHandledAt = System.currentTimeMillis()
preferencesManager.clear()
preferencesManager.clearCorePreferences()
withContext(dispatcher) {
room.clearAllTables()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ import android.content.Context
import com.google.gson.Gson
import org.openedx.app.BuildConfig
import org.openedx.core.data.model.User
import org.openedx.core.data.storage.CalendarPreferences
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.data.storage.InAppReviewPreferences
import org.openedx.core.domain.model.AppConfig
import org.openedx.core.domain.model.VideoQuality
import org.openedx.core.domain.model.VideoSettings
import org.openedx.core.extension.replaceSpace
import org.openedx.core.system.CalendarManager
import org.openedx.course.data.storage.CoursePreferences
import org.openedx.profile.data.model.Account
import org.openedx.profile.data.storage.ProfilePreferences
import org.openedx.whatsnew.data.storage.WhatsNewPreferences

class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences,
WhatsNewPreferences, InAppReviewPreferences, CoursePreferences {
WhatsNewPreferences, InAppReviewPreferences, CoursePreferences, CalendarPreferences {

private val sharedPreferences =
context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE)
Expand All @@ -37,7 +39,7 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}.apply()
}

private fun getLong(key: String): Long = sharedPreferences.getLong(key, 0L)
private fun getLong(key: String, defValue: Long = 0): Long = sharedPreferences.getLong(key, defValue)

private fun saveBoolean(key: String, value: Boolean) {
sharedPreferences.edit().apply {
Expand All @@ -49,7 +51,7 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
return sharedPreferences.getBoolean(key, defValue)
}

override fun clear() {
override fun clearCorePreferences() {
sharedPreferences.edit().apply {
remove(ACCESS_TOKEN)
remove(REFRESH_TOKEN)
Expand All @@ -59,6 +61,14 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}.apply()
}

override fun clearCalendarPreferences() {
sharedPreferences.edit().apply {
remove(CALENDAR_ID)
remove(IS_CALENDAR_SYNC_ENABLED)
remove(HIDE_INACTIVE_COURSES)
}.apply()
}

override var accessToken: String
set(value) {
saveString(ACCESS_TOKEN, value)
Expand All @@ -83,6 +93,12 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}
get() = getLong(EXPIRES_IN)

override var calendarId: Long
set(value) {
saveLong(CALENDAR_ID, value)
}
get() = getLong(CALENDAR_ID, CalendarManager.CALENDAR_DOES_NOT_EXIST)

override var user: User?
set(value) {
val userJson = Gson().toJson(value)
Expand Down Expand Up @@ -165,6 +181,24 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}
get() = getBoolean(RESET_APP_DIRECTORY, true)

override var isCalendarSyncEnabled: Boolean
set(value) {
saveBoolean(IS_CALENDAR_SYNC_ENABLED, value)
}
get() = getBoolean(IS_CALENDAR_SYNC_ENABLED, true)

override var calendarUser: String
set(value) {
saveString(CALENDAR_USER, value)
}
get() = getString(CALENDAR_USER)

override var isHideInactiveCourses: Boolean
set(value) {
saveBoolean(HIDE_INACTIVE_COURSES, value)
}
get() = getBoolean(HIDE_INACTIVE_COURSES, true)

override fun setCalendarSyncEventsDialogShown(courseName: String) {
saveBoolean(courseName.replaceSpace("_"), true)
}
Expand All @@ -186,6 +220,10 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
private const val VIDEO_SETTINGS_STREAMING_QUALITY = "video_settings_streaming_quality"
private const val VIDEO_SETTINGS_DOWNLOAD_QUALITY = "video_settings_download_quality"
private const val APP_CONFIG = "app_config"
private const val CALENDAR_ID = "CALENDAR_ID"
private const val RESET_APP_DIRECTORY = "reset_app_directory"
private const val IS_CALENDAR_SYNC_ENABLED = "IS_CALENDAR_SYNC_ENABLED"
private const val HIDE_INACTIVE_COURSES = "HIDE_INACTIVE_COURSES"
private const val CALENDAR_USER = "CALENDAR_USER"
}
}
24 changes: 21 additions & 3 deletions app/src/main/java/org/openedx/app/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.openedx.app.AnalyticsManager
import org.openedx.app.AppAnalytics
import org.openedx.app.deeplink.DeepLinkRouter
import org.openedx.app.AppRouter
import org.openedx.app.BuildConfig
import org.openedx.app.data.storage.PreferencesManager
import org.openedx.app.deeplink.DeepLinkRouter
import org.openedx.app.room.AppDatabase
import org.openedx.app.room.DATABASE_NAME
import org.openedx.app.room.DatabaseManager
import org.openedx.auth.presentation.AgreementProvider
import org.openedx.auth.presentation.AuthAnalytics
import org.openedx.auth.presentation.AuthRouter
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.CalendarRouter
import org.openedx.core.ImageProcessor
import org.openedx.core.config.Config
import org.openedx.core.data.model.CourseEnrollments
import org.openedx.core.data.storage.CalendarPreferences
import org.openedx.core.data.storage.CorePreferences
import org.openedx.core.data.storage.InAppReviewPreferences
import org.openedx.core.module.DownloadWorkerController
Expand All @@ -48,7 +51,9 @@ import org.openedx.core.system.notifier.DiscoveryNotifier
import org.openedx.core.system.notifier.DownloadNotifier
import org.openedx.core.system.notifier.VideoNotifier
import org.openedx.core.system.notifier.app.AppNotifier
import org.openedx.core.system.notifier.calendar.CalendarNotifier
import org.openedx.core.utils.FileUtil
import org.openedx.core.worker.CalendarSyncScheduler
import org.openedx.course.data.storage.CoursePreferences
import org.openedx.course.presentation.CourseAnalytics
import org.openedx.course.presentation.CourseRouter
Expand All @@ -62,11 +67,12 @@ import org.openedx.discussion.system.notifier.DiscussionNotifier
import org.openedx.profile.data.storage.ProfilePreferences
import org.openedx.profile.presentation.ProfileAnalytics
import org.openedx.profile.presentation.ProfileRouter
import org.openedx.profile.system.notifier.ProfileNotifier
import org.openedx.profile.system.notifier.profile.ProfileNotifier
import org.openedx.whatsnew.WhatsNewManager
import org.openedx.whatsnew.WhatsNewRouter
import org.openedx.whatsnew.data.storage.WhatsNewPreferences
import org.openedx.whatsnew.presentation.WhatsNewAnalytics
import org.openedx.core.DatabaseManager as IDatabaseManager

val appModule = module {

Expand All @@ -77,11 +83,14 @@ val appModule = module {
single<WhatsNewPreferences> { get<PreferencesManager>() }
single<InAppReviewPreferences> { get<PreferencesManager>() }
single<CoursePreferences> { get<PreferencesManager>() }
single<CalendarPreferences> { get<PreferencesManager>() }

single { ResourceManager(get()) }
single { AppCookieManager(get(), get()) }
single { ReviewManagerFactory.create(get()) }
single { CalendarManager(get(), get(), get()) }
single { CalendarManager(get(), get()) }
single { DatabaseManager(get(), get(), get(), get()) }
single<IDatabaseManager> { get<DatabaseManager>() }

single { ImageProcessor(get()) }

Expand All @@ -98,6 +107,7 @@ val appModule = module {
single { DownloadNotifier() }
single { VideoNotifier() }
single { DiscoveryNotifier() }
single { CalendarNotifier() }

single { AppRouter() }
single<AuthRouter> { get<AppRouter>() }
Expand All @@ -109,6 +119,7 @@ val appModule = module {
single<WhatsNewRouter> { get<AppRouter>() }
single<AppUpgradeRouter> { get<AppRouter>() }
single { DeepLinkRouter(get(), get(), get(), get(), get(), get()) }
single<CalendarRouter> { get<AppRouter>() }

single { NetworkConnection(get()) }

Expand Down Expand Up @@ -150,6 +161,11 @@ val appModule = module {
room.downloadDao()
}

single {
val room = get<AppDatabase>()
room.calendarDao()
}

single {
FileDownloader()
}
Expand Down Expand Up @@ -184,4 +200,6 @@ val appModule = module {
factory { OAuthHelper(get(), get(), get()) }

factory { FileUtil(get()) }

single { CalendarSyncScheduler(get()) }
}
28 changes: 21 additions & 7 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import org.openedx.auth.presentation.restore.RestorePasswordViewModel
import org.openedx.auth.presentation.signin.SignInViewModel
import org.openedx.auth.presentation.signup.SignUpViewModel
import org.openedx.core.Validator
import org.openedx.core.domain.interactor.CalendarInteractor
import org.openedx.core.presentation.dialog.selectorbottomsheet.SelectDialogViewModel
import org.openedx.core.presentation.settings.video.VideoQualityViewModel
import org.openedx.core.repository.CalendarRepository
import org.openedx.core.ui.WindowSize
import org.openedx.course.data.repository.CourseRepository
import org.openedx.course.domain.interactor.CourseInteractor
Expand Down Expand Up @@ -58,6 +60,9 @@ import org.openedx.profile.domain.interactor.ProfileInteractor
import org.openedx.profile.domain.model.Account
import org.openedx.profile.presentation.anothersaccount.AnothersProfileViewModel
import org.openedx.profile.presentation.calendar.CalendarViewModel
import org.openedx.profile.presentation.calendar.CoursesToSyncViewModel
import org.openedx.profile.presentation.calendar.DisableCalendarSyncDialogViewModel
import org.openedx.profile.presentation.calendar.NewCalendarDialogViewModel
import org.openedx.profile.presentation.delete.DeleteProfileViewModel
import org.openedx.profile.presentation.edit.EditProfileViewModel
import org.openedx.profile.presentation.manageaccount.ManageAccountViewModel
Expand Down Expand Up @@ -109,6 +114,8 @@ val screenModule = module {
get(),
get(),
get(),
get(),
get(),
courseId,
infoType,
)
Expand Down Expand Up @@ -190,14 +197,21 @@ val screenModule = module {
get(),
get(),
get(),
get()
get(),
get(),
)
}
viewModel { ManageAccountViewModel(get(), get(), get(), get(), get()) }
viewModel { CalendarViewModel(get()) }
viewModel { CalendarViewModel(get(), get(), get(), get(), get(), get(), get()) }
viewModel { CoursesToSyncViewModel(get(), get(), get(), get()) }
viewModel { NewCalendarDialogViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { DisableCalendarSyncDialogViewModel(get(), get(), get(), get()) }
factory { CalendarRepository(get(), get(), get()) }
factory { CalendarInteractor(get()) }

single { CourseRepository(get(), get(), get(), get(), get()) }
factory { CourseInteractor(get()) }

viewModel { (pathId: String, infoType: String) ->
CourseInfoViewModel(
pathId,
Expand All @@ -221,7 +235,8 @@ val screenModule = module {
get(),
get(),
get(),
get()
get(),
get(),
)
}
viewModel { (courseId: String, courseTitle: String, enrollmentMode: String, resumeBlockId: String) ->
Expand All @@ -239,7 +254,6 @@ val screenModule = module {
get(),
get(),
get(),
get(),
get()
)
}
Expand Down Expand Up @@ -327,10 +341,9 @@ val screenModule = module {
get(),
)
}
viewModel { (courseId: String, courseTitle: String, enrollmentMode: String) ->
viewModel { (courseId: String, enrollmentMode: String) ->
CourseDatesViewModel(
courseId,
courseTitle,
enrollmentMode,
get(),
get(),
Expand All @@ -339,7 +352,8 @@ val screenModule = module {
get(),
get(),
get(),
get()
get(),
get(),
)
}
viewModel { (courseId: String, handoutsType: String) ->
Expand Down
Loading

0 comments on commit 559c7e4

Please sign in to comment.