Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #4294: After deleting a profile deleted successfully message should be displayed #4887

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
c8b91a4
added snackbar
Akshatkamboj14 Mar 2, 2023
8257029
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Mar 2, 2023
7e57949
merged into develop
Akshatkamboj14 Mar 2, 2023
38f0f6e
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Mar 10, 2023
748d8a1
changed the timing to short
Akshatkamboj14 Mar 11, 2023
f631b95
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Mar 11, 2023
6ea61fb
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Apr 4, 2023
a5a9a56
added comments
Akshatkamboj14 Apr 4, 2023
44e9e3b
added comments
Akshatkamboj14 Apr 4, 2023
80fbab2
added comments
Akshatkamboj14 Apr 4, 2023
84ca7c6
added comments
Akshatkamboj14 Apr 4, 2023
9c687fa
Merge branch 'develop' into After-deleting-a-profile-Deleted-successf…
adhiamboperes Apr 19, 2023
824fc2d
added snackbar
Akshatkamboj14 Apr 25, 2023
0eabafe
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Apr 25, 2023
85f8dbc
added snackbar
Akshatkamboj14 Apr 25, 2023
257e961
added snackbar
Akshatkamboj14 Apr 25, 2023
8960942
added snackbar
Akshatkamboj14 Apr 25, 2023
958b911
Merge branch 'After-deleting-a-profile-Deleted-successfully-message-s…
Akshatkamboj14 Apr 26, 2023
31faaef
added snackbar-request-provider-id
Akshatkamboj14 May 3, 2023
a3a3c19
rearranged-imports
Akshatkamboj14 May 3, 2023
46b1418
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 May 3, 2023
e5f39e9
rearranged-imports
Akshatkamboj14 May 3, 2023
39740b8
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 May 14, 2023
84da79d
added test for the snackbar controller
Akshatkamboj14 May 29, 2023
2db6631
corrected import statements
Akshatkamboj14 May 29, 2023
aa06e79
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Jul 4, 2023
dbe3cc4
merged-into-develop
Akshatkamboj14 Jul 10, 2023
455edf4
added two tests
Akshatkamboj14 Jul 11, 2023
b7f1542
added the main functionality tests and some few changes
Akshatkamboj14 Jul 12, 2023
2f1c932
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Jul 12, 2023
4d8d714
removed unused import
Akshatkamboj14 Jul 12, 2023
c92ddfd
added Kdoc for the sealed class
Akshatkamboj14 Jul 13, 2023
f2f51be
corrected tests and kdocs
Akshatkamboj14 Jul 14, 2023
e02a1e1
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Jul 18, 2023
a40b2f8
corrected issues
Akshatkamboj14 Jul 18, 2023
1501043
added last
Akshatkamboj14 Jul 30, 2023
47baaae
added snackbarManagerTest
Akshatkamboj14 Aug 3, 2023
6f89a7d
added new line at the end
Akshatkamboj14 Aug 3, 2023
9aaff1e
merged into develop
Akshatkamboj14 Aug 3, 2023
f26d0e4
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Aug 3, 2023
319dd8a
test-commit
Akshatkamboj14 Aug 3, 2023
4176ab7
corrected k-doc
Akshatkamboj14 Aug 3, 2023
821c760
removed coroutine disp
Akshatkamboj14 Aug 3, 2023
a226cc1
restored
Akshatkamboj14 Aug 3, 2023
7abb519
corrected tests
Akshatkamboj14 Aug 8, 2023
5e2d339
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Aug 8, 2023
8252511
started changes
Akshatkamboj14 Oct 31, 2023
3cc76fb
merged-with-develop
Akshatkamboj14 Oct 31, 2023
34f45b1
few changes
Akshatkamboj14 Nov 10, 2023
64f48ba
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Nov 28, 2023
8430f81
Merge branch 'develop' of https://github.com/oppia/oppia-android into…
Akshatkamboj14 Nov 29, 2023
fc47617
done some changes acc to gist-1
Akshatkamboj14 Nov 29, 2023
3e7d3ce
done some changes acc to gist-1
Akshatkamboj14 Nov 29, 2023
599af85
done some changes acc to gist-1
Akshatkamboj14 Nov 29, 2023
f2f1f69
done some changes acc to gist-1
Akshatkamboj14 Nov 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
started changes
  • Loading branch information
Akshatkamboj14 committed Oct 31, 2023
commit 8252511e8b965cc024cca8b2db0e1a3582998cbc
Empty file added .bashrc
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)) {
adhiamboperes marked this conversation as resolved.
Show resolved Hide resolved
val intent =
Intent(fragment.requireContext(), AdministratorControlsActivity::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Unit>, Deferred<Unit>> {
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<Unit>()
val dismissFuture = SettableFuture.create<Unit>()
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<Unit> to dismissFuture as Deferred<Unit>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to call asDeffered() here, not cast it, e.g. showFuture.asDeferred().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BenHenning I am trying on this suggestion, but this is not working can you clarify more on this?
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to import it, e.g. import kotlinx.coroutines.asDeferred.

Copy link
Member Author

@Akshatkamboj14 Akshatkamboj14 Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BenHenning Already tried, not working
image

}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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 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"
Expand All @@ -19,61 +22,64 @@ class SnackbarController @Inject constructor(
private val asyncDataSubscriptionManager: AsyncDataSubscriptionManager,
) {

private val _snackbarRequestQueue: Queue<SnackbarRequest.ShowSnackbar> = LinkedList()
private var showFuture: Deferred<Unit>? = null
val dismissFuture = SettableFuture.create<Unit>()
private val _snackbarRequestQueue: Queue<ShowSnackbarRequest> = LinkedList()

/** Queue of the snackbar requests that are to be shown based on FIFO. */
val snackbarRequestQueue: Queue<SnackbarRequest.ShowSnackbar>
val snackbarRequestQueue: Queue<ShowSnackbarRequest>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't need to be exposed since the queue can be observed via getCurrentSnackbarState.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay got it.

get() = _snackbarRequestQueue

/**
* Gets the snackbar that is enqueued first.
*
* @return a [DataProvider] of the current request
*/
fun getCurrentSnackbar(): DataProvider<SnackbarRequest> {
val currentState = CurrentSnackbarState.NotShowing


fun getCurrentSnackbarState(): DataProvider<CurrentSnackbarState> {

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<Unit>, onDismiss: Deferred<Unit>) {
// 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 {

Expand Down