Skip to content

Commit aeed96e

Browse files
Remove remember ViewModel (#6618)
1 parent 6473d54 commit aeed96e

74 files changed

Lines changed: 773 additions & 1521 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/CLAUDE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ User Request (UI Action)
106106
In addition to the Key Principles above, follow these rules:
107107

108108
### DO
109-
- Use `remember(viewModel)` for lambdas passed to composables
110109
- Map async results to internal actions before updating state
111110
- Inject `Clock` for time-dependent operations
112111
- Return early to reduce nesting

.claude/skills/implementing-android-code/SKILL.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ fun ExampleScreen(
148148
BitwardenTopAppBar(
149149
title = stringResource(R.string.title),
150150
navigationIcon = rememberVectorPainter(BitwardenDrawable.ic_back),
151-
onNavigationIconClick = remember(viewModel) {
152-
{ viewModel.trySendAction(ExampleAction.BackClick) }
153-
},
151+
onNavigationIconClick = { viewModel.trySendAction(ExampleAction.BackClick) },
154152
)
155153
},
156154
) {
@@ -165,7 +163,6 @@ fun ExampleScreen(
165163
- ✅ Use `hiltViewModel()` for dependency injection
166164
- ✅ Use `collectAsStateWithLifecycle()` for state (not `collectAsState()`)
167165
- ✅ Use `EventsEffect(viewModel)` for one-shot events
168-
- ✅ Use `remember(viewModel) { }` for stable callbacks to prevent recomposition
169166
- ✅ Use `Bitwarden*` prefixed components from `:ui` module
170167

171168
**State Hoisting Rules:**

.claude/skills/implementing-android-code/templates.md

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,7 @@ fun ExampleScreen(
342342
// Dialogs
343343
ExampleDialogs(
344344
dialogState = state.dialogState,
345-
onDismissRequest = remember(viewModel) {
346-
{ viewModel.trySendAction(ExampleAction.ErrorDialogDismiss) }
347-
},
345+
onDismissRequest = { viewModel.trySendAction(ExampleAction.ErrorDialogDismiss) },
348346
)
349347

350348
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
@@ -357,20 +355,14 @@ fun ExampleScreen(
357355
title = stringResource(id = BitwardenString.example),
358356
scrollBehavior = scrollBehavior,
359357
navigationIcon = rememberVectorPainter(id = BitwardenDrawable.ic_back),
360-
onNavigationIconClick = remember(viewModel) {
361-
{ viewModel.trySendAction(ExampleAction.BackClick) }
362-
},
358+
onNavigationIconClick = { viewModel.trySendAction(ExampleAction.BackClick) },
363359
)
364360
},
365361
) {
366362
ExampleScreenContent(
367363
state = state,
368-
onInputChanged = remember(viewModel) {
369-
{ viewModel.trySendAction(ExampleAction.InputChanged(it)) }
370-
},
371-
onSubmitClick = remember(viewModel) {
372-
{ viewModel.trySendAction(ExampleAction.SubmitClick) }
373-
},
364+
onInputChanged = { viewModel.trySendAction(ExampleAction.InputChanged(it)) },
365+
onSubmitClick = { viewModel.trySendAction(ExampleAction.SubmitClick) },
374366
modifier = Modifier
375367
.fillMaxSize(),
376368
)

app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupAutofillScreen.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import androidx.compose.material3.Text
1717
import androidx.compose.material3.TopAppBarDefaults
1818
import androidx.compose.runtime.Composable
1919
import androidx.compose.runtime.getValue
20-
import androidx.compose.runtime.remember
2120
import androidx.compose.ui.Alignment
2221
import androidx.compose.ui.Modifier
2322
import androidx.compose.ui.draw.clip
@@ -128,10 +127,8 @@ fun SetupAutoFillScreen(
128127
navigationIconContentDescription = stringResource(
129128
id = BitwardenString.close,
130129
),
131-
onNavigationIconClick = remember(viewModel) {
132-
{
133-
viewModel.trySendAction(SetupAutoFillAction.CloseClick)
134-
}
130+
onNavigationIconClick = {
131+
viewModel.trySendAction(SetupAutoFillAction.CloseClick)
135132
},
136133
)
137134
},

app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupBrowserAutofillScreen.kt

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import androidx.compose.material3.Text
1414
import androidx.compose.material3.TopAppBarDefaults
1515
import androidx.compose.runtime.Composable
1616
import androidx.compose.runtime.getValue
17-
import androidx.compose.runtime.remember
1817
import androidx.compose.ui.Alignment
1918
import androidx.compose.ui.Modifier
2019
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -76,11 +75,9 @@ fun SetupBrowserAutofillScreen(
7675
}
7776
SetupBrowserAutofillDialogs(
7877
dialogState = state.dialogState,
79-
onDismissDialog = remember(viewModel) {
80-
{ viewModel.trySendAction(SetupBrowserAutofillAction.DismissDialog) }
81-
},
82-
onTurnOnLaterConfirm = remember(viewModel) {
83-
{ viewModel.trySendAction(SetupBrowserAutofillAction.TurnOnLaterConfirmClick) }
78+
onDismissDialog = { viewModel.trySendAction(SetupBrowserAutofillAction.DismissDialog) },
79+
onTurnOnLaterConfirm = {
80+
viewModel.trySendAction(SetupBrowserAutofillAction.TurnOnLaterConfirmClick)
8481
},
8582
)
8683
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
@@ -104,8 +101,8 @@ fun SetupBrowserAutofillScreen(
104101
NavigationIcon(
105102
navigationIcon = rememberVectorPainter(id = BitwardenDrawable.ic_close),
106103
navigationIconContentDescription = stringResource(BitwardenString.close),
107-
onNavigationIconClick = remember(viewModel) {
108-
{ viewModel.trySendAction(SetupBrowserAutofillAction.CloseClick) }
104+
onNavigationIconClick = {
105+
viewModel.trySendAction(SetupBrowserAutofillAction.CloseClick)
109106
},
110107
)
111108
},
@@ -114,17 +111,15 @@ fun SetupBrowserAutofillScreen(
114111
) {
115112
SetupBrowserAutofillContent(
116113
state = state,
117-
onWhyIsThisStepRequiredClick = remember(viewModel) {
118-
{ viewModel.trySendAction(SetupBrowserAutofillAction.WhyIsThisStepRequiredClick) }
119-
},
120-
onBrowserClick = remember(viewModel) {
121-
{ viewModel.trySendAction(SetupBrowserAutofillAction.BrowserIntegrationClick(it)) }
114+
onWhyIsThisStepRequiredClick = {
115+
viewModel.trySendAction(SetupBrowserAutofillAction.WhyIsThisStepRequiredClick)
122116
},
123-
onContinueClick = remember(viewModel) {
124-
{ viewModel.trySendAction(SetupBrowserAutofillAction.ContinueClick) }
117+
onBrowserClick = {
118+
viewModel.trySendAction(SetupBrowserAutofillAction.BrowserIntegrationClick(it))
125119
},
126-
onTurnOnLaterClick = remember(viewModel) {
127-
{ viewModel.trySendAction(SetupBrowserAutofillAction.TurnOnLaterClick) }
120+
onContinueClick = { viewModel.trySendAction(SetupBrowserAutofillAction.ContinueClick) },
121+
onTurnOnLaterClick = {
122+
viewModel.trySendAction(SetupBrowserAutofillAction.TurnOnLaterClick)
128123
},
129124
modifier = Modifier.fillMaxSize(),
130125
)

app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupCompleteScreen.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import androidx.compose.material3.Surface
1515
import androidx.compose.material3.Text
1616
import androidx.compose.material3.TopAppBarDefaults
1717
import androidx.compose.runtime.Composable
18-
import androidx.compose.runtime.remember
1918
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
2019
import androidx.compose.ui.Modifier
2120
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -41,10 +40,8 @@ import com.bitwarden.ui.platform.theme.BitwardenTheme
4140
fun SetupCompleteScreen(
4241
viewModel: SetupCompleteViewModel = hiltViewModel(),
4342
) {
44-
val setupCompleteAction: () -> Unit = remember(viewModel) {
45-
{
46-
viewModel.trySendAction(SetupCompleteAction.CompleteSetup)
47-
}
43+
val setupCompleteAction: () -> Unit = {
44+
viewModel.trySendAction(SetupCompleteAction.CompleteSetup)
4845
}
4946

5047
// Handle system back action to complete the setup.

app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/accountsetup/SetupUnlockScreen.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ fun SetupUnlockScreen(
9393

9494
SetupUnlockScreenDialogs(
9595
dialogState = state.dialogState,
96-
onDismissRequest = remember(viewModel) {
97-
{ viewModel.trySendAction(SetupUnlockAction.DismissDialog) }
98-
},
96+
onDismissRequest = { viewModel.trySendAction(SetupUnlockAction.DismissDialog) },
9997
)
10098

10199
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
@@ -121,10 +119,8 @@ fun SetupUnlockScreen(
121119
navigationIconContentDescription = stringResource(
122120
id = BitwardenString.close,
123121
),
124-
onNavigationIconClick = remember(viewModel) {
125-
{
126-
viewModel.trySendAction(SetupUnlockAction.CloseClick)
127-
}
122+
onNavigationIconClick = {
123+
viewModel.trySendAction(SetupUnlockAction.CloseClick)
128124
},
129125
)
130126
},

app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/enterprisesignon/EnterpriseSignOnScreen.kt

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import androidx.compose.material3.TopAppBarDefaults
1414
import androidx.compose.material3.rememberTopAppBarState
1515
import androidx.compose.runtime.Composable
1616
import androidx.compose.runtime.getValue
17-
import androidx.compose.runtime.remember
1817
import androidx.compose.ui.Alignment
1918
import androidx.compose.ui.Modifier
2019
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -83,15 +82,13 @@ fun EnterpriseSignOnScreen(
8382

8483
EnterpriseSignOnDialogs(
8584
dialogState = state.dialogState,
86-
onConfirmKeyConnectorDomain = remember(viewModel) {
87-
{ viewModel.trySendAction(EnterpriseSignOnAction.ConfirmKeyConnectorDomainClick) }
85+
onConfirmKeyConnectorDomain = {
86+
viewModel.trySendAction(EnterpriseSignOnAction.ConfirmKeyConnectorDomainClick)
8887
},
89-
onDismissKeyConnectorDomain = remember(viewModel) {
90-
{ viewModel.trySendAction(EnterpriseSignOnAction.CancelKeyConnectorDomainClick) }
91-
},
92-
onDismissRequest = remember(viewModel) {
93-
{ viewModel.trySendAction(EnterpriseSignOnAction.DialogDismiss) }
88+
onDismissKeyConnectorDomain = {
89+
viewModel.trySendAction(EnterpriseSignOnAction.CancelKeyConnectorDomainClick)
9490
},
91+
onDismissRequest = { viewModel.trySendAction(EnterpriseSignOnAction.DialogDismiss) },
9592
)
9693

9794
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
@@ -105,15 +102,13 @@ fun EnterpriseSignOnScreen(
105102
scrollBehavior = scrollBehavior,
106103
navigationIcon = rememberVectorPainter(id = BitwardenDrawable.ic_close),
107104
navigationIconContentDescription = stringResource(id = BitwardenString.close),
108-
onNavigationIconClick = remember(viewModel) {
109-
{ viewModel.trySendAction(EnterpriseSignOnAction.CloseButtonClick) }
105+
onNavigationIconClick = {
106+
viewModel.trySendAction(EnterpriseSignOnAction.CloseButtonClick)
110107
},
111108
actions = {
112109
BitwardenTextButton(
113110
label = stringResource(id = BitwardenString.log_in_verb),
114-
onClick = remember(viewModel) {
115-
{ viewModel.trySendAction(EnterpriseSignOnAction.LogInClick) }
116-
},
111+
onClick = { viewModel.trySendAction(EnterpriseSignOnAction.LogInClick) },
117112
modifier = Modifier.testTag("LoginButton"),
118113
)
119114
},
@@ -122,8 +117,8 @@ fun EnterpriseSignOnScreen(
122117
) {
123118
EnterpriseSignOnScreenContent(
124119
state = state,
125-
onOrgIdentifierInputChange = remember(viewModel) {
126-
{ viewModel.trySendAction(EnterpriseSignOnAction.OrgIdentifierInputChange(it)) }
120+
onOrgIdentifierInputChange = {
121+
viewModel.trySendAction(EnterpriseSignOnAction.OrgIdentifierInputChange(it))
127122
},
128123
modifier = Modifier.fillMaxSize(),
129124
)

0 commit comments

Comments
 (0)