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

Расширенные настройки

Отслеживание событий внутри SDK

fun setChatCenterUIListener(listener: ChatCenterUIListener) - содержит методы, вызываемые при изменении состояний SDK.

/**
* Описывает методы счетчика непрочитанных сообщений,
* получения сетевой ошибки, реакции на нажатие ссылки в сообщении
*/
interface ChatCenterUIListener {
/**
* Изменился счетчик непрочитанных сообщений
* @param count количество непрочитанных сообщений
*/
fun unreadMessageCountChanged(count: UInt) {}

/**
* Получен ответ от сервера с ошибкой
* @param error описание текущей ошибки
*/
fun networkErrorReceived(error: Error) {}

/**
* Нажата ссылка в сообщении
* @param url строка ссылки
*/
fun urlClicked(url: String) {}
}

Чтобы подписаться на изменение количества непрочитанных сообщений, можно задать слушатель:

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

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

Первый раз проверка непрочитанных запускается при инициализации СДК (если пользователь установлен). Для получения обновлений необходим активный чат (открытый и хранимый в памяти). Если нужно дать пользователю возможность выйти с экрана, но необходимо отображать актуальный счетчик, при инициализации библиотеки следует установить флаг keepWebSocketActive = true внутри ChatConfig. В случае необходимости работы счетчика до входа в чат, необходимо устанавливать пользователя через метод forceAuthorize(...), а так же установить флаг keepWebSocketActive = true

Применение стилей

В классе ChatCenterUI до вызова метода init(...) задайте стили, изменив поля theme или darkTheme. Данные параметры опциональны. В SDK уже заданы параметры по-умолчанию для светлой темы, если вы не определите свои. В случае, если не определена темная тема, внутри SDK всегда будет использоваться светлая тема.

Пример:

chatCenterUI = ChatCenterUI(applicationContext).apply {
theme = chatLightTheme
darkTheme = chatDarkTheme
init(server.threadsGateProviderUid, server.appMarker, chatConfig)
}

Тема состоит из двух уровней. Первый уровень - это компоненты (ChatComponents), второй флоу (ChatFlows). Компоненты представляют собой набор общих стилей для отдельных view. К примеру, ниже представлен фрагмент кода для "кнопок-иконок" внутри SDK:

class IconButtonComponent(
internal val context: Context,
colors: ChatColors,
images: ChatImages
) {
/**
* Иконка для кнопки "назад"
*/
@DrawableRes
var backBtnImage = images.backBtn

//...

/**
* Цвет кнопки "назад"
*/
@ColorRes
var backButtonColor = colors.backButton

/**
* Цвет кнопки "назад"
*/
@ColorRes
var chatToolbarInverseIconTintColor = colors.chatToolbarInverseIconTint

//...

/**
* Цвет иконки очистки цитаты
*/
@ColorRes
var quoteClearIconColor = colors.quoteClearIcon

}

Поля данного класса будут применены ко всем подобным кнопкам в приложении. Вы можете переопределить в SDK какие-то компоненты целиком, либо переопределить точечно конкрутную кнопку через ChatFlows.

Компонент чата можно переопределить как целиком, так и его часть:

val lightChatComponents = ChatComponents(
applicationContext,
colors = lightColors,
images = lightImages
).apply {
navigationBarStyle = navigationBarStyle.copy(closeButtonEnabled = false)
}

Цвета и картинки, указанные выше при создании компонентов - опциональны. Можно задать свои, переопределив только те, которые считаете нужным:

val lightColors = ChatColors(
main = R.color.light_main,
searchingProgressLoader = R.color.light_main,
bodyIconsTint = R.color.light_main,
incomingText = R.color.black_color,
incomingTimeText = R.color.light_time_text,
outgoingTimeText = R.color.light_time_text,
outgoingText = R.color.black_color,
incomingBubble = R.color.alt_white,
outgoingBubble = R.color.light_outgoing_bubble,
toolbarText = R.color.white_color,
messageSendingStatus = R.color.light_icons,
messageSentStatus = R.color.light_icons,
messageDeliveredStatus = R.color.light_icons,
messageReadStatus = R.color.light_icons,
messageFailedStatus = R.color.light_icons,
incomingLink = R.color.light_links,
outgoingLink = R.color.light_links,
toolbar = R.color.light_main,
statusBar = R.color.light_statusbar,
menuItem = R.color.light_main
)

При переопределении компонента выше для светлой темы мы меняем кнопку назад для всех экранов: чат, просмотр изображений и т.д. Однако если вы переопределите эту кнопку внутри ChatFlows, это будет иметь более высокий приоритет перед компонентом.

В дальнейшем вы создаете тему:

chatLightTheme = ChatTheme(lightChatComponents)

и при инициализации SDK устанавливаете ее:

chatCenterUI = ChatCenterUI(applicationContext, loggerConfig).apply {
theme = chatLightTheme
darkTheme = chatDarkTheme
init(server.threadsGateProviderUid ?: "", server.appMarker ?: "", chatConf)
}

Внутри ChatFlows представлены все элементы, которые отображены в SDK. Если вам, к примеру, нужно точечно переопределить только кнопку "назад", вы можете сделать это следующий образом:

val flows = ChatFlows(ChatComponents(applicationContext)).apply {
// меняем кнопку "назад"
chatFlow.navigationBar.backButton = IconButtonChatStyle(
IconButtonColorStyle(
iconTintColor = R.color.blue_color
),
R.drawable.ic_cloud
)
// центрируем текст в тулбаре
chatFlow.navigationBar.centerToolbarText = true
}
chatLightTheme = ChatTheme(flows) // создайте инстанс темы, переопределив точечно нужные элементы

То есть при создании тем вы можете определять как компоненты, которые на более низком уровне будут задавать стили для view, так и переопределить конкретные view с помощью ChatFlows.

