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

[PM-8217] New device notice email access UI #4400

Merged
merged 16 commits into from
Dec 20, 2024

Conversation

andrebispo5
Copy link
Contributor

@andrebispo5 andrebispo5 commented Dec 2, 2024

🎟️ Tracking

PM-8217 Add notice to users with no 2FA

📔 Objective

Add first screen for the notice to users with no 2FA

📸 Screenshots

image image

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed
    issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

Copy link
Contributor

github-actions bot commented Dec 2, 2024

Logo
Checkmarx One – Scan Summary & Details63968bae-d75e-4943-a20c-8d4976465352

No New Or Fixed Issues Found

Copy link

codecov bot commented Dec 2, 2024

Codecov Report

Attention: Patch coverage is 93.69369% with 7 lines in your changes missing coverage. Please review.

Project coverage is 88.92%. Comparing base (e2b93ec) to head (0bb3a1c).
Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
...ewdevicenotice/NewDeviceNoticeEmailAccessScreen.kt 95.45% 2 Missing and 2 partials ⚠️
...evicenotice/NewDeviceNoticeEmailAccessViewModel.kt 85.71% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           main    #4400       +/-   ##
=========================================
+ Coverage      0   88.92%   +88.92%     
=========================================
  Files         0      457      +457     
  Lines         0    39668    +39668     
  Branches      0     5610     +5610     
=========================================
+ Hits          0    35276    +35276     
- Misses        0     2432     +2432     
- Partials      0     1960     +1960     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

* The top level composable for the new device notice email access screen.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Suppress("LongMethod")
Copy link
Collaborator

Choose a reason for hiding this comment

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

This does not look like the method is too long

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right

BitwardenScaffold(
modifier = Modifier
.fillMaxSize()
.nestedScroll(scrollBehavior.nestedScrollConnection),
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no toolbar, do we need this at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removing it

private fun MainContent(
email: String,
isEmailAccessEnabled: Boolean = false,
onEmailAccessToggleChanged: (Boolean) -> Unit = {},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do these have default values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just left them after a layout rework. Removing them.

isEmailAccessEnabled: Boolean = false,
onEmailAccessToggleChanged: (Boolean) -> Unit = {},
) {
Spacer(modifier = Modifier.size(24.dp))
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can just be height, not size

* The main content of the screen.
*/
@Composable
private fun MainContent(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this does not have a wrapping contain with a modifier, I believe the pattern requires us to scope the function to provide that extra context.

private fun ColumnScope.MainContent(

.padding(horizontal = 22.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(size = 4.dp))
.background(BitwardenTheme.colorScheme.background.secondary),
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should not be using custom stuff like this, we already have BitwardenContentCard to handle stuff like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The BitwardenContentCard didn't seem to adapt to what I wanted.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That seems to indicate that the UI is non-standard, I don't think we should be doing that.

@david-livefront
Copy link
Collaborator

@andrebispo5 Could you link the Figma files for this?

This does not seem to match current design patterns used in the app.


private fun handleEmailAccessToggle(action: EmailAccessToggle) {
mutableStateFlow.update {
it.copy(isEmailAccessEnabled = action.newState)
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the intended purpose of the switch?

Do we not send the code if they do not have access to their email?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the user has access to the email we can dismiss this flow.

Image(
painter = rememberVectorPainter(id = R.drawable.warning),
contentDescription = null,
modifier = Modifier.size(120.dp),
modifier = modifier.size(120.dp),
Copy link
Collaborator

Choose a reason for hiding this comment

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

The Modifier should only ever be applied to the top level component, if you wanted to pass one in like this, you would want to wrap it in a column.

onEmailAccessToggleChanged: (Boolean) -> Unit = {},
onContinueClick: () -> Unit = {},
) {
Column(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since you went the route of adding a top-level column, be sure to pass in a modifier.

We also do not need default params for the onEmailAccessToggleChanged and onContinueClick

) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.padding(horizontal = 24.dp),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this using a non-standard amount of padding?

Can we discuss this with design because this screen is going to be difficult to maintain since it uses so many non-standard design patterns.

@andrebispo5
Copy link
Contributor Author

@david-livefront Layout was updated to reflect the new designs.

/**
* Header content containing the warning icon and title.
*/

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change

}
},
onContinueClick = { viewModel.trySendAction(ContinueClick) },
modifier = Modifier,
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't necessary since there's a default Modifier declared.

/**
* User tapped the email access toggle.
*/
data class EmailAccessToggle(val newState: Boolean) : NewDeviceNoticeEmailAccessAction()
Copy link
Contributor

Choose a reason for hiding this comment

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

⛏️ isEnabled reads better. Not a blocker though. Just my OCD flaring up. 😆

/**
* Manages application state for the new device notice email access screen.
*/
@Suppress("TooManyFunctions")
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is needed. There are only a handful of functions. 🤔

email = email,
isEmailAccessEnabled = isEmailAccessEnabled,
onEmailAccessToggleChanged = onEmailAccessToggleChanged,
modifier = Modifier,
Copy link
Contributor

Choose a reason for hiding this comment

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

Not needed since the same default Modifier is declared in the function signature.

Comment on lines 113 to 115
private fun HeaderContent(
modifier: Modifier = Modifier,
) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🎨 If you scope this it will inherit the modifier and other context from its parent Column scope. That would mean you don't need a wrapping Column within HeaderContent to set the modifier and horizontalAlignment. It would look like...

fun NewDeviceNoticeEmailAccessContent(...) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = modifier
            .standardHorizontalMargin()
            .fillMaxSize()
            .verticalScroll(state = rememberScrollState()),
    ) {
        Spacer(...)
        HeaderContent()
        // other components
    }
}

private fun ColumnScope.HeaderContent() {
    Image(...)
    Spacer(...)
    // other components
} 

This works because HeaderContent is using the same modifier and horizontalAlignment from the parent Column scope. It doesn't work quite as cleanly for MainContent because you're not using the same horizontal alignment as its parent Column scope.

Consider this more of a FYI than an actual change request since there's nothing technically wrong with the way you've done it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh I got it and thanks for the explanation, it makes sense specially the part that it's the same as the parent. I'll change it since it clears a lot of unnecessary code lines 👍

@andrebispo5 andrebispo5 added this pull request to the merge queue Dec 20, 2024
Merged via the queue into main with commit a793941 Dec 20, 2024
8 of 9 checks passed
@andrebispo5 andrebispo5 deleted the pm-8217/new-device-notice-ui branch December 20, 2024 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants