Перейти к основному содержимому
Версия: 5.21.0

Делегаты и слушатели событий

Для реакции на события SDK у интегратора есть два механизма:

  1. ChatCenterUIListener — интерфейс с 4 callback-методами: счётчик непрочитанных, сетевая ошибка, клик по ссылке, внутреннее исключение SDK. Достаточно для большинства интеграций.
  2. ChatUpdateProcessor — SharedFlow-шина для событий уровня доставки сообщений, изменения статусов и состояния соединения. Используется только при построении кастомного UI поверх SDK.

ChatCenterUIListener​

fun setChatCenterUIListener(listener: ChatCenterUIListener)

Подписывает приложение на события UI и базовые SDK-события. Вызывать после init(...) — иначе SDK выбросит IllegalStateException. Повторный вызов заменяет предыдущий listener (старые подписки на потоки внутри SDK отменяются).

Методы интерфейса​

МетодПараметрКогда вызывается
unreadMessageCountChanged(count: UInt)количество непрочитанныхСразу после setChatCenterUIListener(...) (текущее значение), затем при изменении счётчика — authorize(...), получение нового входящего сообщения, прочтение оператором
networkErrorReceived(error: Error)edna.chatcenter.core.main.Error — поля и пример обработки см. в Ошибки → networkErrorReceivedСетевая ошибка от сервера или WebSocket
urlClicked(url: String)URLПользователь нажал на ссылку в сообщении
exceptionReceived(trace: String)стек-трейсВнутреннее исключение SDK (для логирования)

Пример​

import android.content.Intent
import edna.chatcenter.core.main.ChatCenterUIListener
import edna.chatcenter.core.main.Error // важно: затеняет kotlin.Error — при необходимости используйте alias `as SdkError`

private const val APP_UNREAD_COUNT_BROADCAST = "com.example.app.UNREAD_COUNT"
private const val UNREAD_COUNT_KEY = "unread_count"

chatCenterUI.setChatCenterUIListener(object : ChatCenterUIListener {
override fun unreadMessageCountChanged(count: UInt) {
val intent = Intent(APP_UNREAD_COUNT_BROADCAST)
.putExtra(UNREAD_COUNT_KEY, count.toInt())
applicationContext.sendBroadcast(intent)
}

override fun networkErrorReceived(error: Error) {
Log.e("ChatCenter", "Сетевая ошибка [${error.code}]: ${error.message}")
}

override fun urlClicked(url: String) {
Log.i("UrlClicked", url)
}
})

Потоки callback'ов​

CallbackПоток
unreadMessageCountChangedmain — можно обновлять UI напрямую
exceptionReceivedmain
urlClickedmain (приходит из обработчика клика по ссылке в UI)
networkErrorReceivedфоновый (OkHttp / Retrofit / @WorkerThread-источники) — для UI переключайтесь на main явно

Рекомендуемый идиом для networkErrorReceived, когда нужно тронуть UI:

override fun networkErrorReceived(error: Error) {
// Этот callback приходит с сетевого потока, не с main.
// Используйте lifecycleScope / viewModelScope вашего экрана.
lifecycleScope.launch(Dispatchers.Main) {
showErrorToUser(error)
}
}

Для View-based кода вне coroutine-контекста допустимы view.post { ... } или Handler(Looper.getMainLooper()).post { ... } — но если в проекте уже используются корутины, держитесь одного идиома (Dispatchers.Main).

Подробное обоснование (где и почему вызывается callback) с конкретными call-sites — в Известных ограничениях.

Продвинутые сценарии​

Продвинутый сценарий — кастомный UI поверх SDK

Раздел ниже нужен только если вы строите собственный список сообщений / индикаторы статусов поверх SDK или мониторите события SDK на низком уровне. Для бейджа непрочитанных, сетевых ошибок и кликов по ссылкам достаточно ChatCenterUIListener выше.

Подписка на дополнительные события — ChatUpdateProcessor​

Если в вашем сценарии нужны события, которых нет в ChatCenterUIListener (например, точный момент доставки сообщения на сервер или сигнал закрытия офлайн-сокета), доступна реактивная шина ChatUpdateProcessor из пакета edna.chatcenter.core.chatUpdates. Класс предоставляет публичные MutableSharedFlow-потоки. Ниже описаны 6 базовых для кастомного UI; помимо них в классе есть потоки для quick replies, typing-индикатора, обновления вложений и прогресса загрузки файлов — доступны как поля того же класса, см. KDoc исходников.