Или, к примеру, если вам нужно переопределить подсказку при поиске в поле ввода:

val flows = ChatFlows(ChatComponents(applicationContext)).apply {
// ... Иные настройки flows, если необходимо
searchFlow.searchBar.textInput?.placeholderText = "Поиск в сообщениях"
}

Пример переопределения внутри компонента цвета текста для всех полей ввода:

ChatTheme(
lightChatComponents.apply {
inputTextComponent.inputMessageColor = R.color.alt_blue
}
)

Подробнее можно посмотреть в нашем демо и в специальном разделе, описывающем все методы публичного апи.

Отправка сообщений

Если вы хотите вручную отправить сообщение, можно вызвать внутри объекта ChatCenterUI метод send(message: ChatMessage)

Настройки сервера по умолчанию позволяют отправлять файлы размером до 30 мб.

SSL Pinning

Позволяет использовать указанный список сертификатов для проверки их соответствия с сертификатом на сервере.

осторожно

При использования данного функционала, не рекомендуется использовать только один сертификат. В случае его отзыва или истечения срока действия - SDK перестанет подключаться к серверу. Используйте резервные сертификаты с их своевременным обновлением.

Для включения SSL pinning необходимо:

  1. В папку res/raw поместить публичные сертификаты.
  2. В ChatConfig пробросить класс ChatNetworkConfig (поле networkConfig), указав сертификаты:
val networkConfig = ChatNetworkConfig(
HTTPConfig(),
WSConfig(),
SSLPinningConfig(certificates, server.allowUntrustedSSLCertificate)
)

val chatConf = ChatConfig(
transportConfig,
networkConfig,
//...
)

Поле allowUntrustedSSLCertificate отключает проверку сертификатов. Все сертификаты будут считаться доверенными.

Настройка таймаутов подключения

Таймауты настраиваются с помощью классов HttpConfig и WSConfig. Объекты данных классов входят в класс ChatNetworkConfig, который, в свою очередь, явялется полем класса ChatConfig. Единица измерения таймаутов в класса HttpConfig и WSConfig - секунды.

Использование внутренних диплинков

Библиотека позволяет использовать внутренние диплинки. Например, если в сообщении встречается текст вида:

earth://some.params?code={code}

И если вы создадите Activity, который будет запускаться Аction.VIEW, то при клике на подобную ссылку запустится ваш указанный активити. Для этого в манифесте указать для вашего активити фильтры:

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="earth"
android:host="*" />
</intent-filter>

Настройки backup для приложения

В библиотеке используется настройка

<application  
android:fullBackupContent="@xml/backup_rules">
...
</application>

Содержимое данного файла:

<full-backup-content>  
<exclude domain="sharedpref" path="im.threads.internal.utils.EncryptedPrefStore.xml"/>
</full-backup-content>

Данная запись необходима, чтобы зашифрованные SharedPreferences не оставались в памяти устройства после переустановки приложения. Если вы используете свой собственный fullBackupContent файл, вам необходимо добавить в ваш файл exclude, который описан у нас и затем переопределить ваш файл своим:

<application  
android:fullBackupContent="@xml/your_backup_rules"
tools:replace="android:fullBackupContent">
...
</application>

Бывает так, что другие SDK также используют android:fullBackupContent настройку. В этом случае нужно посмотреть, какие исключения прописаны в этих SDK и сделать общий файл. Например у Vungle и AppsFlyer есть свои настройки fullBackupContent. Их исключения задокументированы следующим образом:

Vungle - https://support.vungle.com/hc/en-us/articles/360047780372#vungle-exclusion-rules-0-11
AppsFlyer - https://support.appsflyer.com/hc/en-us/articles/207032126-Android-SDK-integration-for-developers#integration-backup-rules

Для объединения их настроек с нашей должен получиться следующий файл:

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="file" path="vungle" />
<exclude domain="file" path="vungle_cache" />
<exclude domain="external" path="vungle_cache" />
<exclude domain="database" path="vungle_db" />
<exclude domain="sharedpref" path="com.vungle.sdk.xml" />
<exclude domain="sharedpref" path="im.threads.internal.utils.EncryptedPrefStore.xml"/>
</full-backup-content>

Логгер

Библиотека использует свой собственный логгер, который поддерживает запись в файл. По умолчанию он выключен, то есть логи не будут выводиться ни в файл, ни в консоль. Чтобы включить логи в библиотеке, создайте объект ChatLoggerConfig и передайте его в ChatCenterUI при инициализации библиотеки. Пример:

val loggerConfig = ChatLoggerConfig(
applicationContext,
logFileSize = 50
)

chatCenterUI = ChatCenterUI(applicationContext, loggerConfig)

Изменение версии backend api

По умолчанию в мобильном sdk уровень backend api = 15. Вы можете изменить его через поле apiVersion внутри класса ChatTransportConfig, который является дочерним классом ChatConfig. Доступные к изменению версии api - 16, 17, 18.

Отключение пользовательского ввода

Для отключения пользовательского ввода и возможности отправки сообщений в чат, необходимо изменить поле userInputEnabled внутри класса ChatConfig

Автоскролл

Если история чата прокручена к более старым сообщениям, в чате появляется кнопка возврата к последним сообщениям и действует следующее поведение:

  • в чате получен TYPING (индикация набора входящего сообщения) = > пользователь остается на текущей позиции истории, ничего не перемещается;
  • в чате получено любое входящее сообщение = > пользователь остается в текущей позиции истории, ничего не перемещается, на кнопке прокрутки появляется индикатор непрочитанных сообщений с указанием количества таких сообщений;
  • пользователь отправил сообщение = > чат прокручивается к последнему сообщению пользователя.