Repository: android/compose-samples
File: Jetsnack/app/src/main/java/com/example/jetsnack/ui/JetsnackApp.kt (Kotlin)

Code before:
                        hostState = it,
                        modifier = Modifier.systemBarsPadding(),
                        snackbar = { snackbarData -> JetsnackSnackbar(snackbarData) }
                    )
                },
                scaffoldState = scaffoldState
            ) { innerPaddingModifier ->
                JetsnackNavGraph(
                    navController = navController,
                    modifier = Modifier.padding(innerPaddingModifier)
                )
            }

            // Handle Snackbar messages
            val currentMessages by SnackbarManager.messages.collectAsState()
            if (currentMessages.isNotEmpty()) {
                val message = currentMessages[0]
                val messageText: String = stringResource(message.messageId)

                // Effect running in a coroutine that displays the Snackbar on the screen
                // If there's a change to messageText, SnackbarManager, or scaffoldState, the
                // previous effect will be cancelled and a new one will start with the new values
                LaunchedEffect(messageText, SnackbarManager, scaffoldState) {
                    scaffoldState.snackbarHostState.showSnackbar(messageText)
                    // Once the message is displayed and dismissed, notify the ViewModel
                    SnackbarManager.setMessageShown(message.id)
                }
            }
        }
    }
}


Review comment (suggestion):
Can you add a comment to explain that this call blocks (within the coroutine) until the Snackbar gets dismissed (either by the user or by the timeout). This is not really clear when reading this code, so it looks as though the ViewModel is directly notified when the snackbar starts showing.

Code after:
                        hostState = it,
                        modifier = Modifier.systemBarsPadding(),
                        snackbar = { snackbarData -> JetsnackSnackbar(snackbarData) }
                    )
                },
                scaffoldState = scaffoldState
            ) { innerPaddingModifier ->
                JetsnackNavGraph(
                    navController = navController,
                    modifier = Modifier.padding(innerPaddingModifier)
                )
            }

            // Handle Snackbar messages
            val currentMessages by SnackbarManager.messages.collectAsState()
            if (currentMessages.isNotEmpty()) {
                val message = currentMessages[0]
                val messageText: String = stringResource(message.messageId)

                // Effect running in a coroutine that displays the Snackbar on the screen
                // If there's a change to messageText, SnackbarManager, or scaffoldState, the
                // previous effect will be cancelled and a new one will start with the new values
                LaunchedEffect(messageText, SnackbarManager, scaffoldState) {
                    // Display the snackbar on the screen. `showSnackbar` is a function
                    // that suspends until the snackbar disappears from the screen
                    scaffoldState.snackbarHostState.showSnackbar(messageText)
                    // Once the snackbar is gone or dismissed, notify the SnackbarManager
                    SnackbarManager.setMessageShown(message.id)
                }
            }
        }
    }
}