Skip to content

Instantly share code, notes, and snippets.

@takahirom
Created June 2, 2022 23:41
Show Gist options
  • Save takahirom/980d7be8a702ac10c74d5544d69de7ed to your computer and use it in GitHub Desktop.
Save takahirom/980d7be8a702ac10c74d5544d69de7ed to your computer and use it in GitHub Desktop.
One-off event for snackbar message
// ---- User side (Write every time) ----
val scaffoldState = rememberScaffoldState()
val viewModel = hiltViewModel<FooViewModel>()
SnackbarMessageEffect(
scaffoldState = scaffoldState,
messageStateHolder = viewModel
)
Scaffold(scaffoldState = scaffoldState) {
...
}
@HiltViewModel
class FooViewModel @Inject constructor(
private val repository: Repository,
private val messageStateHolder: MessageStateHolder,
) :
ViewModel(),
MessageStateHolder by messageStateHolder {
fun bar() {
try {
}catch (..) {
addMessage("error!!")
}
}
}
// ---- Library side(Write only once) ----
@Composable
fun SnackbarMessageEffect(
scaffoldState: ScaffoldState,
messageStateHolder: MessageStateHolder
) {
messageStateHolder.messageUiState.userMessages.firstOrNull()?.let { userMessage ->
LaunchedEffect(userMessage) {
scaffoldState.snackbarHostState.showSnackbar(userMessage.message)
messageStateHolder.userMessageShown(userMessage.id)
}
}
}
data class UserMessage(val id: Long, val message: String)
data class MessageUiState(
val userMessages: List<UserMessage> = emptyList()
)
@Module
@InstallIn(ViewModelComponent::class)
class MessageStateHolderModule{
@Provides
fun provideMessageStateHolder(): MessageStateHolder {
return MessageStateHolderImpl()
}
}
class MessageStateHolderImpl : MessageStateHolder {
private var _messageUiState by mutableStateOf(MessageUiState())
override val messageUiState get() = _messageUiState
override fun userMessageShown(messageId: Long) {
val messages = _messageUiState.userMessages.filterNot { it.id == messageId }
_messageUiState = _messageUiState.copy(userMessages = messages)
}
override fun addMessage(message: String) {
val messages = _messageUiState.userMessages + UserMessage(
id = UUID.randomUUID().mostSignificantBits,
message = message
)
_messageUiState = _messageUiState.copy(userMessages = messages)
}
}
interface MessageStateHolder {
val messageUiState: MessageUiState
fun userMessageShown(messageId: Long)
fun addMessage(message: String)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment