Android Events
The Lovina Chat SDK emits events through the onEvent callback on LovinaChatWidget. Use these events to react to chat activity in your native code.
Event Listener Pattern
Set the onEvent callback before or after calling configure():
chatWidget.onEvent = { event ->
when (event) {
is ChatEvent.Loaded -> { /* ... */ }
is ChatEvent.MessageReceived -> { /* ... */ }
is ChatEvent.UnreadCountChanged -> { /* ... */ }
is ChatEvent.Closed -> { /* ... */ }
is ChatEvent.Error -> { /* ... */ }
}
}
ChatEvent Types
ChatEvent.Loaded
Emitted when the widget has finished loading and is ready for interaction.
| Property | Type | Description |
|---|---|---|
authToken | String? | Session auth token, if the user has an active session. |
is ChatEvent.Loaded -> {
Log.d("Chat", "Widget loaded, token: ${event.authToken}")
}
ChatEvent.MessageReceived
Emitted when a new message is received (from an agent or bot).
| Property | Type | Description |
|---|---|---|
message | Map<String, Any?> | Full message payload including content, sender, attachments, etc. |
is ChatEvent.MessageReceived -> {
val content = event.message["content"] as? String
val sender = (event.message["sender"] as? Map<*, *>)?.get("name")
Log.d("Chat", "Message from $sender: $content")
}
ChatEvent.UnreadCountChanged
Emitted when the number of unread messages changes. Useful for updating notification badges.
| Property | Type | Description |
|---|---|---|
count | Int | Current number of unread messages. |
is ChatEvent.UnreadCountChanged -> {
updateBadge(event.count)
}
ChatEvent.Closed
Emitted when the chat is closed, either by the user or the agent.
| Property | Type | Description |
|---|---|---|
reason | String? | Optional reason for closure (e.g., "user", "resolved"). |
is ChatEvent.Closed -> {
Log.d("Chat", "Chat closed: ${event.reason}")
finish()
}
ChatEvent.Error
Emitted when an error occurs within the widget.
| Property | Type | Description |
|---|---|---|
code | String | Error code (e.g., "network_error", "auth_failed"). |
message | String | Human-readable error description. |
is ChatEvent.Error -> {
Log.e("Chat", "Error [${event.code}]: ${event.message}")
showErrorToast(event.message)
}
Full Example
chatWidget.onEvent = { event ->
when (event) {
is ChatEvent.Loaded -> {
Log.d("Chat", "Ready")
}
is ChatEvent.MessageReceived -> {
val content = event.message["content"] as? String ?: ""
showNotification("New message", content)
}
is ChatEvent.UnreadCountChanged -> {
badgeView.text = if (event.count > 0) "${event.count}" else ""
badgeView.isVisible = event.count > 0
}
is ChatEvent.Closed -> {
finish()
}
is ChatEvent.Error -> {
Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show()
}
}
}
Common Patterns
Navigation: Open chat Activity, finish on close
// In your main Activity — open chat as a new Activity
startActivity(Intent(this, ChatActivity::class.java))
// In ChatActivity
class ChatActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val widget = LovinaChatWidget(this)
widget.onEvent = { event ->
if (event is ChatEvent.Closed) {
finish() // goes back to previous Activity
}
}
widget.configure(config)
setContentView(widget)
}
}
Fragment: Pop on close
widget.onEvent = { event ->
if (event is ChatEvent.Closed) {
parentFragmentManager.popBackStack()
}
}
Show unread badge
is ChatEvent.UnreadCountChanged -> {
val badge = bottomNav.getOrCreateBadge(R.id.chat_tab)
badge.isVisible = event.count > 0
badge.number = event.count
}