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

QuickEditor: No avatar seleted alert banner #458

Merged
merged 5 commits into from
Nov 28, 2024

Conversation

hamorillo
Copy link
Contributor

@hamorillo hamorillo commented Nov 22, 2024

Closes #443

Description

This PR adds an informative banner to encourage users to select an avatar instead of using the default one. Per the definition, the banner should be dismissable but must reappear if the condition occurs again. (Ex: selecting an avatar and deleting it).

Kapture.2024-11-22.at.13.24.53.mp4

Testing Steps

Note: As the deletion flow is not working yet in the SDK, you'll need a browser to remove the selected avatar.

  1. Using an account without a selected avatar, open the QE.
  2. Verify you can see the alert banner
  3. Tap in the X to dismiss the banner
  4. Verify the banner is dismissed
  5. Close the QE and open it again
  6. Verify the banner is visible again
  7. Upload a new image
  8. Verify the banner disappears.
  9. Close the QE
  10. Using the browser, remove the last uploaded (and selected) avatar
  11. Open the QE and select any of the already uploaded avatars
  12. Verify the banner disappears.

Please verify the UI in both light and dark themes.

@hamorillo hamorillo added new feature New feature [Feature] Gravatar-Quickeditor Gravatar Quick Editor module labels Nov 22, 2024
@hamorillo hamorillo added this to the 2.2.0 milestone Nov 22, 2024
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Nov 22, 2024

📲 You can test the changes from this Pull Request in Gravatar Demo by scanning the QR code below to install the corresponding build.
App Name Gravatar Demo
Commitff1e338
Direct Downloadgravatar-demo-prototype-build-pr458-ff1e338.apk

@hamorillo hamorillo marked this pull request as ready for review November 22, 2024 12:45
Comment on lines 152 to 156
var nonSelectedAvatarAlertVisible by rememberSaveable { mutableStateOf(uiState.showNonSelectedAvatarAlert) }

