From c8b91a49616a14f627805797dd0f40174dc523f6 Mon Sep 17 00:00:00 2001 From: AKSHAT KAMBOJ Date: Thu, 2 Mar 2023 12:01:18 +0530 Subject: [PATCH 01/35] added snackbar --- .../profile/ProfileEditFragmentPresenter.kt | 43 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index 914bf3bade4..00421e867c1 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import com.google.android.material.snackbar.Snackbar import org.oppia.android.R import org.oppia.android.app.administratorcontrols.AdministratorControlsActivity import org.oppia.android.app.administratorcontrols.ProfileEditDeletionDialogListener @@ -132,22 +133,34 @@ class ProfileEditFragmentPresenter @Inject constructor( profileManagementController .deleteProfile(ProfileId.newBuilder().setInternalId(internalProfileId).build()).toLiveData() .observe( - fragment, - Observer { - if (it is AsyncResult.Success) { - if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { - val intent = - Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } else { - val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } - } + fragment + ) { + if (it is AsyncResult.Success) { + val snack = Snackbar + .make( + fragment.requireView(), + R.string.profile_edit_delete_success, + Snackbar.LENGTH_LONG + ) + .setAction(R.string.log_out_dialog_okay_button) { } + .addCallback(object : Snackbar.Callback() { + override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { + if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { + val intent = + Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } else { + val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } + } + }) + .setActionTextColor(fragment.resources.getColor(R.color.color_def_bright_turquoise)) + snack.show() } - ) + } } /** This loads the dialog whenever requested by the listener in [AdministratorControlsActivity]. */ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 073d27dcaf3..e8223f8a563 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -584,4 +584,5 @@ Administrator Controls Fragment Test Activity Continue Studying Go to the bottom of the screen for a hint. + Profile Has Been Successfully Deleted. From 748d8a1674ff975d593b88277cff2bd223043863 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Sat, 11 Mar 2023 14:33:11 +0530 Subject: [PATCH 02/35] changed the timing to short --- .../profile/ProfileEditFragmentPresenter.kt | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index dc93080f9a8..fba6d5acc14 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -149,34 +149,35 @@ class ProfileEditFragmentPresenter @Inject constructor( profileManagementController .deleteProfile(ProfileId.newBuilder().setInternalId(internalProfileId).build()).toLiveData() .observe( - fragment - ) { - if (it is AsyncResult.Success) { - val snack = Snackbar - .make( - fragment.requireView(), - R.string.profile_edit_delete_success, - Snackbar.LENGTH_LONG - ) - .setAction(R.string.log_out_dialog_okay_button) { } - .addCallback(object : Snackbar.Callback() { - override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { - if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { - val intent = - Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } else { - val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) + fragment, + Observer { + if (it is AsyncResult.Success) { + val profileDeletionSnackbar = Snackbar + .make( + fragment.requireView(), + R.string.profile_edit_delete_success, + Snackbar.LENGTH_SHORT + ) + .setAction(R.string.log_out_dialog_okay_button) { } + .addCallback(object : Snackbar.Callback() { + override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { + if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { + val intent = + Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } else { + val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } } - } - }) - .setActionTextColor(fragment.resources.getColor(R.color.color_def_bright_turquoise)) - snack.show() + }) + .setActionTextColor(fragment.resources.getColor(R.color.color_def_bright_turquoise)) + profileDeletionSnackbar.show() + } } - } + ) } /** This loads the dialog whenever requested by the listener in [AdministratorControlsActivity]. */ From a5a9a56b55b995523ec6031b416c92eabaddbba3 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 4 Apr 2023 23:33:23 +0530 Subject: [PATCH 03/35] added comments --- .../settings/profile/SnackbarController.kt | 42 ++++++++++ .../app/settings/profile/SnackbarManager.kt | 76 +++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt create mode 100644 app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt new file mode 100644 index 00000000000..bfbcd7dee0d --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -0,0 +1,42 @@ +package org.oppia.android.app.settings.profile + +import androidx.annotation.StringRes +import javax.inject.Inject +import javax.inject.Singleton +import org.oppia.android.R +import org.oppia.android.util.data.DataProvider +import org.oppia.android.util.data.DataProviders + +@Singleton +abstract class SnackbarController @Inject constructor() { + // The class should have a queue of snackbars. + + fun getCurrentSnackbar(): DataProvider { + // Return a data provider that will provide the current snackbar request. + // not getting how to return a data provider + + } + + fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { + // Enqueue the snackbar request. + val list = mutableListOf() + list.add(request) + } + + fun dismissCurrentSnackbar() { + //dismiss the current snackbar + + } + + sealed class SnackbarRequest { + data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration): SnackbarRequest() + + object ShowNothing: SnackbarRequest() + } + + // Abstraction for Snackbar's length constants. + enum class SnackbarDuration { + SHORT, + LONG + } +} \ No newline at end of file diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt new file mode 100644 index 00000000000..513c52c8f8d --- /dev/null +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -0,0 +1,76 @@ +package org.oppia.android.app.settings.profile + +import android.util.Log +import android.view.View +import androidx.annotation.StringRes +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.snackbar.Snackbar +import javax.inject.Inject +import kotlinx.android.synthetic.main.profile_edit_fragment.* +import org.oppia.android.util.data.AsyncResult +import org.oppia.android.util.data.DataProviders.Companion.toLiveData + +class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { + // Use SnackbarController for displaying the current snackbar, hiding it after the snackbar hides, or showing a new one. + + fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration) { + // Enqueue snackbar using SnackbarController... + snackbarController.enqueueSnackbar( + SnackbarController.SnackbarRequest.ShowSnackbar( + messageStringId, + duration + ) + ) + } + + fun enableShowingSnackbars(activity: AppCompatActivity) { + // Called in an activity's onCreate to start listening for snackbar state. + snackbarController.getCurrentSnackbar().toLiveData().observe(activity) { result -> + when (result) { + is AsyncResult.Success -> when (val request = result.value) { + is SnackbarController.SnackbarRequest.ShowSnackbar -> showSnackbar(activity.view, request) + SnackbarController.SnackbarRequest.ShowNothing -> {} // Do nothing. + } + // Other cases... + else -> { + + } + } + } + } + + private fun showSnackbar( + activityView: View?, + showRequest: SnackbarController.SnackbarRequest.ShowSnackbar + ) { + + val duration = when (showRequest.duration) { + SnackbarController.SnackbarDuration.SHORT -> Snackbar.LENGTH_SHORT + SnackbarController.SnackbarDuration.LONG -> Snackbar.LENGTH_LONG + } + + if (activityView == null) { + // ...log an error if activityView is null and ignore the snackbar request (can't be shown--no activity UI). + Log.e("SnackbarManager", "can't be shown--no activity UI") + } + // ...compute length based on showRequest.duration and messageString based on showRequest.messageStringId -- the latter should be done using appResourceHandler (so that the string is in the correct language). + else { + Snackbar.make(activityView, showRequest.messageStringId, duration) + .addCallback(object : Snackbar.Callback() { + override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { + super.onDismissed(transientBottomBar, event) + // ...dismiss the snackbar when it's dismissed. + snackbarController.dismissCurrentSnackbar() + } + }) + .show() + // ...show the snackbar & add a callback for when it dismisses--at that point SnackbarController.dismissCurrentSnackbar() should be called. + } + } + + // Abstract domain layer. +// enum class SnackbarDuration { +// SHORT, +// LONG +// } +} \ No newline at end of file From 44e9e3b4f4037fc37c10929ba513af5eac536f07 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 4 Apr 2023 23:38:24 +0530 Subject: [PATCH 04/35] added comments --- .../app/settings/profile/SnackbarController.kt | 11 +++++------ .../android/app/settings/profile/SnackbarManager.kt | 6 ++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt index bfbcd7dee0d..297a6a8f79f 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -3,9 +3,7 @@ package org.oppia.android.app.settings.profile import androidx.annotation.StringRes import javax.inject.Inject import javax.inject.Singleton -import org.oppia.android.R import org.oppia.android.util.data.DataProvider -import org.oppia.android.util.data.DataProviders @Singleton abstract class SnackbarController @Inject constructor() { @@ -24,14 +22,15 @@ abstract class SnackbarController @Inject constructor() { } fun dismissCurrentSnackbar() { - //dismiss the current snackbar + //dismiss the current snackbar } sealed class SnackbarRequest { - data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration): SnackbarRequest() + data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : + SnackbarRequest() - object ShowNothing: SnackbarRequest() + object ShowNothing : SnackbarRequest() } // Abstraction for Snackbar's length constants. @@ -39,4 +38,4 @@ abstract class SnackbarController @Inject constructor() { SHORT, LONG } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 513c52c8f8d..a5b5b1771b5 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -32,9 +32,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb SnackbarController.SnackbarRequest.ShowNothing -> {} // Do nothing. } // Other cases... - else -> { - - } + else -> {} } } } @@ -73,4 +71,4 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb // SHORT, // LONG // } -} \ No newline at end of file +} From 80fbab2606461014a694464b8f28c2fbed929613 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 4 Apr 2023 23:41:20 +0530 Subject: [PATCH 05/35] added comments --- .../android/app/settings/profile/SnackbarController.kt | 6 ++---- .../oppia/android/app/settings/profile/SnackbarManager.kt | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt index 297a6a8f79f..551949c1d0b 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -1,9 +1,9 @@ package org.oppia.android.app.settings.profile import androidx.annotation.StringRes +import org.oppia.android.util.data.DataProvider import javax.inject.Inject import javax.inject.Singleton -import org.oppia.android.util.data.DataProvider @Singleton abstract class SnackbarController @Inject constructor() { @@ -12,7 +12,6 @@ abstract class SnackbarController @Inject constructor() { fun getCurrentSnackbar(): DataProvider { // Return a data provider that will provide the current snackbar request. // not getting how to return a data provider - } fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { @@ -22,8 +21,7 @@ abstract class SnackbarController @Inject constructor() { } fun dismissCurrentSnackbar() { - //dismiss the current snackbar - + // dismiss the current snackbar } sealed class SnackbarRequest { diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index a5b5b1771b5..561f57c5ad9 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -5,10 +5,10 @@ import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar -import javax.inject.Inject -import kotlinx.android.synthetic.main.profile_edit_fragment.* import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData +import javax.inject.Inject +import kotlinx.android.synthetic.main.profile_edit_fragment.* class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { // Use SnackbarController for displaying the current snackbar, hiding it after the snackbar hides, or showing a new one. From 84ca7c6afdadb1c18ba6ee4d08a3aff29e8c353d Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 4 Apr 2023 23:43:10 +0530 Subject: [PATCH 06/35] added comments --- .../org/oppia/android/app/settings/profile/SnackbarManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 561f57c5ad9..be9b34440e8 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -5,10 +5,10 @@ import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar +import kotlinx.android.synthetic.main.profile_edit_fragment.* import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject -import kotlinx.android.synthetic.main.profile_edit_fragment.* class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { // Use SnackbarController for displaying the current snackbar, hiding it after the snackbar hides, or showing a new one. From 824fc2daf4d39e25c25813090e367330b045cbaa Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 25 Apr 2023 23:40:30 +0530 Subject: [PATCH 07/35] added snackbar --- .../AdministratorControlsActivity.kt | 4 ++ .../profile/ProfileEditFragmentPresenter.kt | 39 +++++++------------ .../settings/profile/ProfileListActivity.kt | 3 ++ .../settings/profile/SnackbarController.kt | 25 ++++++------ .../app/settings/profile/SnackbarManager.kt | 24 ++++-------- app/src/main/res/values/strings.xml | 2 +- 6 files changed, 44 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt b/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt index b0301245da7..07e5d2a1f4b 100644 --- a/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt +++ b/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt @@ -17,6 +17,7 @@ import org.oppia.android.app.translation.AppLanguageResourceHandler import org.oppia.android.util.extensions.getStringFromBundle import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName import javax.inject.Inject +import org.oppia.android.app.settings.profile.SnackbarManager /** Argument key for of title for selected controls in [AdministratorControlsActivity]. */ const val SELECTED_CONTROLS_TITLE_SAVED_KEY = @@ -64,6 +65,8 @@ class AdministratorControlsActivity : lateinit var resourceHandler: AppLanguageResourceHandler private lateinit var lastLoadedFragment: String private var isProfileDeletionDialogVisible: Boolean = false + @Inject + lateinit var snackbarManager: SnackbarManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -86,6 +89,7 @@ class AdministratorControlsActivity : isProfileDeletionDialogVisible ) title = resourceHandler.getStringInLocale(R.string.administrator_controls) + snackbarManager.enableShowingSnackbars(this) } override fun routeToAppVersion() { diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index fba6d5acc14..8fe26570e70 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -7,7 +7,6 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.Observer -import com.google.android.material.snackbar.Snackbar import org.oppia.android.R import org.oppia.android.app.administratorcontrols.AdministratorControlsActivity import org.oppia.android.app.administratorcontrols.ProfileEditDeletionDialogListener @@ -30,7 +29,8 @@ class ProfileEditFragmentPresenter @Inject constructor( private val activity: AppCompatActivity, private val fragment: Fragment, private val oppiaLogger: OppiaLogger, - private val profileManagementController: ProfileManagementController + private val profileManagementController: ProfileManagementController, + private val snackbarManager: SnackbarManager ) { @Inject @@ -152,30 +152,21 @@ class ProfileEditFragmentPresenter @Inject constructor( fragment, Observer { if (it is AsyncResult.Success) { - val profileDeletionSnackbar = Snackbar - .make( - fragment.requireView(), + snackbarManager.showSnackbar( R.string.profile_edit_delete_success, - Snackbar.LENGTH_SHORT + SnackbarController.SnackbarDuration.LONG ) - .setAction(R.string.log_out_dialog_okay_button) { } - .addCallback(object : Snackbar.Callback() { - override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { - if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { - val intent = - Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } else { - val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } - } - }) - .setActionTextColor(fragment.resources.getColor(R.color.color_def_bright_turquoise)) - profileDeletionSnackbar.show() - } + if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { + val intent = + Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } else { + val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } + } } ) } diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileListActivity.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileListActivity.kt index 0855ff14dd4..faf446ca7e9 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileListActivity.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileListActivity.kt @@ -15,11 +15,14 @@ class ProfileListActivity : RouteToProfileEditListener { @Inject lateinit var profileListActivityPresenter: ProfileListActivityPresenter + @Inject + lateinit var snackbarManager: SnackbarManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (activityComponent as ActivityComponentImpl).inject(this) profileListActivityPresenter.handleOnCreate() + snackbarManager.enableShowingSnackbars(this) } override fun onSupportNavigateUp(): Boolean { diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt index 551949c1d0b..5d0c1d76edd 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -1,27 +1,31 @@ package org.oppia.android.app.settings.profile import androidx.annotation.StringRes -import org.oppia.android.util.data.DataProvider +import java.util.* import javax.inject.Inject import javax.inject.Singleton +import org.oppia.android.util.data.DataProvider +import org.oppia.android.util.data.DataProviders @Singleton -abstract class SnackbarController @Inject constructor() { - // The class should have a queue of snackbars. +class SnackbarController @Inject constructor(private val dataProviders: DataProviders) { + + private val snackbarRequestQueue: Queue = LinkedList() fun getCurrentSnackbar(): DataProvider { - // Return a data provider that will provide the current snackbar request. - // not getting how to return a data provider + val currentRequest = snackbarRequestQueue.peek() + return dataProviders.createInMemoryDataProvider(SnackbarRequest::class.java) { + return@createInMemoryDataProvider currentRequest + ?: SnackbarRequest.ShowNothing + } } fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { - // Enqueue the snackbar request. - val list = mutableListOf() - list.add(request) + snackbarRequestQueue.add(request) } - fun dismissCurrentSnackbar() { - // dismiss the current snackbar + fun dismissCurrentSnackbar(){ + snackbarRequestQueue.remove() } sealed class SnackbarRequest { @@ -31,7 +35,6 @@ abstract class SnackbarController @Inject constructor() { object ShowNothing : SnackbarRequest() } - // Abstraction for Snackbar's length constants. enum class SnackbarDuration { SHORT, LONG diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index be9b34440e8..a3dedfcac5b 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -5,16 +5,13 @@ import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.profile_edit_fragment.* +import javax.inject.Inject import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData -import javax.inject.Inject class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { - // Use SnackbarController for displaying the current snackbar, hiding it after the snackbar hides, or showing a new one. fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration) { - // Enqueue snackbar using SnackbarController... snackbarController.enqueueSnackbar( SnackbarController.SnackbarRequest.ShowSnackbar( messageStringId, @@ -24,14 +21,16 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb } fun enableShowingSnackbars(activity: AppCompatActivity) { - // Called in an activity's onCreate to start listening for snackbar state. snackbarController.getCurrentSnackbar().toLiveData().observe(activity) { result -> when (result) { is AsyncResult.Success -> when (val request = result.value) { - is SnackbarController.SnackbarRequest.ShowSnackbar -> showSnackbar(activity.view, request) - SnackbarController.SnackbarRequest.ShowNothing -> {} // Do nothing. + is SnackbarController.SnackbarRequest.ShowSnackbar -> showSnackbar( + activity.findViewById( + android.R.id.content + ), request + ) + SnackbarController.SnackbarRequest.ShowNothing -> {} } - // Other cases... else -> {} } } @@ -48,10 +47,8 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb } if (activityView == null) { - // ...log an error if activityView is null and ignore the snackbar request (can't be shown--no activity UI). Log.e("SnackbarManager", "can't be shown--no activity UI") } - // ...compute length based on showRequest.duration and messageString based on showRequest.messageStringId -- the latter should be done using appResourceHandler (so that the string is in the correct language). else { Snackbar.make(activityView, showRequest.messageStringId, duration) .addCallback(object : Snackbar.Callback() { @@ -62,13 +59,6 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb } }) .show() - // ...show the snackbar & add a callback for when it dismisses--at that point SnackbarController.dismissCurrentSnackbar() should be called. } } - - // Abstract domain layer. -// enum class SnackbarDuration { -// SHORT, -// LONG -// } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 48a90cb25a5..1919e045984 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -592,5 +592,5 @@ Please select all correct choices. You may select more choices. No more than %s choices may be selected. - Profile Has Been Successfully Deleted. + Profile has been successfully deleted. From 85f8dbce990b3cb959cc3fc4de594762a5cf4f0c Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 25 Apr 2023 23:45:30 +0530 Subject: [PATCH 08/35] added snackbar --- .../AdministratorControlsActivity.kt | 2 +- .../profile/ProfileEditFragmentPresenter.kt | 28 +++++++++---------- .../settings/profile/SnackbarController.kt | 6 ++-- .../app/settings/profile/SnackbarManager.kt | 8 +++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt b/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt index 07e5d2a1f4b..0b5842e4925 100644 --- a/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt +++ b/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt @@ -13,11 +13,11 @@ import org.oppia.android.app.model.ScreenName.ADMINISTRATOR_CONTROLS_ACTIVITY import org.oppia.android.app.settings.profile.ProfileEditFragment import org.oppia.android.app.settings.profile.ProfileListActivity import org.oppia.android.app.settings.profile.ProfileListFragment +import org.oppia.android.app.settings.profile.SnackbarManager import org.oppia.android.app.translation.AppLanguageResourceHandler import org.oppia.android.util.extensions.getStringFromBundle import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName import javax.inject.Inject -import org.oppia.android.app.settings.profile.SnackbarManager /** Argument key for of title for selected controls in [AdministratorControlsActivity]. */ const val SELECTED_CONTROLS_TITLE_SAVED_KEY = diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index 8fe26570e70..6a77529867e 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -152,21 +152,21 @@ class ProfileEditFragmentPresenter @Inject constructor( fragment, Observer { if (it is AsyncResult.Success) { - snackbarManager.showSnackbar( - R.string.profile_edit_delete_success, - SnackbarController.SnackbarDuration.LONG - ) - if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { - val intent = - Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } else { - val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - fragment.startActivity(intent) - } + snackbarManager.showSnackbar( + R.string.profile_edit_delete_success, + SnackbarController.SnackbarDuration.LONG + ) + if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { + val intent = + Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) + } else { + val intent = Intent(fragment.requireContext(), ProfileListActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + fragment.startActivity(intent) } + } } ) } diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt index 5d0c1d76edd..f1909a1169d 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -1,11 +1,11 @@ package org.oppia.android.app.settings.profile import androidx.annotation.StringRes +import org.oppia.android.util.data.DataProvider +import org.oppia.android.util.data.DataProviders import java.util.* import javax.inject.Inject import javax.inject.Singleton -import org.oppia.android.util.data.DataProvider -import org.oppia.android.util.data.DataProviders @Singleton class SnackbarController @Inject constructor(private val dataProviders: DataProviders) { @@ -24,7 +24,7 @@ class SnackbarController @Inject constructor(private val dataProviders: DataProv snackbarRequestQueue.add(request) } - fun dismissCurrentSnackbar(){ + fun dismissCurrentSnackbar() { snackbarRequestQueue.remove() } diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index a3dedfcac5b..30ce9bde28d 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -5,9 +5,9 @@ import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar -import javax.inject.Inject import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData +import javax.inject.Inject class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { @@ -27,7 +27,8 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb is SnackbarController.SnackbarRequest.ShowSnackbar -> showSnackbar( activity.findViewById( android.R.id.content - ), request + ), + request ) SnackbarController.SnackbarRequest.ShowNothing -> {} } @@ -48,8 +49,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb if (activityView == null) { Log.e("SnackbarManager", "can't be shown--no activity UI") - } - else { + } else { Snackbar.make(activityView, showRequest.messageStringId, duration) .addCallback(object : Snackbar.Callback() { override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { From 257e961ef139085680448e9d042fc393fa022a35 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 25 Apr 2023 23:50:00 +0530 Subject: [PATCH 09/35] added snackbar --- .../oppia/android/app/settings/profile/SnackbarController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt index f1909a1169d..261573a2136 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -3,9 +3,9 @@ package org.oppia.android.app.settings.profile import androidx.annotation.StringRes import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders -import java.util.* import javax.inject.Inject import javax.inject.Singleton +import java.util.* @Singleton class SnackbarController @Inject constructor(private val dataProviders: DataProviders) { From 8960942a86e19c182616e2e303bb5ae7efbe3162 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 25 Apr 2023 23:53:22 +0530 Subject: [PATCH 10/35] added snackbar --- .../oppia/android/app/settings/profile/SnackbarController.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt index 261573a2136..a60328b9502 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt @@ -3,9 +3,10 @@ package org.oppia.android.app.settings.profile import androidx.annotation.StringRes import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders +import java.util.LinkedList +import java.util.Queue import javax.inject.Inject import javax.inject.Singleton -import java.util.* @Singleton class SnackbarController @Inject constructor(private val dataProviders: DataProviders) { From 31faaef8174946c4f445ad636fa948f5ed9e2d29 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 3 May 2023 23:05:00 +0530 Subject: [PATCH 11/35] added snackbar-request-provider-id --- .../profile/ProfileEditFragmentPresenter.kt | 1 + .../settings/profile/SnackbarController.kt | 43 -------------- .../app/settings/profile/SnackbarManager.kt | 10 +++- .../domain/snackbar/SnackbarController.kt | 58 +++++++++++++++++++ 4 files changed, 67 insertions(+), 45 deletions(-) delete mode 100644 app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt create mode 100644 domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index 6a77529867e..0d2f96db083 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -16,6 +16,7 @@ import org.oppia.android.app.model.ProfileId import org.oppia.android.databinding.ProfileEditFragmentBinding import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.profile.ProfileManagementController +import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt deleted file mode 100644 index a60328b9502..00000000000 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarController.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.oppia.android.app.settings.profile - -import androidx.annotation.StringRes -import org.oppia.android.util.data.DataProvider -import org.oppia.android.util.data.DataProviders -import java.util.LinkedList -import java.util.Queue -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SnackbarController @Inject constructor(private val dataProviders: DataProviders) { - - private val snackbarRequestQueue: Queue = LinkedList() - - fun getCurrentSnackbar(): DataProvider { - val currentRequest = snackbarRequestQueue.peek() - return dataProviders.createInMemoryDataProvider(SnackbarRequest::class.java) { - return@createInMemoryDataProvider currentRequest - ?: SnackbarRequest.ShowNothing - } - } - - fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { - snackbarRequestQueue.add(request) - } - - fun dismissCurrentSnackbar() { - snackbarRequestQueue.remove() - } - - sealed class SnackbarRequest { - data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : - SnackbarRequest() - - object ShowNothing : SnackbarRequest() - } - - enum class SnackbarDuration { - SHORT, - LONG - } -} diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 30ce9bde28d..ba5a52d903b 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -8,6 +8,7 @@ import com.google.android.material.snackbar.Snackbar import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject +import org.oppia.android.domain.snackbar.SnackbarController class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { @@ -30,7 +31,12 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb ), request ) - SnackbarController.SnackbarRequest.ShowNothing -> {} + SnackbarController.SnackbarRequest.ShowNothing -> { + if (snackbarController.snackbarRequestQueue.isNotEmpty()){ + snackbarController.notifyPotentialSnackbarChange() + snackbarController.dismissCurrentSnackbar() + } + } } else -> {} } @@ -54,7 +60,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb .addCallback(object : Snackbar.Callback() { override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { super.onDismissed(transientBottomBar, event) - // ...dismiss the snackbar when it's dismissed. + snackbarController.notifyPotentialSnackbarChange() snackbarController.dismissCurrentSnackbar() } }) diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt new file mode 100644 index 00000000000..1d4fa0732a0 --- /dev/null +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -0,0 +1,58 @@ +package org.oppia.android.domain.snackbar + +import androidx.annotation.StringRes +import org.oppia.android.util.data.DataProvider +import org.oppia.android.util.data.DataProviders +import java.util.LinkedList +import java.util.Queue +import javax.inject.Inject +import javax.inject.Singleton +import org.oppia.android.util.data.AsyncDataSubscriptionManager + +private const val SNACKBAR_REQUEST_PROVIDER_ID = "snackbar_request_provider_id" + +@Singleton +class SnackbarController @Inject constructor( + private val dataProviders: DataProviders, + private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager, +) { + + private val _snackbarRequestQueue: Queue = LinkedList() + + val snackbarRequestQueue: Queue + get() = _snackbarRequestQueue + + fun getCurrentSnackbar(): DataProvider { + val currentRequest = _snackbarRequestQueue.peek() + return dataProviders.createInMemoryDataProvider(SNACKBAR_REQUEST_PROVIDER_ID) { + return@createInMemoryDataProvider currentRequest + ?: SnackbarRequest.ShowNothing + } + } + + fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { + _snackbarRequestQueue.add(request) + notifyPotentialSnackbarChange() + } + + fun dismissCurrentSnackbar() { + notifyPotentialSnackbarChange() + _snackbarRequestQueue.remove() + } + + fun notifyPotentialSnackbarChange() { + asyncDataSubscriptionManager.notifyChangeAsync(SNACKBAR_REQUEST_PROVIDER_ID) + } + + sealed class SnackbarRequest { + data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : + SnackbarRequest() + + object ShowNothing : SnackbarRequest() + } + + enum class SnackbarDuration { + SHORT, + LONG + } +} From a3a3c1975836663a96114cf11d26ea719442ce49 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 3 May 2023 23:08:47 +0530 Subject: [PATCH 12/35] rearranged-imports --- .../org/oppia/android/app/settings/profile/SnackbarManager.kt | 4 ++-- .../org/oppia/android/domain/snackbar/SnackbarController.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index ba5a52d903b..9551e7df72f 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -7,8 +7,8 @@ import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData -import javax.inject.Inject import org.oppia.android.domain.snackbar.SnackbarController +import javax.inject.Inject class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { @@ -32,7 +32,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb request ) SnackbarController.SnackbarRequest.ShowNothing -> { - if (snackbarController.snackbarRequestQueue.isNotEmpty()){ + if (snackbarController.snackbarRequestQueue.isNotEmpty()) { snackbarController.notifyPotentialSnackbarChange() snackbarController.dismissCurrentSnackbar() } diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 1d4fa0732a0..dcdfc33e704 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -3,11 +3,11 @@ package org.oppia.android.domain.snackbar import androidx.annotation.StringRes import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders +import org.oppia.android.util.data.AsyncDataSubscriptionManager import java.util.LinkedList import java.util.Queue import javax.inject.Inject import javax.inject.Singleton -import org.oppia.android.util.data.AsyncDataSubscriptionManager private const val SNACKBAR_REQUEST_PROVIDER_ID = "snackbar_request_provider_id" From e5f39e94d52a7117c0614bcdf94023c4277ac33b Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 3 May 2023 23:12:48 +0530 Subject: [PATCH 13/35] rearranged-imports --- .../org/oppia/android/app/settings/profile/SnackbarManager.kt | 2 +- .../org/oppia/android/domain/snackbar/SnackbarController.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 9551e7df72f..2b3a2f37bd4 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -5,9 +5,9 @@ import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar +import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData -import org.oppia.android.domain.snackbar.SnackbarController import javax.inject.Inject class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index dcdfc33e704..0022e322873 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -1,9 +1,9 @@ package org.oppia.android.domain.snackbar import androidx.annotation.StringRes +import org.oppia.android.util.data.AsyncDataSubscriptionManager import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders -import org.oppia.android.util.data.AsyncDataSubscriptionManager import java.util.LinkedList import java.util.Queue import javax.inject.Inject From 84da79dc5d0c6e021f94944dbb78c1c2054137c0 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Mon, 29 May 2023 17:01:45 +0530 Subject: [PATCH 14/35] added test for the snackbar controller --- .../domain/snackbar/SnackbarController.kt | 2 +- .../domain/snackbar/SnackbarControllerTest.kt | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 0022e322873..c6883933150 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -36,8 +36,8 @@ class SnackbarController @Inject constructor( } fun dismissCurrentSnackbar() { - notifyPotentialSnackbarChange() _snackbarRequestQueue.remove() + notifyPotentialSnackbarChange() } fun notifyPotentialSnackbarChange() { diff --git a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt new file mode 100644 index 00000000000..bac8f62b888 --- /dev/null +++ b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt @@ -0,0 +1,132 @@ +package org.oppia.android.domain.snackbar + +import android.app.Application +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.Module +import dagger.Provides +import javax.inject.Inject +import javax.inject.Singleton +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.oppia.android.testing.TestLogReportingModule +import org.oppia.android.testing.data.DataProviderTestMonitor +import org.oppia.android.testing.robolectric.RobolectricModule +import org.oppia.android.testing.threading.TestDispatcherModule +import org.oppia.android.testing.time.FakeOppiaClockModule +import org.oppia.android.util.caching.AssetModule +import org.oppia.android.util.data.DataProvidersInjector +import org.oppia.android.util.data.DataProvidersInjectorProvider +import org.oppia.android.util.locale.LocaleProdModule +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode + +const val test_string: Int = 1 + +@Suppress("FunctionName", "SameParameterValue") +@RunWith(AndroidJUnit4::class) +@LooperMode(LooperMode.Mode.PAUSED) +@Config(application = SnackbarControllerTest.TestApplication::class) +class SnackbarControllerTest { + + @Inject + lateinit var context: Context + + @Inject + lateinit var snackbarController: SnackbarController + + @Inject + lateinit var monitorFactory: DataProviderTestMonitor.Factory + + lateinit var request: SnackbarController.SnackbarRequest.ShowSnackbar + lateinit var request2: SnackbarController.SnackbarRequest.ShowSnackbar + + + @Before + fun setUp() { + request = SnackbarController.SnackbarRequest.ShowSnackbar( + messageStringId = test_string, + duration = SnackbarController.SnackbarDuration.SHORT + ) + request2 = SnackbarController.SnackbarRequest.ShowSnackbar( + messageStringId = test_string, + duration = SnackbarController.SnackbarDuration.LONG + ) + setUpTestApplicationComponent() + } + + @Test + fun testAddSnackbarRequestReturnsElementInTheQueue() { + snackbarController.enqueueSnackbar(request) + + assertThat(snackbarController.snackbarRequestQueue).contains(request) + } + + @Test + fun testAddAndRemoveSnackbarRequestReturnsElementNotInTheQueue() { + snackbarController.enqueueSnackbar(request) + snackbarController.dismissCurrentSnackbar() + + assertThat(snackbarController.snackbarRequestQueue).doesNotContain(request) + } + + @Test + fun testAddTwoRequestsReturnsEarliestRequestInTheQueue(){ + snackbarController.enqueueSnackbar(request) + snackbarController.enqueueSnackbar(request2) + + assertThat(snackbarController.snackbarRequestQueue.peek()).isEqualTo(request) + } + + private fun setUpTestApplicationComponent() { + ApplicationProvider.getApplicationContext().inject(this) + } + + @Module + class TestModule { + @Provides + @Singleton + fun provideContext(application: Application): Context { + return application + } + } + + @Singleton + @Component( + modules = [ + TestModule::class, AssetModule::class, LocaleProdModule::class, FakeOppiaClockModule::class, + TestLogReportingModule::class, TestDispatcherModule::class, RobolectricModule::class, + ] + ) + interface TestApplicationComponent : DataProvidersInjector { + @Component.Builder + interface Builder { + @BindsInstance + fun setApplication(application: Application): Builder + + fun build(): TestApplicationComponent + } + + fun inject(snackbarControllerTest: SnackbarControllerTest) + } + + class TestApplication : Application(), DataProvidersInjectorProvider { + private val component: TestApplicationComponent by lazy { + DaggerSnackbarControllerTest_TestApplicationComponent.builder() + .setApplication(this) + .build() + } + + fun inject(snackbarControllerTest: SnackbarControllerTest) { + component.inject(snackbarControllerTest) + } + + override fun getDataProvidersInjector(): DataProvidersInjector = component + } + +} \ No newline at end of file From 2db6631c73a570d22593770eb3c98d66ce6b29c5 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Mon, 29 May 2023 17:08:13 +0530 Subject: [PATCH 15/35] corrected import statements --- .../android/domain/snackbar/SnackbarControllerTest.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt index bac8f62b888..8c8cfde0c1e 100644 --- a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt @@ -9,8 +9,6 @@ import dagger.BindsInstance import dagger.Component import dagger.Module import dagger.Provides -import javax.inject.Inject -import javax.inject.Singleton import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -25,6 +23,8 @@ import org.oppia.android.util.data.DataProvidersInjectorProvider import org.oppia.android.util.locale.LocaleProdModule import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode +import javax.inject.Inject +import javax.inject.Singleton const val test_string: Int = 1 @@ -46,7 +46,6 @@ class SnackbarControllerTest { lateinit var request: SnackbarController.SnackbarRequest.ShowSnackbar lateinit var request2: SnackbarController.SnackbarRequest.ShowSnackbar - @Before fun setUp() { request = SnackbarController.SnackbarRequest.ShowSnackbar( @@ -76,7 +75,7 @@ class SnackbarControllerTest { } @Test - fun testAddTwoRequestsReturnsEarliestRequestInTheQueue(){ + fun testAddTwoRequestsReturnsEarliestRequestInTheQueue() { snackbarController.enqueueSnackbar(request) snackbarController.enqueueSnackbar(request2) @@ -128,5 +127,4 @@ class SnackbarControllerTest { override fun getDataProvidersInjector(): DataProvidersInjector = component } - -} \ No newline at end of file +} From 455edf4d54db89e2295ef24b0f4fb954e03c673a Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 11 Jul 2023 22:37:18 +0530 Subject: [PATCH 16/35] added two tests --- .../app/settings/profile/SnackbarManager.kt | 2 -- .../profile/ProfileEditFragmentTest.kt | 19 +++++++++++++++++++ .../domain/snackbar/SnackbarController.kt | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 2b3a2f37bd4..ef5c9042506 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -33,7 +33,6 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb ) SnackbarController.SnackbarRequest.ShowNothing -> { if (snackbarController.snackbarRequestQueue.isNotEmpty()) { - snackbarController.notifyPotentialSnackbarChange() snackbarController.dismissCurrentSnackbar() } } @@ -60,7 +59,6 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb .addCallback(object : Snackbar.Callback() { override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { super.onDismissed(transientBottomBar, event) - snackbarController.notifyPotentialSnackbarChange() snackbarController.dismissCurrentSnackbar() } }) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index 5c28e75d5d9..040119b9051 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -158,6 +158,25 @@ class ProfileEditFragmentTest { } } + @Test + fun testProfileEdit_startWithUserProfile_clickProfileDeletionButton_deleteSnackbarIsVisible() { + launchFragmentTestActivity(internalProfileId = 1).use { + onView(withId(R.id.profile_delete_button)).perform(click()) + onView(withId(android.R.id.button1)).perform(click()) + onView(withId(com.google.android.material.R.id.snackbar_text)) + .check(matches(withText(R.string.profile_edit_delete_success))) + } + } + + @Test + fun testProfileEdit_startWithUserProfile_AfterDeleteSnackbar_profileActivityIsShownAgain() { + launchFragmentTestActivity(internalProfileId = 1).use { + onView(withId(R.id.profile_delete_button)).perform(click()) + onView(withId(android.R.id.button1)).perform(click()) + intended(hasComponent(ProfileListActivity::class.java.name)) + } + } + @Test @Config(qualifiers = "land") fun testProfileEdit_configChange_startWithUserProfile_clickDelete_checkOpensDeletionDialog() { diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index c6883933150..9bc592ac498 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -40,7 +40,7 @@ class SnackbarController @Inject constructor( notifyPotentialSnackbarChange() } - fun notifyPotentialSnackbarChange() { + private fun notifyPotentialSnackbarChange() { asyncDataSubscriptionManager.notifyChangeAsync(SNACKBAR_REQUEST_PROVIDER_ID) } From b7f1542b5532401276fc483efe99383f40a72e0b Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Thu, 13 Jul 2023 03:20:46 +0530 Subject: [PATCH 17/35] added the main functionality tests and some few changes --- .../AdministratorControlsActivity.kt | 4 --- .../app/settings/profile/SnackbarManager.kt | 22 ++++++++++-- .../domain/snackbar/SnackbarController.kt | 26 ++++++++++++-- .../domain/snackbar/SnackbarControllerTest.kt | 34 +++++++------------ 4 files changed, 55 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt b/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt index 5eb3e60c4ca..74e0f97ae89 100644 --- a/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt +++ b/app/src/main/java/org/oppia/android/app/administratorcontrols/AdministratorControlsActivity.kt @@ -13,7 +13,6 @@ import org.oppia.android.app.model.ScreenName.ADMINISTRATOR_CONTROLS_ACTIVITY import org.oppia.android.app.settings.profile.ProfileEditFragment import org.oppia.android.app.settings.profile.ProfileListActivity import org.oppia.android.app.settings.profile.ProfileListFragment -import org.oppia.android.app.settings.profile.SnackbarManager import org.oppia.android.app.translation.AppLanguageResourceHandler import org.oppia.android.util.extensions.getStringFromBundle import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName @@ -65,8 +64,6 @@ class AdministratorControlsActivity : lateinit var resourceHandler: AppLanguageResourceHandler private lateinit var lastLoadedFragment: String private var isProfileDeletionDialogVisible: Boolean = false - @Inject - lateinit var snackbarManager: SnackbarManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -89,7 +86,6 @@ class AdministratorControlsActivity : isProfileDeletionDialogVisible ) title = resourceHandler.getStringInLocale(R.string.administrator_controls) - snackbarManager.enableShowingSnackbars(this) } override fun routeToAppVersion() { diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index ef5c9042506..a18a255fd86 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -1,17 +1,30 @@ package org.oppia.android.app.settings.profile -import android.util.Log import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar +import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject +private const val TAG = "SnackbarManager" +private const val ERROR_MESSAGE = "can't be shown--no activity UI" + +/** Manager for showing snackbars. */ class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { + @Inject + lateinit var oppiaLogger: OppiaLogger + + /** + * Enqueues the snackbar that is be to shown in the FIFO buffer. + * + * @param messageStringId The message string of string resource that is to be displayed. + * @param duration The duration for which snackbar is to be shown. + * */ fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration) { snackbarController.enqueueSnackbar( SnackbarController.SnackbarRequest.ShowSnackbar( @@ -21,6 +34,11 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb ) } + /** + * Enables the activity to show the snackbar. + * + * @param activity For the activity that is to be observed and to upon which the snackbar to be shown. + */ fun enableShowingSnackbars(activity: AppCompatActivity) { snackbarController.getCurrentSnackbar().toLiveData().observe(activity) { result -> when (result) { @@ -53,7 +71,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb } if (activityView == null) { - Log.e("SnackbarManager", "can't be shown--no activity UI") + oppiaLogger.e(TAG, ERROR_MESSAGE) } else { Snackbar.make(activityView, showRequest.messageStringId, duration) .addCallback(object : Snackbar.Callback() { diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 9bc592ac498..6ca831cf8f2 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -9,8 +9,10 @@ import java.util.Queue import javax.inject.Inject import javax.inject.Singleton -private const val SNACKBAR_REQUEST_PROVIDER_ID = "snackbar_request_provider_id" +private const val GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID = + "get_current_snackbar_request_provider_id" +/** Controller for enqueueing, dismissing, and retrieving snackbars. */ @Singleton class SnackbarController @Inject constructor( private val dataProviders: DataProviders, @@ -19,29 +21,41 @@ class SnackbarController @Inject constructor( private val _snackbarRequestQueue: Queue = LinkedList() + /** Queue for the snackbar request that to be shown in FIFO Behaviour. */ val snackbarRequestQueue: Queue get() = _snackbarRequestQueue + /** + * Gets the snackbar that is enqueued first. + * + * @return a [DataProvider] of the current request. + */ fun getCurrentSnackbar(): DataProvider { val currentRequest = _snackbarRequestQueue.peek() - return dataProviders.createInMemoryDataProvider(SNACKBAR_REQUEST_PROVIDER_ID) { + return dataProviders.createInMemoryDataProvider(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID) { return@createInMemoryDataProvider currentRequest ?: SnackbarRequest.ShowNothing } } + /** + * Enqueue the snackbar request that to be shown and notify the data provider that it is changed. + * + * @param request the request that is to be added in the queue. + */ fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { _snackbarRequestQueue.add(request) notifyPotentialSnackbarChange() } + /** Dismiss the current snackbar and notify the data provider that it is changed. */ fun dismissCurrentSnackbar() { _snackbarRequestQueue.remove() notifyPotentialSnackbarChange() } private fun notifyPotentialSnackbarChange() { - asyncDataSubscriptionManager.notifyChangeAsync(SNACKBAR_REQUEST_PROVIDER_ID) + asyncDataSubscriptionManager.notifyChangeAsync(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID) } sealed class SnackbarRequest { @@ -51,8 +65,14 @@ class SnackbarController @Inject constructor( object ShowNothing : SnackbarRequest() } + /** + * These are for the length of the snackbar that is to be shown. + */ enum class SnackbarDuration { + /** Indicates the short duration of the snackbar */ SHORT, + + /** Indicates the long duration of the snackbar */ LONG } } diff --git a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt index 8c8cfde0c1e..d8bfc72bd95 100644 --- a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt @@ -26,7 +26,7 @@ import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton -const val test_string: Int = 1 +private const val STRING_ID: Int = 1 @Suppress("FunctionName", "SameParameterValue") @RunWith(AndroidJUnit4::class) @@ -34,51 +34,41 @@ const val test_string: Int = 1 @Config(application = SnackbarControllerTest.TestApplication::class) class SnackbarControllerTest { - @Inject - lateinit var context: Context - @Inject lateinit var snackbarController: SnackbarController - @Inject - lateinit var monitorFactory: DataProviderTestMonitor.Factory + var request = SnackbarController.SnackbarRequest.ShowSnackbar( + messageStringId = STRING_ID, + duration = SnackbarController.SnackbarDuration.SHORT + ) - lateinit var request: SnackbarController.SnackbarRequest.ShowSnackbar - lateinit var request2: SnackbarController.SnackbarRequest.ShowSnackbar + var request2 = SnackbarController.SnackbarRequest.ShowSnackbar( + messageStringId = STRING_ID, + duration = SnackbarController.SnackbarDuration.LONG + ) @Before fun setUp() { - request = SnackbarController.SnackbarRequest.ShowSnackbar( - messageStringId = test_string, - duration = SnackbarController.SnackbarDuration.SHORT - ) - request2 = SnackbarController.SnackbarRequest.ShowSnackbar( - messageStringId = test_string, - duration = SnackbarController.SnackbarDuration.LONG - ) setUpTestApplicationComponent() } @Test - fun testAddSnackbarRequestReturnsElementInTheQueue() { + fun testEnqueueSnackbarRequest_returns_requestInTheQueue() { snackbarController.enqueueSnackbar(request) - assertThat(snackbarController.snackbarRequestQueue).contains(request) } @Test - fun testAddAndRemoveSnackbarRequestReturnsElementNotInTheQueue() { + fun testEnqueueAndDismissSnackbarRequest_returns_requestNotInTheQueue() { snackbarController.enqueueSnackbar(request) snackbarController.dismissCurrentSnackbar() - assertThat(snackbarController.snackbarRequestQueue).doesNotContain(request) } @Test - fun testAddTwoRequestsReturnsEarliestRequestInTheQueue() { + fun testEnqueueTwoRequests_returns_FirstRequestInTheQueue() { snackbarController.enqueueSnackbar(request) snackbarController.enqueueSnackbar(request2) - assertThat(snackbarController.snackbarRequestQueue.peek()).isEqualTo(request) } From 4d8d7143eb44edd10fe6981e58b10000925d8110 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Thu, 13 Jul 2023 03:37:21 +0530 Subject: [PATCH 18/35] removed unused import --- .../org/oppia/android/domain/snackbar/SnackbarControllerTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt index d8bfc72bd95..93882082021 100644 --- a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt @@ -13,7 +13,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.oppia.android.testing.TestLogReportingModule -import org.oppia.android.testing.data.DataProviderTestMonitor import org.oppia.android.testing.robolectric.RobolectricModule import org.oppia.android.testing.threading.TestDispatcherModule import org.oppia.android.testing.time.FakeOppiaClockModule From c92ddfde4278e5c2af423f128ab169986d8d5b75 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Thu, 13 Jul 2023 19:02:28 +0530 Subject: [PATCH 19/35] added Kdoc for the sealed class --- .../oppia/android/domain/snackbar/SnackbarController.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 6ca831cf8f2..8bd854124fd 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -58,10 +58,18 @@ class SnackbarController @Inject constructor( asyncDataSubscriptionManager.notifyChangeAsync(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID) } + /** For the Snackbar Request. */ sealed class SnackbarRequest { + + /** For showing the snackbar. + * + * @param messageStringId The message string of string resource that is to be displayed. + * @param duration The duration for which snackbar is to be shown. + */ data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : SnackbarRequest() + /** For not showing snackbar and dismissing the snackbar if present in the queue. */ object ShowNothing : SnackbarRequest() } From f2f51bed496dca6e50ee446cca30391bd5d087a3 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Sat, 15 Jul 2023 00:18:26 +0530 Subject: [PATCH 20/35] corrected tests and kdocs --- .../app/settings/profile/SnackbarManager.kt | 8 ++-- .../profile/ProfileEditFragmentTest.kt | 43 +++++++++++++------ .../domain/snackbar/SnackbarController.kt | 25 ++++++----- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index a18a255fd86..d58e02bbf59 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -22,9 +22,9 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb /** * Enqueues the snackbar that is be to shown in the FIFO buffer. * - * @param messageStringId The message string of string resource that is to be displayed. - * @param duration The duration for which snackbar is to be shown. - * */ + * @param messageStringId The message string of string resource that is to be displayed + * @param duration The duration for which snackbar is to be shown + */ fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration) { snackbarController.enqueueSnackbar( SnackbarController.SnackbarRequest.ShowSnackbar( @@ -37,7 +37,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb /** * Enables the activity to show the snackbar. * - * @param activity For the activity that is to be observed and to upon which the snackbar to be shown. + * @param activity that is to observing for a snackbar and in which the snackbar will be shown */ fun enableShowingSnackbars(activity: AppCompatActivity) { snackbarController.getCurrentSnackbar().toLiveData().observe(activity) { result -> diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index 040119b9051..d12b594397a 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -112,6 +112,7 @@ import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton +import org.hamcrest.Matchers.allOf /** Tests for [ProfileEditFragment]. */ // FunctionName: test names are conventionally named with underscores. @@ -121,14 +122,21 @@ import javax.inject.Singleton @Config(application = ProfileEditFragmentTest.TestApplication::class, qualifiers = "port-xxhdpi") class ProfileEditFragmentTest { - @get:Rule val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() - @get:Rule val oppiaTestRule = OppiaTestRule() - - @Inject lateinit var context: Context - @Inject lateinit var profileTestHelper: ProfileTestHelper - @Inject lateinit var profileManagementController: ProfileManagementController - @Inject lateinit var monitorFactory: DataProviderTestMonitor.Factory - @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + @get:Rule + val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() + @get:Rule + val oppiaTestRule = OppiaTestRule() + + @Inject + lateinit var context: Context + @Inject + lateinit var profileTestHelper: ProfileTestHelper + @Inject + lateinit var profileManagementController: ProfileManagementController + @Inject + lateinit var monitorFactory: DataProviderTestMonitor.Factory + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers @Before fun setUp() { @@ -162,9 +170,13 @@ class ProfileEditFragmentTest { fun testProfileEdit_startWithUserProfile_clickProfileDeletionButton_deleteSnackbarIsVisible() { launchFragmentTestActivity(internalProfileId = 1).use { onView(withId(R.id.profile_delete_button)).perform(click()) - onView(withId(android.R.id.button1)).perform(click()) - onView(withId(com.google.android.material.R.id.snackbar_text)) - .check(matches(withText(R.string.profile_edit_delete_success))) + testCoroutineDispatchers.runCurrent() + onView(withText(R.string.profile_edit_delete_dialog_positive)) + .inRoot(isDialog()) + .perform(click()) + testCoroutineDispatchers.runCurrent() + onView(allOf(withText(R.string.profile_edit_delete_success))) + .check(matches(isDisplayed())) } } @@ -172,7 +184,14 @@ class ProfileEditFragmentTest { fun testProfileEdit_startWithUserProfile_AfterDeleteSnackbar_profileActivityIsShownAgain() { launchFragmentTestActivity(internalProfileId = 1).use { onView(withId(R.id.profile_delete_button)).perform(click()) - onView(withId(android.R.id.button1)).perform(click()) + testCoroutineDispatchers.runCurrent() + onView(withText(R.string.profile_edit_delete_dialog_positive)) + .inRoot(isDialog()) + .perform(click()) + testCoroutineDispatchers.runCurrent() + onView(allOf(withText(R.string.profile_edit_delete_success))) + .check(matches(isDisplayed())) + testCoroutineDispatchers.runCurrent() intended(hasComponent(ProfileListActivity::class.java.name)) } } diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 8bd854124fd..eb00dab57d6 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -21,14 +21,14 @@ class SnackbarController @Inject constructor( private val _snackbarRequestQueue: Queue = LinkedList() - /** Queue for the snackbar request that to be shown in FIFO Behaviour. */ + /** Queue of the snackbar requests that are to be shown based on FIFO. */ val snackbarRequestQueue: Queue get() = _snackbarRequestQueue /** * Gets the snackbar that is enqueued first. * - * @return a [DataProvider] of the current request. + * @return a [DataProvider] of the current request */ fun getCurrentSnackbar(): DataProvider { val currentRequest = _snackbarRequestQueue.peek() @@ -39,16 +39,16 @@ class SnackbarController @Inject constructor( } /** - * Enqueue the snackbar request that to be shown and notify the data provider that it is changed. + * Enqueue the snackbar request that is to be shown and notify subscribers that it has changed. * - * @param request the request that is to be added in the queue. + * @param request that is to be added in the queue */ fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { _snackbarRequestQueue.add(request) notifyPotentialSnackbarChange() } - /** Dismiss the current snackbar and notify the data provider that it is changed. */ + /** Dismiss the current snackbar and notify subscribers that the [DataProvider] has changed. */ fun dismissCurrentSnackbar() { _snackbarRequestQueue.remove() notifyPotentialSnackbarChange() @@ -58,13 +58,13 @@ class SnackbarController @Inject constructor( asyncDataSubscriptionManager.notifyChangeAsync(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID) } - /** For the Snackbar Request. */ + /** Sealed class that encapsulates the SnackbarRequest behaviour. */ sealed class SnackbarRequest { /** For showing the snackbar. * - * @param messageStringId The message string of string resource that is to be displayed. - * @param duration The duration for which snackbar is to be shown. + * @param messageStringId The message string of string resource that is to be displayed + * @param duration The duration for which snackbar is to be shown */ data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : SnackbarRequest() @@ -73,14 +73,13 @@ class SnackbarController @Inject constructor( object ShowNothing : SnackbarRequest() } - /** - * These are for the length of the snackbar that is to be shown. - */ + /** These are for the length of the snackbar that is to be shown. */ enum class SnackbarDuration { - /** Indicates the short duration of the snackbar */ + + /** Indicates the short duration of the snackbar. */ SHORT, - /** Indicates the long duration of the snackbar */ + /** Indicates the long duration of the snackbar. */ LONG } } From a40b2f83a936e3f70cd2ec96b13e6a87705c7292 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 19 Jul 2023 01:04:50 +0530 Subject: [PATCH 21/35] corrected issues --- .../android/app/settings/profile/ProfileEditFragmentTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index d12b594397a..fa57ebecd26 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -25,6 +25,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import dagger.Component +import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.not import org.junit.After import org.junit.Before @@ -112,7 +113,6 @@ import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton -import org.hamcrest.Matchers.allOf /** Tests for [ProfileEditFragment]. */ // FunctionName: test names are conventionally named with underscores. @@ -189,7 +189,7 @@ class ProfileEditFragmentTest { .inRoot(isDialog()) .perform(click()) testCoroutineDispatchers.runCurrent() - onView(allOf(withText(R.string.profile_edit_delete_success))) + onView(allOf(withText(R.string.profile_edit_delete_success))) .check(matches(isDisplayed())) testCoroutineDispatchers.runCurrent() intended(hasComponent(ProfileListActivity::class.java.name)) From 1501043b20f51d733b4d3077dd65bdb405855d6d Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Mon, 31 Jul 2023 00:14:07 +0530 Subject: [PATCH 22/35] added last --- .../settings/profile/SnackbarManagerTest.kt | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt new file mode 100644 index 00000000000..cf38ee567ee --- /dev/null +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt @@ -0,0 +1,194 @@ +package org.oppia.android.app.settings.profile + +import android.app.Application +import android.content.Context +import androidx.appcompat.app.AppCompatActivity +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.intent.Intents +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.runners.AndroidJUnit4 +import dagger.Component +import javax.inject.Inject +import javax.inject.Singleton +import org.hamcrest.Matchers.allOf +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.oppia.android.R +import org.oppia.android.app.activity.ActivityComponent +import org.oppia.android.app.activity.ActivityComponentFactory +import org.oppia.android.app.activity.route.ActivityRouterModule +import org.oppia.android.app.application.ApplicationComponent +import org.oppia.android.app.application.ApplicationInjector +import org.oppia.android.app.application.ApplicationInjectorProvider +import org.oppia.android.app.application.ApplicationModule +import org.oppia.android.app.application.ApplicationStartupListenerModule +import org.oppia.android.app.application.testing.TestingBuildFlavorModule +import org.oppia.android.app.devoptions.DeveloperOptionsModule +import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule +import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule +import org.oppia.android.app.shim.ViewBindingShimModule +import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule +import org.oppia.android.data.backends.gae.NetworkConfigProdModule +import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.domain.classify.InteractionsModule +import org.oppia.android.domain.classify.rules.algebraicexpressioninput.AlgebraicExpressionInputModule +import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule +import org.oppia.android.domain.classify.rules.dragAndDropSortInput.DragDropSortInputModule +import org.oppia.android.domain.classify.rules.fractioninput.FractionInputModule +import org.oppia.android.domain.classify.rules.imageClickInput.ImageClickInputModule +import org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputModule +import org.oppia.android.domain.classify.rules.mathequationinput.MathEquationInputModule +import org.oppia.android.domain.classify.rules.multiplechoiceinput.MultipleChoiceInputModule +import org.oppia.android.domain.classify.rules.numberwithunits.NumberWithUnitsRuleModule +import org.oppia.android.domain.classify.rules.numericexpressioninput.NumericExpressionInputModule +import org.oppia.android.domain.classify.rules.numericinput.NumericInputRuleModule +import org.oppia.android.domain.classify.rules.ratioinput.RatioInputModule +import org.oppia.android.domain.classify.rules.textinput.TextInputRuleModule +import org.oppia.android.domain.exploration.ExplorationProgressModule +import org.oppia.android.domain.exploration.ExplorationStorageModule +import org.oppia.android.domain.hintsandsolution.HintsAndSolutionConfigModule +import org.oppia.android.domain.hintsandsolution.HintsAndSolutionProdModule +import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule +import org.oppia.android.domain.oppialogger.LogStorageModule +import org.oppia.android.domain.oppialogger.LoggingIdentifierModule +import org.oppia.android.domain.oppialogger.analytics.ApplicationLifecycleModule +import org.oppia.android.domain.oppialogger.analytics.CpuPerformanceSnapshotterModule +import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModule +import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule +import org.oppia.android.domain.platformparameter.PlatformParameterModule +import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule +import androidx.test.espresso.assertion.ViewAssertions.matches +import org.oppia.android.domain.question.QuestionModule +import org.oppia.android.domain.snackbar.SnackbarController +import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule +import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule +import org.oppia.android.testing.OppiaTestRule +import org.oppia.android.testing.TestLogReportingModule +import org.oppia.android.testing.junit.InitializeDefaultLocaleRule +import org.oppia.android.testing.robolectric.RobolectricModule +import org.oppia.android.testing.threading.TestCoroutineDispatchers +import org.oppia.android.testing.threading.TestDispatcherModule +import org.oppia.android.testing.time.FakeOppiaClockModule +import org.oppia.android.util.accessibility.AccessibilityTestModule +import org.oppia.android.util.caching.AssetModule +import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.gcsresource.GcsResourceModule +import org.oppia.android.util.locale.LocaleProdModule +import org.oppia.android.util.logging.EventLoggingConfigurationModule +import org.oppia.android.util.logging.LoggerModule +import org.oppia.android.util.logging.SyncStatusModule +import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule +import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule +import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule +import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule +import org.oppia.android.util.parser.image.GlideImageLoaderModule +import org.oppia.android.util.parser.image.ImageParsingModule +import org.robolectric.annotation.LooperMode + +/** Tests for [SnackbarManager]*/ +@RunWith(AndroidJUnit4::class) +@LooperMode(LooperMode.Mode.PAUSED) +class SnackbarManagerTest { + + @get:Rule + val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() + + @get:Rule + val oppiaTestRule = OppiaTestRule() + + @Inject + lateinit var context: Context + + @Inject + lateinit var snackbarManager: SnackbarManager + + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + + @Before + fun setUp() { + Intents.init() + setUpTestApplicationComponent() + testCoroutineDispatchers.registerIdlingResource() + } + + @After + fun tearDown() { + testCoroutineDispatchers.unregisterIdlingResource() + Intents.release() + } + + + @Test + fun firstTest(){ + snackbarManager.showSnackbar(R.string.profile_edit_delete_success, SnackbarController.SnackbarDuration.SHORT) + onView(allOf(withText(R.string.profile_edit_delete_success))) + .check(matches(isDisplayed())) + } + + + private fun setUpTestApplicationComponent() { + ApplicationProvider.getApplicationContext().inject(this) + } + + @Singleton + @Component( + modules = [ + RobolectricModule::class, + PlatformParameterModule::class, PlatformParameterSingletonModule::class, + TestDispatcherModule::class, ApplicationModule::class, + LoggerModule::class, ContinueModule::class, FractionInputModule::class, + ItemSelectionInputModule::class, MultipleChoiceInputModule::class, + NumberWithUnitsRuleModule::class, NumericInputRuleModule::class, TextInputRuleModule::class, + DragDropSortInputModule::class, ImageClickInputModule::class, InteractionsModule::class, + GcsResourceModule::class, GlideImageLoaderModule::class, ImageParsingModule::class, + HtmlParserEntityTypeModule::class, QuestionModule::class, TestLogReportingModule::class, + AccessibilityTestModule::class, LogStorageModule::class, CachingTestModule::class, + PrimeTopicAssetsControllerModule::class, ExpirationMetaDataRetrieverModule::class, + ViewBindingShimModule::class, RatioInputModule::class, WorkManagerConfigurationModule::class, + ApplicationStartupListenerModule::class, LogReportWorkerModule::class, + HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class, + FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, + DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class, + ExplorationStorageModule::class, NetworkModule::class, NetworkConfigProdModule::class, + NetworkConnectionUtilDebugModule::class, NetworkConnectionDebugUtilModule::class, + AssetModule::class, LocaleProdModule::class, ActivityRecreatorTestModule::class, + NumericExpressionInputModule::class, AlgebraicExpressionInputModule::class, + MathEquationInputModule::class, SplitScreenInteractionModule::class, + LoggingIdentifierModule::class, ApplicationLifecycleModule::class, + SyncStatusModule::class, MetricLogSchedulerModule::class, TestingBuildFlavorModule::class, + EventLoggingConfigurationModule::class, ActivityRouterModule::class, + CpuPerformanceSnapshotterModule::class, ExplorationProgressModule::class + ] + ) + + interface TestApplicationComponent : ApplicationComponent { + @Component.Builder + interface Builder : ApplicationComponent.Builder + + fun inject(snackbarManagerTest: SnackbarManagerTest) + } + + class TestApplication : Application(), ActivityComponentFactory, ApplicationInjectorProvider { + private val component: TestApplicationComponent by lazy { + DaggerSnackbarManagerTest_TestApplicationComponent.builder() + .setApplication(this) + .build() as TestApplicationComponent + } + + fun inject(snackbarManagerTest: SnackbarManagerTest) { + component.inject(snackbarManagerTest) + } + + override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent { + return component.getActivityComponentBuilderProvider().get().setActivity(activity).build() + } + + override fun getApplicationInjector(): ApplicationInjector = component + } +} \ No newline at end of file From 47baaaed32963d4c04dd86a6b3a40d1be8ad5ac8 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Thu, 3 Aug 2023 16:38:11 +0530 Subject: [PATCH 23/35] added snackbarManagerTest --- .../app/settings/profile/SnackbarManager.kt | 2 +- .../settings/profile/SnackbarManagerTest.kt | 34 +++++++++++--- .../domain/snackbar/SnackbarControllerTest.kt | 46 ++++++++++++++++++- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index d58e02bbf59..d37593b83bb 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -37,7 +37,7 @@ class SnackbarManager @Inject constructor(private val snackbarController: Snackb /** * Enables the activity to show the snackbar. * - * @param activity that is to observing for a snackbar and in which the snackbar will be shown + * @param activity An activity that will observe for snackbars and display them */ fun enableShowingSnackbars(activity: AppCompatActivity) { snackbarController.getCurrentSnackbar().toLiveData().observe(activity) { result -> diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt index cf38ee567ee..8173c2bbcf6 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt @@ -3,15 +3,16 @@ package org.oppia.android.app.settings.profile import android.app.Application import android.content.Context import androidx.appcompat.app.AppCompatActivity +import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.intent.Intents import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat import dagger.Component -import javax.inject.Inject -import javax.inject.Singleton import org.hamcrest.Matchers.allOf import org.junit.After import org.junit.Before @@ -62,7 +63,6 @@ import org.oppia.android.domain.oppialogger.logscheduler.MetricLogSchedulerModul import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule import org.oppia.android.domain.platformparameter.PlatformParameterModule import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule -import androidx.test.espresso.assertion.ViewAssertions.matches import org.oppia.android.domain.question.QuestionModule import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule @@ -88,11 +88,15 @@ import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule import org.oppia.android.util.parser.image.GlideImageLoaderModule import org.oppia.android.util.parser.image.ImageParsingModule +import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode +import javax.inject.Inject +import javax.inject.Singleton /** Tests for [SnackbarManager]*/ @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) +@Config(application = SnackbarManagerTest.TestApplication::class, qualifiers = "port-xxhdpi") class SnackbarManagerTest { @get:Rule @@ -107,6 +111,9 @@ class SnackbarManagerTest { @Inject lateinit var snackbarManager: SnackbarManager + @Inject + lateinit var snackbarController: SnackbarController + @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers @@ -123,15 +130,30 @@ class SnackbarManagerTest { Intents.release() } + @Test + fun testShowSnackbarMethod_enqueuesRequestInTheRequestQueue_returns_SameMessage() { + snackbarManager.showSnackbar( + R.string.profile_edit_delete_success, + SnackbarController.SnackbarDuration.SHORT + ) + val element = snackbarController.snackbarRequestQueue.peek() + assertThat(element?.messageStringId).isEqualTo(R.string.profile_edit_delete_success) + } @Test - fun firstTest(){ - snackbarManager.showSnackbar(R.string.profile_edit_delete_success, SnackbarController.SnackbarDuration.SHORT) + fun testShowSnackbarMethod_showsSnackbarInTheActivity_IfEnableSnackbarsIsCalled() { + snackbarManager.showSnackbar( + R.string.profile_edit_delete_success, + SnackbarController.SnackbarDuration.SHORT + ) + ActivityScenario.launch(ProfileListActivity::class.java).onActivity { + snackbarManager.enableShowingSnackbars(it) + } + testCoroutineDispatchers.runCurrent() onView(allOf(withText(R.string.profile_edit_delete_success))) .check(matches(isDisplayed())) } - private fun setUpTestApplicationComponent() { ApplicationProvider.getApplicationContext().inject(this) } diff --git a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt index 93882082021..bf9733320af 100644 --- a/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/snackbar/SnackbarControllerTest.kt @@ -13,7 +13,9 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.oppia.android.testing.TestLogReportingModule +import org.oppia.android.testing.data.DataProviderTestMonitor import org.oppia.android.testing.robolectric.RobolectricModule +import org.oppia.android.testing.threading.TestCoroutineDispatchers import org.oppia.android.testing.threading.TestDispatcherModule import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.caching.AssetModule @@ -26,6 +28,7 @@ import javax.inject.Inject import javax.inject.Singleton private const val STRING_ID: Int = 1 +private const val STRING_ID_2: Int = 2 @Suppress("FunctionName", "SameParameterValue") @RunWith(AndroidJUnit4::class) @@ -36,14 +39,20 @@ class SnackbarControllerTest { @Inject lateinit var snackbarController: SnackbarController + @Inject + lateinit var dataProviderTestMonitor: DataProviderTestMonitor.Factory + + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + var request = SnackbarController.SnackbarRequest.ShowSnackbar( messageStringId = STRING_ID, duration = SnackbarController.SnackbarDuration.SHORT ) var request2 = SnackbarController.SnackbarRequest.ShowSnackbar( - messageStringId = STRING_ID, - duration = SnackbarController.SnackbarDuration.LONG + messageStringId = STRING_ID_2, + duration = SnackbarController.SnackbarDuration.SHORT ) @Before @@ -71,6 +80,39 @@ class SnackbarControllerTest { assertThat(snackbarController.snackbarRequestQueue.peek()).isEqualTo(request) } + @Test + fun testEnqueueRequest_returns_getCurrentSnackbar_success() { + snackbarController.enqueueSnackbar(request) + val monitor = dataProviderTestMonitor.createMonitor(snackbarController.getCurrentSnackbar()) + testCoroutineDispatchers.runCurrent() + monitor.ensureNextResultIsSuccess() + } + + @Test + fun testEnqueueTwoRequest_returns_firstRequest() { + snackbarController.enqueueSnackbar(request) + snackbarController.enqueueSnackbar(request2) + val result = + dataProviderTestMonitor.waitForNextSuccessfulResult(snackbarController.getCurrentSnackbar()) + testCoroutineDispatchers.runCurrent() + assertThat(result).isEqualTo(request) + } + + @Test + fun testEnqueueTwoRequest_verifyingFirst_thenDismissing_returns_secondRequest() { + snackbarController.enqueueSnackbar(request) + snackbarController.enqueueSnackbar(request2) + val result = + dataProviderTestMonitor.waitForNextSuccessfulResult(snackbarController.getCurrentSnackbar()) + testCoroutineDispatchers.runCurrent() + assertThat(result).isEqualTo(request) + snackbarController.dismissCurrentSnackbar() + val result2 = + dataProviderTestMonitor.waitForNextSuccessfulResult(snackbarController.getCurrentSnackbar()) + testCoroutineDispatchers.runCurrent() + assertThat(result2).isEqualTo(request2) + } + private fun setUpTestApplicationComponent() { ApplicationProvider.getApplicationContext().inject(this) } From 6f89a7d2cf5598499c612fc0e0440a7af79cd6a9 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Thu, 3 Aug 2023 16:41:36 +0530 Subject: [PATCH 24/35] added new line at the end --- .../oppia/android/app/settings/profile/SnackbarManagerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt index 8173c2bbcf6..3258de1fd11 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt @@ -213,4 +213,4 @@ class SnackbarManagerTest { override fun getApplicationInjector(): ApplicationInjector = component } -} \ No newline at end of file +} From 319dd8a5eaafd622fff2e8c01cb42e7bb2970702 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Fri, 4 Aug 2023 00:07:02 +0530 Subject: [PATCH 25/35] test-commit --- .../android/app/settings/profile/ProfileEditFragmentTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index fa57ebecd26..ef457a1e338 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -175,7 +175,7 @@ class ProfileEditFragmentTest { .inRoot(isDialog()) .perform(click()) testCoroutineDispatchers.runCurrent() - onView(allOf(withText(R.string.profile_edit_delete_success))) + onView(withText(R.string.profile_edit_delete_success)) .check(matches(isDisplayed())) } } From 4176ab7632d8ba155be8047fbe29a4171c14a984 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Fri, 4 Aug 2023 00:15:27 +0530 Subject: [PATCH 26/35] corrected k-doc --- .../oppia/android/app/settings/profile/SnackbarManagerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt index 3258de1fd11..39870d7395a 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/SnackbarManagerTest.kt @@ -93,7 +93,7 @@ import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton -/** Tests for [SnackbarManager]*/ +/** Test for [SnackbarManager]. */ @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) @Config(application = SnackbarManagerTest.TestApplication::class, qualifiers = "port-xxhdpi") From 821c76036d4837a2ad11d0cab2d0ff3360991c96 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Fri, 4 Aug 2023 01:44:16 +0530 Subject: [PATCH 27/35] removed coroutine disp --- .../app/settings/profile/ProfileEditFragmentTest.kt | 2 -- .../android/domain/snackbar/SnackbarController.kt | 13 +++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index ef457a1e338..39e88492198 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -174,7 +174,6 @@ class ProfileEditFragmentTest { onView(withText(R.string.profile_edit_delete_dialog_positive)) .inRoot(isDialog()) .perform(click()) - testCoroutineDispatchers.runCurrent() onView(withText(R.string.profile_edit_delete_success)) .check(matches(isDisplayed())) } @@ -188,7 +187,6 @@ class ProfileEditFragmentTest { onView(withText(R.string.profile_edit_delete_dialog_positive)) .inRoot(isDialog()) .perform(click()) - testCoroutineDispatchers.runCurrent() onView(allOf(withText(R.string.profile_edit_delete_success))) .check(matches(isDisplayed())) testCoroutineDispatchers.runCurrent() diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index eb00dab57d6..7f5f556eb02 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -39,16 +39,16 @@ class SnackbarController @Inject constructor( } /** - * Enqueue the snackbar request that is to be shown and notify subscribers that it has changed. + * Enqueue the snackbar request that is to be shown and notify subscribers that it has changed. * - * @param request that is to be added in the queue + * @param request that is to be added in the queue */ fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { _snackbarRequestQueue.add(request) notifyPotentialSnackbarChange() } - /** Dismiss the current snackbar and notify subscribers that the [DataProvider] has changed. */ + /** Dismiss the current snackbar and notify subscribers that the [DataProvider] has changed. */ fun dismissCurrentSnackbar() { _snackbarRequestQueue.remove() notifyPotentialSnackbarChange() @@ -61,10 +61,11 @@ class SnackbarController @Inject constructor( /** Sealed class that encapsulates the SnackbarRequest behaviour. */ sealed class SnackbarRequest { - /** For showing the snackbar. + /** + * For showing the snackbar. * - * @param messageStringId The message string of string resource that is to be displayed - * @param duration The duration for which snackbar is to be shown + * @param messageStringId The message string of string resource that is to be displayed + * @param duration The duration for which snackbar is to be shown */ data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : SnackbarRequest() From a226cc1ad561c79b477b9b676b2bd0142abc6293 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Fri, 4 Aug 2023 02:14:02 +0530 Subject: [PATCH 28/35] restored --- .../android/app/settings/profile/ProfileEditFragmentTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index 39e88492198..fa57ebecd26 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -174,7 +174,8 @@ class ProfileEditFragmentTest { onView(withText(R.string.profile_edit_delete_dialog_positive)) .inRoot(isDialog()) .perform(click()) - onView(withText(R.string.profile_edit_delete_success)) + testCoroutineDispatchers.runCurrent() + onView(allOf(withText(R.string.profile_edit_delete_success))) .check(matches(isDisplayed())) } } @@ -187,6 +188,7 @@ class ProfileEditFragmentTest { onView(withText(R.string.profile_edit_delete_dialog_positive)) .inRoot(isDialog()) .perform(click()) + testCoroutineDispatchers.runCurrent() onView(allOf(withText(R.string.profile_edit_delete_success))) .check(matches(isDisplayed())) testCoroutineDispatchers.runCurrent() From 7abb519af8e02f2a8a9eae631cef8c77a7a40d30 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 8 Aug 2023 19:13:36 +0530 Subject: [PATCH 29/35] corrected tests --- .../app/settings/profile/ProfileEditFragmentTest.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt index fa57ebecd26..c41f049fab6 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/settings/profile/ProfileEditFragmentTest.kt @@ -14,18 +14,19 @@ import androidx.test.espresso.intent.Intents.intended import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent import androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra import androidx.test.espresso.matcher.RootMatchers.isDialog +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isChecked import androidx.test.espresso.matcher.ViewMatchers.isClickable import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isFocusable import androidx.test.espresso.matcher.ViewMatchers.isRoot +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import dagger.Component -import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.not import org.junit.After import org.junit.Before @@ -175,8 +176,8 @@ class ProfileEditFragmentTest { .inRoot(isDialog()) .perform(click()) testCoroutineDispatchers.runCurrent() - onView(allOf(withText(R.string.profile_edit_delete_success))) - .check(matches(isDisplayed())) + onView(withText(R.string.profile_edit_delete_success)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) } } @@ -189,9 +190,6 @@ class ProfileEditFragmentTest { .inRoot(isDialog()) .perform(click()) testCoroutineDispatchers.runCurrent() - onView(allOf(withText(R.string.profile_edit_delete_success))) - .check(matches(isDisplayed())) - testCoroutineDispatchers.runCurrent() intended(hasComponent(ProfileListActivity::class.java.name)) } } From 8252511e8b965cc024cca8b2db0e1a3582998cbc Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Tue, 31 Oct 2023 22:34:50 +0530 Subject: [PATCH 30/35] started changes --- .bashrc | 0 .../profile/ProfileEditFragmentPresenter.kt | 10 +- .../app/settings/profile/SnackbarManager.kt | 124 ++++++++++-------- .../domain/snackbar/SnackbarController.kt | 72 +++++----- 4 files changed, 112 insertions(+), 94 deletions(-) create mode 100644 .bashrc diff --git a/.bashrc b/.bashrc new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index 0d2f96db083..2319b38cc92 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -7,6 +7,8 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.Observer +import com.google.common.util.concurrent.FutureCallback +import com.google.common.util.concurrent.Futures import org.oppia.android.R import org.oppia.android.app.administratorcontrols.AdministratorControlsActivity import org.oppia.android.app.administratorcontrols.ProfileEditDeletionDialogListener @@ -153,10 +155,10 @@ class ProfileEditFragmentPresenter @Inject constructor( fragment, Observer { if (it is AsyncResult.Success) { - snackbarManager.showSnackbar( - R.string.profile_edit_delete_success, - SnackbarController.SnackbarDuration.LONG - ) +// snackbarManager.showSnackbar( +// R.string.profile_edit_delete_success, +// SnackbarController.SnackbarDuration.LONG +// ) if (fragment.requireContext().resources.getBoolean(R.bool.isTablet)) { val intent = Intent(fragment.requireContext(), AdministratorControlsActivity::class.java) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index d37593b83bb..348cd558347 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -4,83 +4,93 @@ import android.view.View import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar +import com.google.common.util.concurrent.FutureCallback +import com.google.common.util.concurrent.Futures +import com.google.common.util.concurrent.Futures.immediateFuture +import com.google.common.util.concurrent.ListenableFuture +import com.google.common.util.concurrent.SettableFuture +import java.util.concurrent.Executor +import java.util.concurrent.Future import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject +import kotlinx.coroutines.Deferred +import org.oppia.android.util.data.DataProvider +import org.oppia.android.util.data.DataProviders private const val TAG = "SnackbarManager" private const val ERROR_MESSAGE = "can't be shown--no activity UI" +private const val GET_CURRENT_SNACKBAR_STATUS_PROVIDER_ID = + "get_current_snackbar_status_provider_id" + +class SnackbarManager @Inject constructor(private val activity: AppCompatActivity, private val snackbarController: SnackbarController) { + private var currentShowingSnackbarId: Int? = null + + // Must be called by activities wishing to show snackbars. + fun enableShowingSnackbars(contentView: View) { + snackbarController.getCurrentSnackbarState().toLiveData().observe(activity) { result -> + + when(result){ + is AsyncResult.Success -> when(val request = result.value) { + + is SnackbarController.CurrentSnackbarState.Showing -> { +// if (request.snackbarId != currentShowingSnackbarId){ +// snackbarController.snackbarRequestQueue.peek()?.let { showSnackbar(contentView, it) } +// } + + snackbarController.notifySnackbarShowing(request.snackbarId, ) + + } + + is SnackbarController.CurrentSnackbarState.NotShowing -> { + + } + + is SnackbarController.CurrentSnackbarState.WaitingToShow -> { -/** Manager for showing snackbars. */ -class SnackbarManager @Inject constructor(private val snackbarController: SnackbarController) { - - @Inject - lateinit var oppiaLogger: OppiaLogger - - /** - * Enqueues the snackbar that is be to shown in the FIFO buffer. - * - * @param messageStringId The message string of string resource that is to be displayed - * @param duration The duration for which snackbar is to be shown - */ - fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration) { - snackbarController.enqueueSnackbar( - SnackbarController.SnackbarRequest.ShowSnackbar( - messageStringId, - duration - ) - ) - } - /** - * Enables the activity to show the snackbar. - * - * @param activity An activity that will observe for snackbars and display them - */ - fun enableShowingSnackbars(activity: AppCompatActivity) { - snackbarController.getCurrentSnackbar().toLiveData().observe(activity) { result -> - when (result) { - is AsyncResult.Success -> when (val request = result.value) { - is SnackbarController.SnackbarRequest.ShowSnackbar -> showSnackbar( - activity.findViewById( - android.R.id.content - ), - request - ) - SnackbarController.SnackbarRequest.ShowNothing -> { - if (snackbarController.snackbarRequestQueue.isNotEmpty()) { - snackbarController.dismissCurrentSnackbar() - } } + + } + else -> { + } - else -> {} } + + // Show a new snackbar if the current state is "showing snackbar" with an ID different than currentShowingSnackbarId. + // Note that this should automatically handle the case of a new activity being opened before a previous snackbar finished (it should be reshown). + // Need to call back into SnackbarController via notifySnackbarShowing() to indicate that it's now showing. } } private fun showSnackbar( - activityView: View?, - showRequest: SnackbarController.SnackbarRequest.ShowSnackbar - ) { - + activityView: View, + showRequest: SnackbarController.ShowSnackbarRequest + ): Pair, Deferred> { val duration = when (showRequest.duration) { SnackbarController.SnackbarDuration.SHORT -> Snackbar.LENGTH_SHORT SnackbarController.SnackbarDuration.LONG -> Snackbar.LENGTH_LONG } - if (activityView == null) { - oppiaLogger.e(TAG, ERROR_MESSAGE) - } else { - Snackbar.make(activityView, showRequest.messageStringId, duration) - .addCallback(object : Snackbar.Callback() { - override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { - super.onDismissed(transientBottomBar, event) - snackbarController.dismissCurrentSnackbar() - } - }) - .show() - } + val showFuture = SettableFuture.create() + val dismissFuture = SettableFuture.create() + Snackbar.make(activityView, showRequest.messageStringId, duration) + .addCallback(object : Snackbar.Callback() { + override fun onShown(snackbar: Snackbar) { + +// snackbarController.notifySnackbarShowing() + showFuture.set(Unit) + } + + override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { + dismissFuture.set(Unit) + + } + }) + .show() + // See: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-guava/kotlinx.coroutines.guava/as-deferred.html. + return showFuture as Deferred to dismissFuture as Deferred } -} +} \ No newline at end of file diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 7f5f556eb02..9ec0cfa5945 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -1,6 +1,7 @@ package org.oppia.android.domain.snackbar import androidx.annotation.StringRes +import com.google.common.util.concurrent.SettableFuture import org.oppia.android.util.data.AsyncDataSubscriptionManager import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders @@ -8,6 +9,8 @@ import java.util.LinkedList import java.util.Queue import javax.inject.Inject import javax.inject.Singleton +import kotlinx.coroutines.Deferred +import org.oppia.android.util.data.AsyncResult private const val GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID = "get_current_snackbar_request_provider_id" @@ -19,61 +22,64 @@ class SnackbarController @Inject constructor( private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager, ) { - private val _snackbarRequestQueue: Queue = LinkedList() + private var showFuture: Deferred? = null + val dismissFuture = SettableFuture.create() + private val _snackbarRequestQueue: Queue = LinkedList() /** Queue of the snackbar requests that are to be shown based on FIFO. */ - val snackbarRequestQueue: Queue + val snackbarRequestQueue: Queue get() = _snackbarRequestQueue - /** - * Gets the snackbar that is enqueued first. - * - * @return a [DataProvider] of the current request - */ - fun getCurrentSnackbar(): DataProvider { + val currentState = CurrentSnackbarState.NotShowing + + + fun getCurrentSnackbarState(): DataProvider { + val currentRequest = _snackbarRequestQueue.peek() - return dataProviders.createInMemoryDataProvider(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID) { - return@createInMemoryDataProvider currentRequest - ?: SnackbarRequest.ShowNothing + + if (_snackbarRequestQueue.isEmpty()){ + return dataProviders.createInMemoryDataProvider(CurrentSnackbarState.NotShowing){ + return@createInMemoryDataProvider CurrentSnackbarState.NotShowing + } } + +// if () + } - /** - * Enqueue the snackbar request that is to be shown and notify subscribers that it has changed. - * - * @param request that is to be added in the queue - */ - fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar) { + fun enqueueSnackbar(request: ShowSnackbarRequest) { _snackbarRequestQueue.add(request) notifyPotentialSnackbarChange() } - /** Dismiss the current snackbar and notify subscribers that the [DataProvider] has changed. */ - fun dismissCurrentSnackbar() { - _snackbarRequestQueue.remove() - notifyPotentialSnackbarChange() + fun notifySnackbarShowing(snackbarId: Int, onShow: Deferred, onDismiss: Deferred) { + // onDismiss is resolved when the snackbar by unique ID snackbarId is no longer showing. + + showFuture = onShow + } private fun notifyPotentialSnackbarChange() { asyncDataSubscriptionManager.notifyChangeAsync(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID) } - /** Sealed class that encapsulates the SnackbarRequest behaviour. */ - sealed class SnackbarRequest { + sealed class CurrentSnackbarState { + object NotShowing : CurrentSnackbarState() - /** - * For showing the snackbar. - * - * @param messageStringId The message string of string resource that is to be displayed - * @param duration The duration for which snackbar is to be shown - */ - data class ShowSnackbar(@StringRes val messageStringId: Int, val duration: SnackbarDuration) : - SnackbarRequest() + data class Showing(val request: ShowSnackbarRequest, val snackbarId: Int) : + CurrentSnackbarState() - /** For not showing snackbar and dismissing the snackbar if present in the queue. */ - object ShowNothing : SnackbarRequest() + data class WaitingToShow(val nextRequest: ShowSnackbarRequest, val snackbarId: Int) : + CurrentSnackbarState() } + data class ShowSnackbarRequest( + @StringRes val messageStringId: Int, + val duration: SnackbarDuration + ) + + private data class Snackbar(val request: ShowSnackbarRequest, val snackbarId: Int) + /** These are for the length of the snackbar that is to be shown. */ enum class SnackbarDuration { From 34f45b142c9ed6b4182f6eae5e4228a2554bc8e3 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Fri, 10 Nov 2023 23:16:54 +0530 Subject: [PATCH 31/35] few changes --- .../app/settings/profile/SnackbarManager.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 348cd558347..0a1d11c7dc2 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -9,6 +9,7 @@ import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.Futures.immediateFuture import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture +import java.util.* import java.util.concurrent.Executor import java.util.concurrent.Future import org.oppia.android.domain.oppialogger.OppiaLogger @@ -26,7 +27,16 @@ private const val GET_CURRENT_SNACKBAR_STATUS_PROVIDER_ID = "get_current_snackbar_status_provider_id" class SnackbarManager @Inject constructor(private val activity: AppCompatActivity, private val snackbarController: SnackbarController) { - private var currentShowingSnackbarId: Int? = null + private var currentShowingSnackbarId: String? = null + + + fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration){ + currentShowingSnackbarId = UUID.randomUUID().toString() + + showSnackbar(contentView, showRequest) + + + } // Must be called by activities wishing to show snackbars. fun enableShowingSnackbars(contentView: View) { @@ -40,8 +50,6 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit // snackbarController.snackbarRequestQueue.peek()?.let { showSnackbar(contentView, it) } // } - snackbarController.notifySnackbarShowing(request.snackbarId, ) - } is SnackbarController.CurrentSnackbarState.NotShowing -> { @@ -50,12 +58,14 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit is SnackbarController.CurrentSnackbarState.WaitingToShow -> { + snackbarController.notifySnackbarShowing( } } else -> { + } } @@ -79,7 +89,6 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit Snackbar.make(activityView, showRequest.messageStringId, duration) .addCallback(object : Snackbar.Callback() { override fun onShown(snackbar: Snackbar) { - // snackbarController.notifySnackbarShowing() showFuture.set(Unit) } From fc4761784c7d52c490dcf69c8e6359bca2d2b8b8 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 29 Nov 2023 23:21:06 +0530 Subject: [PATCH 32/35] done some changes acc to gist-1 --- .../app/settings/profile/SnackbarManager.kt | 22 +++++-------------- .../domain/snackbar/SnackbarController.kt | 4 ++-- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 0a1d11c7dc2..b59b80128b6 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -29,15 +29,6 @@ private const val GET_CURRENT_SNACKBAR_STATUS_PROVIDER_ID = class SnackbarManager @Inject constructor(private val activity: AppCompatActivity, private val snackbarController: SnackbarController) { private var currentShowingSnackbarId: String? = null - - fun showSnackbar(@StringRes messageStringId: Int, duration: SnackbarController.SnackbarDuration){ - currentShowingSnackbarId = UUID.randomUUID().toString() - - showSnackbar(contentView, showRequest) - - - } - // Must be called by activities wishing to show snackbars. fun enableShowingSnackbars(contentView: View) { snackbarController.getCurrentSnackbarState().toLiveData().observe(activity) { result -> @@ -57,15 +48,13 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit } is SnackbarController.CurrentSnackbarState.WaitingToShow -> { - - snackbarController.notifySnackbarShowing( - + val showSnackbar = showSnackbar(contentView, request.nextRequest) + snackbarController.notifySnackbarShowing(request.snackbarId, showSnackbar.first, showSnackbar.second) } } else -> { - } } @@ -86,19 +75,18 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit val showFuture = SettableFuture.create() val dismissFuture = SettableFuture.create() + Snackbar.make(activityView, showRequest.messageStringId, duration) .addCallback(object : Snackbar.Callback() { override fun onShown(snackbar: Snackbar) { -// snackbarController.notifySnackbarShowing() showFuture.set(Unit) } override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { dismissFuture.set(Unit) - } - }) - .show() + }).show() + // See: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-guava/kotlinx.coroutines.guava/as-deferred.html. return showFuture as Deferred to dismissFuture as Deferred } diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 9ec0cfa5945..5ea7a13112d 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -22,7 +22,6 @@ class SnackbarController @Inject constructor( private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager, ) { - private var showFuture: Deferred? = null val dismissFuture = SettableFuture.create() private val _snackbarRequestQueue: Queue = LinkedList() @@ -54,8 +53,9 @@ class SnackbarController @Inject constructor( fun notifySnackbarShowing(snackbarId: Int, onShow: Deferred, onDismiss: Deferred) { // onDismiss is resolved when the snackbar by unique ID snackbarId is no longer showing. + CurrentSnackbarState.NotShowing - showFuture = onShow +// val showFuture = onShow.await() } From 3e7d3ced15e2e1ea9f992f13d52189b9b3b03a25 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 29 Nov 2023 23:26:48 +0530 Subject: [PATCH 33/35] done some changes acc to gist-1 --- .../profile/ProfileEditFragmentPresenter.kt | 3 -- .../app/settings/profile/SnackbarManager.kt | 34 ++++++++----------- .../domain/snackbar/SnackbarController.kt | 15 ++++---- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt index 2319b38cc92..1a8f4de364b 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt @@ -7,8 +7,6 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.Observer -import com.google.common.util.concurrent.FutureCallback -import com.google.common.util.concurrent.Futures import org.oppia.android.R import org.oppia.android.app.administratorcontrols.AdministratorControlsActivity import org.oppia.android.app.administratorcontrols.ProfileEditDeletionDialogListener @@ -18,7 +16,6 @@ import org.oppia.android.app.model.ProfileId import org.oppia.android.databinding.ProfileEditFragmentBinding import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.profile.ProfileManagementController -import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index b59b80128b6..914ae24a64f 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -1,40 +1,32 @@ package org.oppia.android.app.settings.profile import android.view.View -import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import com.google.android.material.snackbar.Snackbar -import com.google.common.util.concurrent.FutureCallback -import com.google.common.util.concurrent.Futures -import com.google.common.util.concurrent.Futures.immediateFuture -import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture -import java.util.* -import java.util.concurrent.Executor -import java.util.concurrent.Future -import org.oppia.android.domain.oppialogger.OppiaLogger +import kotlinx.coroutines.Deferred import org.oppia.android.domain.snackbar.SnackbarController import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject -import kotlinx.coroutines.Deferred -import org.oppia.android.util.data.DataProvider -import org.oppia.android.util.data.DataProviders private const val TAG = "SnackbarManager" private const val ERROR_MESSAGE = "can't be shown--no activity UI" private const val GET_CURRENT_SNACKBAR_STATUS_PROVIDER_ID = "get_current_snackbar_status_provider_id" -class SnackbarManager @Inject constructor(private val activity: AppCompatActivity, private val snackbarController: SnackbarController) { +class SnackbarManager @Inject constructor( + private val activity: AppCompatActivity, + private val snackbarController: SnackbarController +) { private var currentShowingSnackbarId: String? = null // Must be called by activities wishing to show snackbars. fun enableShowingSnackbars(contentView: View) { snackbarController.getCurrentSnackbarState().toLiveData().observe(activity) { result -> - when(result){ - is AsyncResult.Success -> when(val request = result.value) { + when (result) { + is AsyncResult.Success -> when (val request = result.value) { is SnackbarController.CurrentSnackbarState.Showing -> { // if (request.snackbarId != currentShowingSnackbarId){ @@ -49,13 +41,15 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit is SnackbarController.CurrentSnackbarState.WaitingToShow -> { val showSnackbar = showSnackbar(contentView, request.nextRequest) - snackbarController.notifySnackbarShowing(request.snackbarId, showSnackbar.first, showSnackbar.second) + snackbarController.notifySnackbarShowing( + request.snackbarId, + showSnackbar.first, + showSnackbar.second + ) } } - else -> { - - } + else -> {} } // Show a new snackbar if the current state is "showing snackbar" with an ID different than currentShowingSnackbarId. @@ -90,4 +84,4 @@ class SnackbarManager @Inject constructor(private val activity: AppCompatActivit // See: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-guava/kotlinx.coroutines.guava/as-deferred.html. return showFuture as Deferred to dismissFuture as Deferred } -} \ No newline at end of file +} diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 5ea7a13112d..9c0f8a75993 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -2,15 +2,13 @@ package org.oppia.android.domain.snackbar import androidx.annotation.StringRes import com.google.common.util.concurrent.SettableFuture -import org.oppia.android.util.data.AsyncDataSubscriptionManager -import org.oppia.android.util.data.DataProvider -import org.oppia.android.util.data.DataProviders -import java.util.LinkedList -import java.util.Queue +import java.util.* import javax.inject.Inject import javax.inject.Singleton import kotlinx.coroutines.Deferred -import org.oppia.android.util.data.AsyncResult +import org.oppia.android.util.data.AsyncDataSubscriptionManager +import org.oppia.android.util.data.DataProvider +import org.oppia.android.util.data.DataProviders private const val GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID = "get_current_snackbar_request_provider_id" @@ -31,13 +29,12 @@ class SnackbarController @Inject constructor( val currentState = CurrentSnackbarState.NotShowing - fun getCurrentSnackbarState(): DataProvider { val currentRequest = _snackbarRequestQueue.peek() - if (_snackbarRequestQueue.isEmpty()){ - return dataProviders.createInMemoryDataProvider(CurrentSnackbarState.NotShowing){ + if (_snackbarRequestQueue.isEmpty()) { + return dataProviders.createInMemoryDataProvider(CurrentSnackbarState.NotShowing) { return@createInMemoryDataProvider CurrentSnackbarState.NotShowing } } From 599af85cf8c0f67260a23dd5cee6bda07f440e77 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 29 Nov 2023 23:30:29 +0530 Subject: [PATCH 34/35] done some changes acc to gist-1 --- .../oppia/android/app/settings/profile/SnackbarManager.kt | 7 +------ .../oppia/android/domain/snackbar/SnackbarController.kt | 8 +++----- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt index 914ae24a64f..c600b80d371 100644 --- a/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt +++ b/app/src/main/java/org/oppia/android/app/settings/profile/SnackbarManager.kt @@ -32,12 +32,9 @@ class SnackbarManager @Inject constructor( // if (request.snackbarId != currentShowingSnackbarId){ // snackbarController.snackbarRequestQueue.peek()?.let { showSnackbar(contentView, it) } // } - } - is SnackbarController.CurrentSnackbarState.NotShowing -> { - - } + is SnackbarController.CurrentSnackbarState.NotShowing -> {} is SnackbarController.CurrentSnackbarState.WaitingToShow -> { val showSnackbar = showSnackbar(contentView, request.nextRequest) @@ -47,11 +44,9 @@ class SnackbarManager @Inject constructor( showSnackbar.second ) } - } else -> {} } - // Show a new snackbar if the current state is "showing snackbar" with an ID different than currentShowingSnackbarId. // Note that this should automatically handle the case of a new activity being opened before a previous snackbar finished (it should be reshown). // Need to call back into SnackbarController via notifySnackbarShowing() to indicate that it's now showing. diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 9c0f8a75993..6e6e719c844 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -2,13 +2,13 @@ package org.oppia.android.domain.snackbar import androidx.annotation.StringRes import com.google.common.util.concurrent.SettableFuture -import java.util.* -import javax.inject.Inject -import javax.inject.Singleton import kotlinx.coroutines.Deferred import org.oppia.android.util.data.AsyncDataSubscriptionManager import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders +import java.util.* +import javax.inject.Inject +import javax.inject.Singleton private const val GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID = "get_current_snackbar_request_provider_id" @@ -40,7 +40,6 @@ class SnackbarController @Inject constructor( } // if () - } fun enqueueSnackbar(request: ShowSnackbarRequest) { @@ -53,7 +52,6 @@ class SnackbarController @Inject constructor( CurrentSnackbarState.NotShowing // val showFuture = onShow.await() - } private fun notifyPotentialSnackbarChange() { From f2f1f69d3449074693cba7fb7f9314c7488bcc22 Mon Sep 17 00:00:00 2001 From: Akshat Kamboj Date: Wed, 29 Nov 2023 23:39:33 +0530 Subject: [PATCH 35/35] done some changes acc to gist-1 --- .../org/oppia/android/domain/snackbar/SnackbarController.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt index 6e6e719c844..0f8edca40f8 100644 --- a/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt +++ b/domain/src/main/java/org/oppia/android/domain/snackbar/SnackbarController.kt @@ -6,7 +6,8 @@ import kotlinx.coroutines.Deferred import org.oppia.android.util.data.AsyncDataSubscriptionManager import org.oppia.android.util.data.DataProvider import org.oppia.android.util.data.DataProviders -import java.util.* +import java.util.LinkedList +import java.util.Queue import javax.inject.Inject import javax.inject.Singleton @@ -38,8 +39,6 @@ class SnackbarController @Inject constructor( return@createInMemoryDataProvider CurrentSnackbarState.NotShowing } } - -// if () } fun enqueueSnackbar(request: ShowSnackbarRequest) {