ПотокЧто эмититсяКогда полезно
newMessageFlowChatItem — элемент истории чата, добавленный после ответа сервера (включая исходящие, пришедшие в GET_MESSAGES)Кастомное оповещение/счётчик помимо штатного push'а
messageSendSuccessFlowChatItemProviderData (uuid, messageId, sentAt) — подтверждение от сервера, что исходящее сообщение принятоПодтверждение доставки на стороне приложения
messageSendErrorFlowChatItemSendErrorModelРеакция на ошибку отправки (retry-стратегия)
outgoingMessageStatusChangedFlowList<Status> — пачка обновлений статусов (Status.status принимает значение MessageStatus); в одном эмитте — статусы разных сообщенийОтображение «галочек» в кастомном UI
socketIsClosedFlowInt — код закрытия WebSocketИндикатор офлайн-режима
cleanAllOnUiFlowСигнал на очистку UIСброс кастомного состояния — эмитится в обоих сценариях logout() (как при отложенной очистке во время хендшейка, так и при полной)

Получить экземпляр — через inject()-делегат публичного DI-контейнера SDK:

import edna.chatcenter.core.chatUpdates.ChatUpdateProcessor
import edna.chatcenter.core.serviceLocator.core.inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

val processor: ChatUpdateProcessor by inject()

// ChatUpdateProcessor эмитит из Dispatchers.Unconfined — события приходят не на Main
// thread (на потоке, где сработал emit() внутри SDK). Перед UI-вызовами оборачивайте
// код в withContext(Dispatchers.Main). Подробности — в Известных ограничениях.
lifecycleScope.launch {
processor.newMessageFlow.collect { item ->
withContext(Dispatchers.Main) {
// обновление UI
}
}
}
inject() — публичный DI-контейнер SDK, не Hilt/Koin

Делегат inject() принадлежит публичному пакету edna.chatcenter.core.serviceLocator.core и не связан с DI-фреймворками вашего приложения (Hilt, Koin, Dagger).

Дополнительные модели для кастомного UI​

Этими типами вы можете оперировать при построении собственного интерфейса чата (списка сообщений, индикаторов статусов, прогресса скачивания файлов). Создавать их экземпляры вручную не нужно — SDK эмитит их сам через ChatUpdateProcessor или передаёт в callback'ах.

FileDescription — модель вложения​

edna.chatcenter.core.models.FileDescription — модель файлового вложения, которую SDK эмитит для элементов истории чата (исходящие сообщения хранят список как UserPhrase.files, входящие — аналогично).

Ключевые поля: fileUri: Uri?, size: Long, from: String?, state: MutableStateFlow<AttachmentStateEnum> (default ANY; SDK обновляет сам — читайте через state.value / state.collect { ... }, не модифицируйте), errorCode: ErrorStateEnum (default ANY), downloadPath: String?.

AttachmentStateEnum (ANY, PENDING, ERROR, EXPIRED, READY) и ErrorStateEnum — публичные enum'ы из того же пакета (edna.chatcenter.core.models.enums).

ProgressReceiver — события скачивания файлов​

edna.chatcenter.core.broadcastReceivers.ProgressReceiver — BroadcastReceiver, через который SDK сообщает о ходе скачивания файлов. Регистрируйте, если нужно отображать собственный индикатор прогресса. Константы actions объявлены в companion object самого ProgressReceiver:

  • ProgressReceiver.PROGRESS_BROADCAST — обновление прогресса (0..100).
  • ProgressReceiver.DOWNLOADED_SUCCESSFULLY_BROADCAST — файл скачан.
  • ProgressReceiver.DOWNLOAD_ERROR_BROADCAST — ошибка скачивания.

Intent содержит FileDescription как Parcelable-extra под ключом FileDownloadWorker.FD_TAG (edna.chatcenter.core.workers.FileDownloadWorker.FD_TAG). Для DOWNLOAD_ERROR_BROADCAST дополнительно передаётся Throwable через Serializable-extra под ключом ProgressReceiver.DOWNLOAD_ERROR_BROADCAST (та же константа используется и в качестве action).

MessageStatus — enum статусов сообщения​

Описан в каноническом разделе Сообщения → Статусы сообщения. Используется для построения кастомных индикаторов «галочек» (поле sentState отправленных элементов истории).

Связанные разделы​