LaunchedEffect(uiState.showNonSelectedAvatarAlert) {
nonSelectedAvatarAlertVisible = uiState.showNonSelectedAvatarAlert
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you mind explaining why we need this? I believe this is done so that the banner reappears when the state changes in the ViewModel. Is that it?

I'm worried though, that we now have UI state in two places and we should avoid that.

Would it be possible to keep the state fully in ViewModel (including the dismissed state)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing this out. 🙇 I agree that the approach wasn't correct. I've refactored it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks better now! I'm worried about the current logic though. Considering a scenario like this:

  1. User deletes the currently selected Avatar
  2. Alert banner appears
  3. User dismisses the banner
  4. User tries to delete another avatar, but the request fails
  5. Alert banner reappears -- this shouldn't happen
  6. User dismisses the banner
  7. User tries to delete another avatar again, this time successfully
  8. Alert banner reappears -- this shouldn't happen

Here's the recording showing alert banner reappearing:

banner_reappears.mp4

I do believe we should respect the user's action to dismiss the banner for longer. I would propose to reset that user action only if the user went from avatar selected to no avatar state. Here's an updated scenario where the alert banner would reappear:

  1. User deletes the currently selected Avatar
  2. Alert banner appears
  3. User dismisses the banner
  4. User tries to delete another avatar, but the request fails
  5. Alert banner DOESN'T reappear
  6. User tries to delete another avatar again, this time successfully
  7. Alert banner DOESN'T reappear
  8. User selects an avatar
  9. User deletes the currently selected Avatar
  10. Alert banner appears - Only here

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It makes sense. I've refactored that and added DeleteAvatarAlertStatus to make it clearer the current status of the AlertBanner.

Copy link
Contributor

@AdamGrzybkowski AdamGrzybkowski Nov 27, 2024

Choose a reason for hiding this comment

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

The behavior looks good now!

💡 💡 💡 💡

I do feel like we could simply the implementation and make it more future proof though.

The Alert banner visibility is defined by two values isAvatarSelected (emailAvatars.selectedAvatarId == null) and isBannerDismissed.
The visibility condition would look like this: banner.visible = !isAvatarSelected && !isBannerDismissed

The first value isAvatarSelected is already in the UI state so technically we don't need to do anything extra here.
The second one isBannerDissmed should change based on the behavior in two places:

  1. When the users dismisses it manually it should be set to true
  2. When the isAvatarSelected changes from true to false it should be reset to false

Point 1 is already handled in your implementation. Point 2 is to, kinda, but manually in each potential place where the emailAvatars.selectedAvatarId value could change. This is where I think we might end up with some bugs in the future as we could simply forget to update it in new places.

As I mentioned above we already have the emailAvatars.selectedAvatarId in the UI state so we could simply observe it and react when the value changes. Here's an example code:

_uiState
            .filter { it.emailAvatars != null } //We don't care about this until we get this value
            .map { it.emailAvatars?.selectedAvatarId != null }
            .distinctUntilChanged()
            .onEach { isAvatarSelected ->
                if (isAvatarSelected) {
                    _uiState.update { currentState ->
                        currentState.copy(
                            nonSelectedAvatarAlertVisible = DeleteAvatarAlertStatus.HIDDEN,
                        )
                    }
                } else {
                    _uiState.update { currentState ->
                        currentState.copy(
                            nonSelectedAvatarAlertVisible = DeleteAvatarAlertStatus.VISIBLE,
                        )
                    }
                }
            }
            .launchIn(viewModelScope)

I've used DeleteAvatarAlertStatus from your implementation but not sure we need it.

With the above code, we can get rid of the shouldShowNonSelectedAvatarAlert() function completely and the isBannerDismissed should be properly reset whenever the emailAvatars.selectedAvatarId value changes no matter what triggered it.

Sorry, for not catching this earlier, but I was focused on the behavior rather than the code! Let me know what you think!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was looking for a similar approach, but I couldn't come up with anything. Looks like I could have been more inspired.

I've updated the code, removing the DeleteAvatarAlertStatus, which is totally unnecessary right now, and observing the flow to update the nonSelectedAvatarAlertVisible, as you suggested.

Thanks for your review, @AdamGrzybkowski, I really appreciate it. I hope it looks better now.

@@ -197,6 +204,13 @@ internal fun AvatarPicker(uiState: AvatarPickerUiState, onEvent: (AvatarPickerEv
.fillMaxWidth()
.padding(bottom = 10.dp),
)
AnimatedVisibility(nonSelectedAvatarAlertVisible) {
Copy link
Contributor

@AdamGrzybkowski AdamGrzybkowski Nov 22, 2024

Choose a reason for hiding this comment

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

I wonder if we could customize this animation. Currently when this banner gets hidden the whole UI is moved up, rather than the top of the bottom sheet just going down. Feels unnatural.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've been playing with the AnimatedVisibility params and options. It's not easy to achieve, or at least it's not pretty straightforward.

I agree it's nice to have, but I don't want to dedicate too much time to this now. What do you think about creating a ticket and returning to it when we have more "free time"?

The UI State for the non selected avatar banner was wrongly split in two different places, the viewModel and the composable.

The ViewModel should be the only source of thrust, so moving all the state there.
Copy link
Contributor

@AdamGrzybkowski AdamGrzybkowski left a comment

Choose a reason for hiding this comment

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

Thanks for all the updates @hamorillo!! Looks good now 🎉

I believe, we need to switch the target branch, as this won't make it into 2.2.0, right?

@hamorillo hamorillo changed the base branch from trunk to release/2.3.0 November 27, 2024 11:49
@hamorillo
Copy link
Contributor Author

hamorillo commented Nov 27, 2024

we need to switch the target branch, as this won't make it into 2.2.0, right?

Yeah, as we've discussed, this should be in 2.3.0. I've created release/2.3.0 from trunk and switched the target.

@hamorillo hamorillo merged commit b8591ad into release/2.3.0 Nov 28, 2024
17 checks passed
@hamorillo hamorillo deleted the hamorillo/443-no-avatar-alert branch November 28, 2024 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Gravatar-Quickeditor Gravatar Quick Editor module new feature New feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

QuickEditor: Warning when there is not avatar selected
3 participants