Skip to content

Commit 35a88f3

Browse files
authored
Merge pull request #21 from nativeapptemplate/extract_snackbar_message_effect
Extract SnackbarMessageEffect composable
2 parents 980e434 + 19c3729 commit 35a88f3

21 files changed

Lines changed: 143 additions & 135 deletions

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/AcceptPrivacyView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import androidx.compose.material3.SnackbarDuration
1717
import androidx.compose.material3.Text
1818
import androidx.compose.material3.TopAppBarDefaults
1919
import androidx.compose.runtime.Composable
20-
import androidx.compose.runtime.LaunchedEffect
2120
import androidx.compose.runtime.getValue
2221
import androidx.compose.ui.Alignment
2322
import androidx.compose.ui.Modifier
@@ -37,6 +36,7 @@ import com.nativeapptemplate.nativeapptemplatefree.R
3736
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
3837
import com.nativeapptemplate.nativeapptemplatefree.ui.common.MainButtonView
3938
import com.nativeapptemplate.nativeapptemplatefree.ui.common.NatAlertDialog
39+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
4040
import com.nativeapptemplate.nativeapptemplatefree.utils.Utility.restartApp
4141

4242
@Composable
@@ -46,12 +46,11 @@ fun AcceptPrivacyView(
4646
) {
4747
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
4848

49-
LaunchedEffect(uiState.message) {
50-
if (uiState.message.isNotBlank()) {
51-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
52-
viewModel.snackbarMessageShown()
53-
}
54-
}
49+
SnackbarMessageEffect(
50+
message = uiState.message,
51+
onShowSnackbar = onShowSnackbar,
52+
onMessageShown = viewModel::snackbarMessageShown,
53+
)
5554

5655
if (uiState.isUpdated) {
5756
val context = LocalContext.current

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/AcceptTermsView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import androidx.compose.material3.SnackbarDuration
1717
import androidx.compose.material3.Text
1818
import androidx.compose.material3.TopAppBarDefaults
1919
import androidx.compose.runtime.Composable
20-
import androidx.compose.runtime.LaunchedEffect
2120
import androidx.compose.runtime.getValue
2221
import androidx.compose.ui.Alignment
2322
import androidx.compose.ui.Modifier
@@ -37,6 +36,7 @@ import com.nativeapptemplate.nativeapptemplatefree.R
3736
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
3837
import com.nativeapptemplate.nativeapptemplatefree.ui.common.MainButtonView
3938
import com.nativeapptemplate.nativeapptemplatefree.ui.common.NatAlertDialog
39+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
4040
import com.nativeapptemplate.nativeapptemplatefree.utils.Utility.restartApp
4141

4242
@Composable
@@ -46,12 +46,11 @@ fun AcceptTermsView(
4646
) {
4747
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
4848

49-
LaunchedEffect(uiState.message) {
50-
if (uiState.message.isNotBlank()) {
51-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
52-
viewModel.snackbarMessageShown()
53-
}
54-
}
49+
SnackbarMessageEffect(
50+
message = uiState.message,
51+
onShowSnackbar = onShowSnackbar,
52+
onMessageShown = viewModel::snackbarMessageShown,
53+
)
5554

5655
if (uiState.isUpdated) {
5756
val context = LocalContext.current

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/ForgotPasswordView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import androidx.compose.material3.SnackbarDuration
2727
import androidx.compose.material3.Text
2828
import androidx.compose.material3.TopAppBarDefaults
2929
import androidx.compose.runtime.Composable
30-
import androidx.compose.runtime.LaunchedEffect
3130
import androidx.compose.runtime.getValue
3231
import androidx.compose.ui.Alignment
3332
import androidx.compose.ui.Modifier
@@ -41,6 +40,7 @@ import com.nativeapptemplate.nativeapptemplatefree.NatConstants
4140
import com.nativeapptemplate.nativeapptemplatefree.R
4241
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
4342
import com.nativeapptemplate.nativeapptemplatefree.ui.common.NatAlertDialog
43+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
4444

4545
@Composable
4646
fun ForgotPasswordView(
@@ -50,12 +50,11 @@ fun ForgotPasswordView(
5050
) {
5151
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
5252

53-
LaunchedEffect(uiState.message) {
54-
if (uiState.message.isNotBlank()) {
55-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
56-
viewModel.snackbarMessageShown()
57-
}
58-
}
53+
SnackbarMessageEffect(
54+
message = uiState.message,
55+
onShowSnackbar = onShowSnackbar,
56+
onMessageShown = viewModel::snackbarMessageShown,
57+
)
5958

6059
if (uiState.isSent) {
6160
NatAlertDialog(

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/ResendConfirmationInstructionsView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import androidx.compose.material3.SnackbarDuration
2727
import androidx.compose.material3.Text
2828
import androidx.compose.material3.TopAppBarDefaults
2929
import androidx.compose.runtime.Composable
30-
import androidx.compose.runtime.LaunchedEffect
3130
import androidx.compose.runtime.getValue
3231
import androidx.compose.ui.Alignment
3332
import androidx.compose.ui.Modifier
@@ -41,6 +40,7 @@ import com.nativeapptemplate.nativeapptemplatefree.NatConstants
4140
import com.nativeapptemplate.nativeapptemplatefree.R
4241
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
4342
import com.nativeapptemplate.nativeapptemplatefree.ui.common.NatAlertDialog
43+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
4444

4545
@Composable
4646
fun ResendConfirmationInstructionsView(
@@ -50,12 +50,11 @@ fun ResendConfirmationInstructionsView(
5050
) {
5151
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
5252

53-
LaunchedEffect(uiState.message) {
54-
if (uiState.message.isNotBlank()) {
55-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
56-
viewModel.snackbarMessageShown()
57-
}
58-
}
53+
SnackbarMessageEffect(
54+
message = uiState.message,
55+
onShowSnackbar = onShowSnackbar,
56+
onMessageShown = viewModel::snackbarMessageShown,
57+
)
5958

6059
if (uiState.isSent) {
6160
NatAlertDialog(

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/SignInEmailAndPasswordView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import androidx.compose.material3.SnackbarDuration
2525
import androidx.compose.material3.Text
2626
import androidx.compose.material3.TopAppBarDefaults
2727
import androidx.compose.runtime.Composable
28-
import androidx.compose.runtime.LaunchedEffect
2928
import androidx.compose.runtime.getValue
3029
import androidx.compose.runtime.mutableStateOf
3130
import androidx.compose.runtime.saveable.rememberSaveable
@@ -44,6 +43,7 @@ import com.nativeapptemplate.nativeapptemplatefree.NatConstants
4443
import com.nativeapptemplate.nativeapptemplatefree.R
4544
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
4645
import com.nativeapptemplate.nativeapptemplatefree.ui.common.MainButtonView
46+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
4747

4848
@Composable
4949
fun SignInEmailAndPasswordView(
@@ -117,12 +117,11 @@ fun SignInEmailAndPasswordContentView(
117117
) {
118118
var passwordVisible by rememberSaveable { mutableStateOf(false) }
119119

120-
LaunchedEffect(uiState.message) {
121-
if (uiState.message.isNotBlank()) {
122-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
123-
viewModel.snackbarMessageShown()
124-
}
125-
}
120+
SnackbarMessageEffect(
121+
message = uiState.message,
122+
onShowSnackbar = onShowSnackbar,
123+
onMessageShown = viewModel::snackbarMessageShown,
124+
)
126125

127126
Scaffold(
128127
topBar = {

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/SignUpView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import androidx.compose.material3.Text
3434
import androidx.compose.material3.TextField
3535
import androidx.compose.material3.TopAppBarDefaults
3636
import androidx.compose.runtime.Composable
37-
import androidx.compose.runtime.LaunchedEffect
3837
import androidx.compose.runtime.getValue
3938
import androidx.compose.runtime.mutableStateOf
4039
import androidx.compose.runtime.remember
@@ -55,6 +54,7 @@ import com.nativeapptemplate.nativeapptemplatefree.R
5554
import com.nativeapptemplate.nativeapptemplatefree.model.TimeZones
5655
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
5756
import com.nativeapptemplate.nativeapptemplatefree.ui.common.NatAlertDialog
57+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
5858

5959
@Composable
6060
fun SignUpView(
@@ -64,12 +64,11 @@ fun SignUpView(
6464
) {
6565
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
6666

67-
LaunchedEffect(uiState.message) {
68-
if (uiState.message.isNotBlank()) {
69-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
70-
viewModel.snackbarMessageShown()
71-
}
72-
}
67+
SnackbarMessageEffect(
68+
message = uiState.message,
69+
onShowSnackbar = onShowSnackbar,
70+
onMessageShown = viewModel::snackbarMessageShown,
71+
)
7372

7473
if (uiState.isCreated) {
7574
NatAlertDialog(
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.nativeapptemplate.nativeapptemplatefree.ui.common
2+
3+
import androidx.compose.material3.SnackbarDuration
4+
import androidx.compose.runtime.Composable
5+
import androidx.compose.runtime.LaunchedEffect
6+
7+
/**
8+
* Composable that displays a snackbar when [message] is non-blank,
9+
* then notifies the caller so it can clear the message from state.
10+
*/
11+
@Composable
12+
fun SnackbarMessageEffect(
13+
message: String,
14+
onShowSnackbar: suspend (String, String?, SnackbarDuration) -> Boolean,
15+
onMessageShown: () -> Unit,
16+
) {
17+
LaunchedEffect(message) {
18+
if (message.isNotBlank()) {
19+
onShowSnackbar(message, "dismiss", SnackbarDuration.Indefinite)
20+
onMessageShown()
21+
}
22+
}
23+
}

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/scan/ScanView.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import com.nativeapptemplate.nativeapptemplatefree.ui.common.ErrorView
5050
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
5151
import com.nativeapptemplate.nativeapptemplatefree.ui.common.MainButtonView
5252
import com.nativeapptemplate.nativeapptemplatefree.ui.common.NonScaledSp.nonScaledSp
53+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
5354
import kotlinx.coroutines.launch
5455

5556
enum class ScanPage(
@@ -74,12 +75,11 @@ internal fun ScanView(
7475
viewModel.reload()
7576
}
7677

77-
LaunchedEffect(uiState.message) {
78-
if (uiState.message.isNotBlank()) {
79-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
80-
viewModel.snackbarMessageShown()
81-
}
82-
}
78+
SnackbarMessageEffect(
79+
message = uiState.message,
80+
onShowSnackbar = onShowSnackbar,
81+
onMessageShown = viewModel::snackbarMessageShown,
82+
)
8383

8484
LaunchedEffect(uiState.userData.shouldFetchItemTagForShowTagInfoScan) {
8585
if (uiState.userData.shouldFetchItemTagForShowTagInfoScan) {

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/settings/PasswordEditView.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
4747
import com.nativeapptemplate.nativeapptemplatefree.NatConstants
4848
import com.nativeapptemplate.nativeapptemplatefree.R
4949
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
50+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
5051

5152
@Composable
5253
fun PasswordEditView(
@@ -57,12 +58,11 @@ fun PasswordEditView(
5758
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
5859
val passwordUpdatedMessage = stringResource(R.string.message_password_updated)
5960

60-
LaunchedEffect(uiState.message) {
61-
if (uiState.message.isNotBlank()) {
62-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
63-
viewModel.snackbarMessageShown()
64-
}
65-
}
61+
SnackbarMessageEffect(
62+
message = uiState.message,
63+
onShowSnackbar = onShowSnackbar,
64+
onMessageShown = viewModel::snackbarMessageShown,
65+
)
6666

6767
LaunchedEffect(uiState.isUpdated) {
6868
if (uiState.isUpdated) {

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/settings/SettingsView.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import androidx.compose.material3.SnackbarDuration
3131
import androidx.compose.material3.Text
3232
import androidx.compose.material3.TopAppBarDefaults
3333
import androidx.compose.runtime.Composable
34-
import androidx.compose.runtime.LaunchedEffect
3534
import androidx.compose.runtime.getValue
3635
import androidx.compose.runtime.mutableStateOf
3736
import androidx.compose.runtime.saveable.rememberSaveable
@@ -52,6 +51,7 @@ import com.nativeapptemplate.nativeapptemplatefree.model.DarkThemeConfig
5251
import com.nativeapptemplate.nativeapptemplatefree.ui.common.ErrorView
5352
import com.nativeapptemplate.nativeapptemplatefree.ui.common.LoadingView
5453
import com.nativeapptemplate.nativeapptemplatefree.ui.common.MainButtonView
54+
import com.nativeapptemplate.nativeapptemplatefree.ui.common.SnackbarMessageEffect
5555
import com.nativeapptemplate.nativeapptemplatefree.utils.Utility
5656

5757
@Composable
@@ -67,12 +67,11 @@ internal fun SettingsView(
6767
viewModel.reload()
6868
}
6969

70-
LaunchedEffect(uiState.message) {
71-
if (uiState.message.isNotBlank()) {
72-
onShowSnackbar(uiState.message, "dismiss", SnackbarDuration.Indefinite)
73-
viewModel.snackbarMessageShown()
74-
}
75-
}
70+
SnackbarMessageEffect(
71+
message = uiState.message,
72+
onShowSnackbar = onShowSnackbar,
73+
onMessageShown = viewModel::snackbarMessageShown,
74+
)
7675

7776
SettingsView(
7877
viewModel = viewModel,

0 commit comments

Comments
 (0)