-
Notifications
You must be signed in to change notification settings - Fork 523
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
Conversation
… After-deleting-a-profile-Deleted-successfully-message-should-be-displayed
Hey @BenHenning, Can you take a first pass at this and let me know if there are corrections to be made? after that i will proceed to add tests for this. Thanks. |
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
… After-deleting-a-profile-Deleted-successfully-message-should-be-displayed
… After-deleting-a-profile-Deleted-successfully-message-should-be-displayed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Akshatkamboj14. Sorry for the review delay here.
I think from a UX perspective that we actually want to route back and show the snackbar simultaneously (otherwise, the user could still interact with the profile after it's been deleted which could result in problems & user confusion).
I think this will require introducing some sort of general-purpose SnackbarManager
class which can show snackbars irrespective of the current activity showing. E.g. something with an API like:
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: SnackbarDuration) {
// Enqueue snackbar using SnackbarController...
}
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...
}
}
}
private fun showSnackbar(activityView: View?, showRequest: SnackbarController.SnackbarRequest.ShowSnackbar) {
if (activityView == null) {
// ...log an error if activityView is null and ignore the snackbar request (can't be shown--no activity UI).
return
}
// ...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).
Snackbar.make(activityView, messageString, length)
// ...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
}
}
with a controller to store the actual snackbar state:
@Singleton
class SnackbarController @Inject constructor() {
// The class should have a queue of snackbars.
fun getCurrentSnackbar(): DataProvider<SnackbarRequest>
fun enqueueSnackbar(request: SnackbarRequest.ShowSnackbar)
fun dismissCurrentSnackbar()
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
}
}
app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/oppia/android/app/settings/profile/ProfileEditFragmentPresenter.kt
Outdated
Show resolved
Hide resolved
Hey @BenHenning Sorry for late reply as i have exams i was unable to update on this?.. I have a question can you explain a bit more on this |
From the video you have in the PR description, the current behavior seems to be that app won't navigate away from the "profile edit screen" until after the snackbar's "ok" button is shown (allowing the user to still interact with parts of the UI). We should be navigating the user back to the profile list and then showing the snackbar after deletion confirmation. Does that help clarify? |
Ya sure @BenHenning Thanks for the Clarification. |
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
… After-deleting-a-profile-Deleted-successfully-message-should-be-displayed
Hey @BenHenning, I have pushed some sample code(not completed) |
Unassigning @Akshatkamboj14 since a re-review was requested. @Akshatkamboj14, please make sure you have addressed all review comments. Thanks! |
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Akshatkamboj14. Which parts do you need clarification on?
I took a pass on the manager & controller and left a few follow-up comments. I think a good next step would be to focus on getting tests working for the controller to verify that it works in all the cases expected, then do the same with the manager (since the manager depends on the controller). Once both those test suites are done and showing that the respective classes are working, you should be able to hook into the manager and manually test that it's showing correctly (otherwise the manager/controller implementations & tests will need revision).
}).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> |
There was a problem hiding this comment.
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()
.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
private val _snackbarRequestQueue: Queue<ShowSnackbarRequest> = LinkedList() | ||
|
||
/** Queue of the snackbar requests that are to be shown based on FIFO. */ | ||
val snackbarRequestQueue: Queue<ShowSnackbarRequest> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay got it.
// onDismiss is resolved when the snackbar by unique ID snackbarId is no longer showing. | ||
CurrentSnackbarState.NotShowing | ||
|
||
// val showFuture = onShow.await() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we need for onShow to finish before we can actually change the snackbar to be shown. We also need to observe onDismiss so that we know when to remove the snackbar from the queue. Something like:
CoroutineScope(backgroundDispatcher).launch {
onShow.await()
// TODO: Move to helper.
val queueFrontWhenShown = snackbarQueue.peek()
check(queueFrontWhenShown is CurrentSnackbarState.WaitingToShow)
check(queueFrontWhenShown.snackbarId == snackbarId)
snackbarQueue.removeFirst()
snackbarQueue.pushFirst(CurrentSnackbarState.Showing(queueFrontWhenShown.request, snackbarId))
asyncDataSubscriptionManager.notifyChange(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID)
onDismiss.await()
// TODO: Move to helper.
val queueFrontWhenDismissed = snackbarQueue.peek()
check(queueFrontWhenDismissed is CurrentSnackbarState.Showing)
check(queueFrontWhenDismissed.snackbarId == snackbarId)
snackbarQueue.removeFirst()
asyncDataSubscriptionManager.notifyChange(GET_CURRENT_SNACKBAR_REQUEST_PROVIDER_ID)
}.invokeOnCompletion {
// Log error if it != null.
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BenHenning when on this line snackbarQueue.pushFirst(CurrentSnackbarState.Showing(queueFrontWhenShown.request, snackbarId))
actually, this is not compatible as snackbarRequestQueue is of type ShowSnackbarRequest
and we can't add CurrentSnackbarState
, can you PTAL?
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
Hi @Akshatkamboj14, I'm going to mark this PR as stale because it hasn't had any updates for 7 days. If no further activity occurs within 7 days, it will be automatically closed so that others can take up the issue. |
Explanation
Fixes #4294
Essential Checklist
For UI-specific PRs only
If your PR includes UI-related changes, then:
snackbar.webm