Saytv Chat Example Android
App that is going to use the Saytv Chat library.
Table of contents
- What's New
- Prerequisites
- Installation
- Initialization
- Register
- Login
- Get Logged In User
- Logout
- ChatView
- Header
- Dummy header
- Full Chat
- Get active users
- Profile
- Customization and Theming
- Options
- User Analytics
- Troubleshooting
What's New
13.0.5
- Features fixes to the authentication issues in v13.0.4
12.3.0
- Now admin messages display the name of the admin instead of hardcoded "Admin" string.
Check older versions on the CHANGELOG
Prerequisites
- Create a Jitpack account and generate an authentication token.
- In the
gradle.properties
replace string<PROVIDED JITPACK AUTH TOKEN>
with the provided Jitpack.io authentication token
Installation
- In the
gradle.properties
of your app, add the following line:
JITPACK_AUTH_TOKEN=<PROVIDED JITPACK AUTH TOKEN>
where the <PROVIDED JITPACK AUTH TOKEN>
is the Jitpack Authentication token you have been provided. Example: See gradle.properties at line 24 2. In your settings.gradle
file, in the dependencyResolutionManagement
block, add the following Jitpack repository and sync your project. See settings.gradle
maven {
url 'https://www.jitpack.io'
credentials { username JITPACK_AUTH_TOKEN }
}
- In your library or app
build.gradle
file add the following dependency:
implementation 'org.bitbucket.square1.saytv_sdk_android:release:14.0.0'
- You're all set!
Initialization
Before any operation, the SDK must be initialized, this is done mainly through the SayTVSdk.init()
method and can be achieved in 2 ways:
- Using our helper components that take care of initialization, automatically (OPTIONAL)
- Using your own custom
Application
andFirebaseMessagingService
implementations
I. Initialization - Using the helper components (OPTIONAL)
SayTVApplication
- Helper class to handle the SDK initialization. Extend this class or simply declare it in yourAndroidManifest.xml
and the SDK initialization will be handled automatically. To listen to it's result one could overrideonSayTvSdkInitCompleted()
or subscribe toSayTVSdk.initResultLiveData
events.Extending and using this class is optional. Please refer to section II. Initialization - Custom implementation for a more custom approach
SayTVFirebaseService
- Helper class to automatically delegate the Firebase events to the SDK. Extend this class or simply declare it in yourAndroidManifest.xml
and the component will automatically forward the Firebase events to the SDK.Extending and using this class is optional. Please refer to section II. Initialization - Custom implementation for a more custom approach
Please reference to :sample:no-firebase
for an example on how to use the helper components. Please notice that you still have to add the io.square1.saytvsdk.SayTVApplication
and io.square1.saytvsdk.SayTVFirebaseService
(or their correspondent children classes when extending them) in your AndroidManifest
in order for it to properly work, like so:
<application
android:name="io.square1.saytvsdk.SayTVApplication"
... >
...
<service
android:name="io.square1.saytvsdk.SayTVFirebaseService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
II. Initialization - Custom implementation
If you already have existing Application
or FirebaseMessagingService
components and you don't need to use the helper ones from section I. Initialization - Using the helper components then to integrate with our SDK you'll have to:
- If you don't have an
Application
class already, create one, declare it in yourAndroidManifest.xml
, and in youronCreate()
method callSayTVSdk.init()
. In theSayTVSdk.init()
, with theonCompleted()
parameter function, you'll be notified when the initialization has completed. See:sample:firebase
for a working example.
class SampleApp : Application() {
override fun onCreate() {
super.onCreate()
SayTVSdk.init(
context = this,
firebaseApp = FirebaseApp.initializeApp(this),
preferredDisplayName = ...,
baseURL = ...) {
when (it) {
is Result.Success -> logcat { "SayTVSdk initialized successfully" }
is Result.Error.Firebase -> logcat(Log.ERROR, it.throwable) { "SayTVSdk failed to initialize:" }
}
}
}
}
- If you don't have a
FirebaseMessagingService
, create one, declare it in yourAndroidManifest.xml
and in theonNewToken(String)
method callSayTVSdk.firebaseDelegate.onNewToken(token)
, also in youronMessageReceived(message)
method call SayTVSdk.firebaseDelegate.onMessageReceived(message). See:sample:firebase
for a working example.
class SampleFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
SayTVSdk.firebaseDelegate.onNewToken(token)
}
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
SayTVSdk.firebaseDelegate.onMessageReceived(message)
}
}
- In the not so rare case where
onNewToken(token: String)
is not triggered, we recommend adding the following piece of code to yourSayTVSdk.init()
Result.Success
block. This forces Firebase to provide a mandatory token to receive notifications with
SayTVSdk.init(...) {
is Result.Success -> {
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(MainActivity.TAG, "Fetching FCM registration token failed", task.exception)
return@OnCompleteListener
}
// Get new FCM registration token
val token = task.result
SayTVSdk.firebaseDelegate.onNewToken(token)
})
}
...
}
Don't forget to declare them in your AndroidManifest.xml
file:
<application
android:name=".SampleApp"
... >
...
<service
android:name=".SampleFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
Register
To create an account the SayTVSdk.register()
method must be used with the proper params only after SayTVSdk.init()
has completed. Doing so an authentication token will be generated and cached by the SayTVSdk
in order for the SayTVChatView
to work properly Please keep in mind that the avatar Uri
param has to be an URL. This method does not upload an image!
lifecycle.coroutineScope.launch {
when (val register = SayTVSdk.register(
apiToken = ...,
externalId = ...,
username = ...,
avatar = ...,
)
) {
is Result.Success -> doSomething()
else -> doSomething()
}
}
Login
Call this only after the SayTVSdk.init()
method, given an account has already been created. Doing so an authentication token will be generated and cached by the SayTVSdk
in order for the SayTVChatView
to work properly
lifecycle.coroutineScope.launch {
when (val login = SayTVSdk.login(apiToken = ..., externalId = ...)) {
is Result.Success -> doSomething()
else -> doSomething()
}
}
Get Logged In User
For this view to work properly, 2 things must be met first:
SayTVSdk.init()
has been called and completed successfullySayTVSdk.login
orSayTVSdk.register
has been called and completed successfully
To get the logged in user, call the getLoggedInUser()
method from the SayTVSDK object anywhere in your code
when (val loggedInUser = SayTVSdk.getLoggedInUser()) {
is Result.Success -> doSomething()
else -> doSomething()
}
Logout
To logout inside the SDK, call SayTvSdk.logout()
like below
when (val logout = SayTVSdk.logout()) {
is Result.Success -> doSomething()
else -> doSomething()
}
ChatView
This is an Android View containing the chat itself. For this view to work properly, 2 things must be met first:
SayTVSdk.init()
has been called and completed successfullySayTVSdk.login
orSayTVSdk.register
has been called and completed successfully
You can add the SayTVChatView
component to your XML file and give it an ID you can reference later on in code, for example
<io.square1.saytvsdk.app.scenes.SayTVChatView
android:id="@+id/chat_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
In your Kotlin file, initialize the component by calling SayTVChatView.init(...) with its relevant parameters, for example
binding.chatView.init(
chatId = ...,
chatName = ...,
chatImage = ...,
startDate = ...,
endDate = ...,
isFanzone = true,
shouldAutoUnsubscribe = true,
shouldDisplayQuizzes = false,
displayButtonBar = true,
language = "fr"
)
chatId
: ID of the chat you're subscribing dynamically to
chatName
: Name of the chat you're subscribing dynamically to
You can further customize the SayTVChatView
by directly calling custom methods, for example
binding.chatView.apply {
setCustomFiltersBottomSheetBackgroundColor(R.color.black)
setCustomFiltersBottomSheetBodyTextColor(io.square1.saytvsdk.R.color.lime)
setCustomFiltersBottomSheetTitleTextColor(R.color.red)
setCustomFiltersBottomSheetCloseButtonTextColor(R.color.red)
}
Or you can customize by using the customizeTheme method on the SayTVChatView
component. For example
binding.chatView.customizeTheme {
quizTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
quizOptionsTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
quizOptionsButtonTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
quizBackgroundDrawable = resources.getDrawable(R.drawable.test_drawable)
}
For more on customizations, see the customization section
When initialising a chat component SDK automatically subscribes user to the chat events. While subscription is done automatically by the SDK, you need to handle unsubscribe manually if the shouldAutoUnsubscribe
attribute of the SayTVChatView
is set to false. You can unsubscribe from a chat by calling the unsubscribe()
method off the SayTVChatView
component:
launch {
when (val unsubscribeOp = binding.chatView.unsubscribe()) {
is Result.Success -> doSomething()
else -> doSomething()
}
}
Yet there are some exceptions where SDK also unsubscribe user automatically from the chat: - when user has been banned from the chat by admin.
There could be only one active chat at a time in the SDK. If the new chat is created (different chatId) without unsubscribing from old chat then unsubscribe from old chat will be performed automatically before subscribing to a new chat. This provides possibility to control subscribe status when recreating chat component in different scenarios so the SDK can store all chat data between subscribe and unsubscribe so if chat is multiple time recreated (for example on device orientation change) all the data of the chat are up to date and are removed only when unsubscribe is called. This improves data synchronisation when recreating the chat without unsubscribing.
Header
This is an Android View containing the chat header. For this view to work properly, 2 things must be met first:
SayTVSdk.init()
has been called and completed successfullySayTVSdk.login
orSayTVSdk.register
has been called and completed successfully
You can add the SayTVChatHeaderView
component to your XML file and give it an ID you can reference later on in code, for example
<io.square1.saytvsdk.app.scenes.SayTVChatHeaderView
android:id="@+id/chat_header_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
In your Kotlin file, initialize the component by calling SayTVChatHeaderView.init(...) with its relevant parameters, for example
binding.chatHeaderView.init(
chatId = ...,
chatName = ...,
chatImage = ...,
startDate = ...,
endDate = ...,
isFanzone = true,
shouldAutoUnsubscribe = true,
shouldDisplayQuizzes = false,
displayButtonBar = true,
language = "fr"
)
You can further customize the SayTVChatHeaderView
by directly calling custom methods, for example
binding.chatHeaderView.apply {
setExpirationTimeTextNormalColorValue(R.color.red)
setExpirationTimeTextExpiringColorValue(R.color.teal_700)
}
Or you can customize by using the customizeTheme method on the SayTVChatHeaderView
component. For example
binding.chatHeaderView.customizeTheme {
quizTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
quizOptionsTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
quizOptionsButtonTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
quizBackgroundDrawable = resources.getDrawable(R.drawable.test_drawable)
}
For more on customizations, see the customization section
Dummy Header
This is an Android View containing the chat header but without the ability to subscribe dynamically to a chat or make any service calls, this view acts as a sort of dummy for a header. For this view to work properly, 2 things must be met first:
SayTVSdk.init()
has been called and completed successfullySayTVSdk.login
orSayTVSdk.register
has been called and completed successfully
You can add the SayTVChatHeaderView
component to your XML file and give it an ID you can reference later on in code, for example
<io.square1.saytvsdk.app.scenes.SayTVChatHeaderView
android:id="@+id/dummy_chat_header_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
In your Kotlin file, initialize the component by calling SayTVChatHeaderView.initWithoutSubscribeDynamic(...) with its relevant parameters, for example
binding.dummyChatHeaderView.initWithoutSubscribeDynamic(
chatId = ...,
chatName = ...,
chatImage = ...,
startDate = ...,
endDate = ...,
)
Customization for this is the same as customization for a header
Full Chat
This is an Android View containing the chatView and chatHeaderView in one component. For this view to work properly, 2 things must be met first:
SayTVSdk.init()
has been called and completed successfullySayTVSdk.login
orSayTVSdk.register
has been called and completed successfully
You can add the SayTVChatFullView
component to your XML file and give it an ID you can reference later on in code, for example
<io.square1.saytvsdk.app.scenes.SayTVChatFullView
android:id="@+id/full_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
In your Kotlin file, initialize the component by calling SayTVChatFullView.init(...) with its relevant parameters, for example
binding.fullView.init(
chatId = ...,
chatName = ...,
chatImage = ...,
startDate = ...,
endDate = ...,
isFanzone = true,
shouldAutoUnsubscribe = true,
shouldDisplayQuizzes = false,
displayButtonBar = true,
language = "fr"
)
Since the fullView is a merger of the header and chatView, you can customize the fullView by customizing the headerView and chatView independently, for example
binding.fullView.headerView.customizeTheme {
...
}
binding.fullView.commentsView.customizeTheme {
...
}
Get active users
Get the active users in as many chat rooms as you need. Simply pass the externalIDs of the chat in a list to the getActiveUsersFor()
method as seen below. The result on success is a list containing objects with the information
launch {
when (val activeUsers = SayTVSDK.getActiveUsersFor(listOf("", "", ""))) {
is Result.Success -> doSomething()
else -> doSomething()
}
}
Profile
This is an Android View containing the profileView. For this view to work properly, 2 things must be met first:
SayTVSdk.init()
has been called and completed successfullySayTVSdk.login
orSayTVSdk.register
has been called and completed successfully
You can add the SayTVProfileView
component to your XML file and give it an ID you can reference later on in code, for example
<io.square1.saytvsdk.app.scenes.profile.SayTVProfileView
android:id="@+id/profile_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
...>
In your Kotlin file, initialize the component by calling SayTVProfileView.setUserId(...) with its relevant parameters, for example
binding.profileView.setUserId(
userID = ...,
language = ...
)
NB: Both userID
and language
are optional, where a userID is passed, the profile information for the relevant user is collected, where nothing is passed, the profile information for the currently logged in user is collected.
You can further customize the SayTVProfileView
by directly calling custom methods, for example
binding.profileView.apply {
setCustomProfileBadgesActivityBackgroundColor(R.color.black)
setCustomProfileBadgesActivityProgressBarColor(io.square1.saytvsdk.R.color.lime)
setCustomProfileBadgesActivityToolBarColor(R.color.red)
setCustomProfileBadgesActivityToolBarTextColor(R.color.red)
}
Or you can customize by using the customizeTheme method on the SayTVProfileView
component. For example h
binding.profileView.customizeTheme {
profileBackgroundColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
nameTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
memberSinceTextColor = ContextCompat.getColor(this@ChatActivity, R.color.red)
}
For more on customizations, see the customization section
Customization and Theming
Several parameters are available for theming SayTVChatView
xml layout as shown below
<io.square1.saytvsdk.app.scenes.SayTVChatView
android:id="@+id/chat_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:chatBackground="@drawable/some_drawable"
app:headerBackground="@color/some_color"
app:headerTextColor="@color/some_color"
app:viewerCountIcon="@drawable/some_drawable"
app:viewerCountTextColor="@color/some_color"
app:viewerCountBackground="@drawable/some_drawable"
app:tvShowProgressBarDrawable="@drawable/some_drawable"
app:settingsFilterBackground="@drawable/some_drawable"
app:settingsPauseBackground="@drawable/some_drawable"
app:settingsWallpaperBackground="@drawable/some_drawable"
app:settingsQuizBackground="@drawable/some_drawable"
app:settingsHashtagBackground="@drawable/some_drawable"
app:settingsFilterIcon="@drawable/some_drawable"
app:settingsPauseIcon="@drawable/some_drawable"
app:settingsWallpaperIcon="@drawable/some_drawable"
app:settingsQuizIcon="@drawable/some_drawable"
app:settingsHashtagIcon="@drawable/some_drawable"
app:settingsFilterTextColor="@color/some_color"
app:settingsQuizTextColor="@color/some_color"
app:timeRemainingTextColor="@color/some_color"
app:timeRemainingIcon="@drawable/some_drawable"
app:timeIntervalTextColor="@color/some_color"
app:timeIntervalIcon="@drawable/some_drawable"
app:createChatBackground="@drawable/some_drawable"
app:storeIcon="@drawable/some_drawable"
/>
Explanation:
app:chatBackground
- Sets the background for the entire chat view as a drawableapp:headerBackground
- Sets the background for the header view as a colorapp:headerTextColor
- Sets the text color for the header text as a colorapp:viewerCountIcon
- Sets the image/icon for the number of viewers as a drawableapp:viewerCountTextColor
- Sets the text color for the number of viewers as a colorapp:viewerCountBackground
- Sets the background for the number of viewers as a drawableapp:tvShowProgressBarDrawable
- Sets the background for the show progress as a drawableapp:settingsFilterBackground
- Sets the background for the filter button as a drawableapp:settingsPauseBackground
- Sets the background for the pause button as a drawableapp:settingsWallpaperBackground
- Sets the background for the wallpaper button as a drawableapp:settingsQuizBackground
- Sets the background for the quiz button as a drawableapp:settingsHashtagBackground
- Sets the background for the hashtag button as a drawableapp:settingsFilterIcon
- Sets the image/icon for the filter button as a drawableapp:settingsPauseIcon
- Sets the image/icon for the pause button as a drawableapp:settingsWallpaperIcon
- Sets the image/icon for the wallpaper button as a drawableapp:settingsQuizIcon
- Sets the image/icon for the quiz button as a drawableapp:settingsHashtagIcon
- Sets the image/icon for the hashtag button as a drawableapp:settingsFilterTextColor
- Sets the text color for the filter button as a colorapp:settingsQuizTextColor
- Sets the text color for the quiz button as a colorapp:timeRemainingTextColor
- Sets the text color for time remaining as a colorapp:timeRemainingIcon
- Sets the image/icon for time remaining as a drawableapp:timeIntervalTextColor
- Sets the text color for time interval as a colorapp:timeIntervalIcon
- Sets the image/icon for time interval as a drawableapp:createChatBackground
- Sets the background for the chat edit text as a drawableapp:storeIcon
- Sets the image/icon for the store button as a drawable
Also, attributes can be customised using the component theme(s). SayTVChatView
, SayTVChatHeaderView
and SayTVProfileView
can all be customised using their themes. For example,
binding.chatView.customizeTheme {
chatBackground = someDrawable
chatMessageBackgroundColor = someInt
chatEventItemBackgroundColor = someInt
quizResultItemBackgroundColor = someInt
chatHintColor = someInt
chatTextColor = someInt
messageInputBackground = someDrawable
mentionsBackground = someDrawable
nextChatButtonTextColor = someInt
nextChatButtonBackground = someInt
nextChatMessageTextColor = someInt
nextChatTitleTextColor = someInt
quizTextColor = someInt
quizTitleTextColor = someInt
quizTitleBackground = someDrawable
quizOptionsTextColor = someInt
quizXButtonTintColor = someInt
quizCollapseButtonTintColor = someInt
quizOptionsButtonTextColor = someInt
quizBackgroundDrawable = someDrawable
quizExpirationTimeBackground = someDrawable
quizOptionsButtonBackground = someDrawable
quizOptionProgressBarNormalColor = someInt
quizOptionProgressBarFilledColor = someInt
}
binding.chatHeaderView.customizeTheme {
chatBackgroundColor = someInt
cardBackground = someDrawable
cardBackgroundColor = someInt
cardElevation = someFloat
viewersCounterTextColor = someInt
viewersCounterIcon = someDrawable
headerDescriptionTextColor = someInt
filtersTextColor = someInt
timeRemainingTextColor = someInt
quizTextColor = someInt
quizTitleTextColor = someInt
quizTitleBackground = someDrawable
quizOptionsTextColor = someInt
quizXButtonTintColor = someInt
quizCollapseButtonTintColor = someInt
quizOptionsButtonTextColor = someInt
quizBackgroundDrawable = someDrawable
quizExpirationTimeBackground = someDrawable
quizOptionsButtonBackground = someDrawable
programTimeTextColor = someInt
progressBarForegroundColor = someInt
progressBarBackgroundColor = someInt
viewerCounterBackground = someDrawable
settingsFilterBackground = someDrawable
settingsPauseBackground = someDrawable
settingsWallpaperBackground = someDrawable
settingsQuizBackground = someDrawable
settingsHashtagBackground = someDrawable
tvShowProgressBarDrawable = someDrawable
quizOptionProgressBarNormalColor = someInt
quizOptionProgressBarFilledColor = someInt
}
binding.profileView.customizeTheme {
rootContainerBackgroundColor = someInt
nameTextColor = someInt
memberSinceTextColor= someInt
profileBadgesBackground = someDrawable
profileInfoLayoutBackground = someDrawable
seeAllEarnedBadgesBackground = someDrawable
seeAllEarnedBadgesBackground = someDrawable
progressBarColor = someInt
}
Components have several methods that can be used to customize different other elements not customizable by the theme. Use this section of the documentation to refer to them.
SayTVChatView
/**
* Set custom text color for the filter bottom sheet title
* @param color Custom color resource
*/
fun setCustomFiltersBottomSheetTitleTextColor(color: Int?)
/**
* Set custom text color for the filter bottom sheet
* @param color Custom color resource
*/
fun setCustomFiltersBottomSheetBodyTextColor(color: Int?)
/**
* Set custom background color for the filter bottom sheet
* @param color Custom color resource
*/
fun setCustomFiltersBottomSheetBackgroundColor(color: Int?)
/**
* Set custom text color for the filter bottom sheet close button
* @param color Custom color resource
*/
fun setCustomFiltersBottomSheetCloseButtonTextColor(color: Int?)
/**
* Set custom text color for the chat rules fragment
* @param color Custom color resource
*/
fun setCustomChatRulesTextColor(color: Int?)
/**
* Set custom text color for the chat rules button
* @param color Custom color resource
*/
fun setCustomChatRulesButtonTextColor(color: Int?)
/**
* Set custom background color for the chat rules button
* @param color Custom color resource
*/
fun setCustomChatRulesButtonColor(color: Int?)
/**
* Set custom background drawable for the chat rules fragment
* @param drawable Custom drawable resource
*/
fun setCustomChatRulesBackgroundDrawable(drawable: Int?)
/**
* Set custom background drawable for the empty chat button
* @param drawable Custom drawable resource
*/
fun setCustomEmptyChatButtonBackgroundDrawable(drawable: Int)
/**
* Set the custom text of the error button
* @param text Custom text
*/
fun setErrorText(text: String)
/**
* Set the custom text of the error view
* @param text Custom text
*/
fun setErrorMessageText(text: String)
/**
* Set the color for the quiz time remaining in normal mode
* @param color The color resource for the quiz time remaining in normal mode
*/
fun setExpirationTimeTextNormalColorValue(color: Int)
/**
* Set the color for the quiz time remaining in expiring mode
* @param color The color resource for the quiz time remaining in expiring mode
*/
fun setExpirationTimeTextExpiringColorValue(color: Int)
/**
* Set the color for the quiz result background
* @param color The color resource for the quiz result background
*/
fun setQuizResultItemBackgroundColorValue(color: Int)
SayTVChatHeaderView
/**
* Set the color for the quiz time remaining in normal mode
* @param color The color resource for the quiz time remaining in normal mode
*/
fun setExpirationTimeTextNormalColorValue(color: Int)
/**
* Set the color for the quiz time remaining in expiring mode
* @param color The color resource for the quiz time remaining in expiring mode
*/
fun setExpirationTimeTextExpiringColorValue(color: Int)
SayTVProfileView
fun setCustomProfileBadgesActivityBackgroundColor(color: Int?)
fun setCustomProfileBadgesActivityProgressBarColor(color: Int?)
fun setCustomProfileBadgesActivityToolBarColor(color: Int?)
fun setCustomProfileBadgesActivityToolBarTextColor(color: Int?)
fun setCustomProfileBadgesActivityToolBarText(text: String?)
fun setCustomProfileBadgesActivityToolBarBackIcon(drawable: Int?)
fun setCustomSelectAvatarActivityBackgroundColor(color: Int?)
fun setCustomSelectAvatarActivityProgressBarColor(color: Int?)
fun setCustomSelectAvatarActivityToolBarColor(color: Int?)
fun setCustomSelectAvatarActivityToolBarTextColor(color: Int?)
fun setCustomSelectAvatarActivityToolBarText(text: String?)
fun setCustomSelectAvatarActivityToolBarBackIcon(drawable: Int?)
Options
- Subscibing to the
ChatActionListener
,ChatHeaderActionListener
andProfileActionListener
can give us access to the realtime changes of a number of properties within the chat, header and profile views, for example active users count, when a comment has been liked, when a first message has been sent, etc. Find below a list of the actions you can listen to through theChatActionListener
,ChatHeaderActionListener
andProfileActionListener
class ChatActivity : AppCompatActivity(), ChatActionListener {
override fun onCreate(savedInstanceState: Bundle?) {
...
binding.chatView.addChatActionListener(this)
...
}
override fun eventSendChat(userId: Int, commentText: String) {
// Do something when the logged in user sends a chat
}
override fun eventAddFavourite(userId: Int, commentId: Long, commentText: String) {
// Do something when a comment is liked/favourited
}
override fun eventEnterChatroom(userId: String, episodeId: Int) {
// Do something when a user subscribes successfully to a chat
}
override fun eventFirstComment(userId: Int, commentText: String) {
// Do something when a user sends the first message
}
override fun eventTenthComment(userId: Int, commentText: String) {
// Do something when a user sends the tenth message
}
override fun eventActiveUsers(activeUsers: Int) {
// Do something with activeUsers count
}
override fun eventOnNextChatClicked() {
// Do something when the next chat button is clicked
}
override fun eventOnUserAnalyticsRequested(analyticsInformation: Map<String, Any?>) {
// Do something when user analytics are available
}
}
class ChatActivity : AppCompatActivity(), ChatHeaderActionListener {
override fun onCreate(savedInstanceState: Bundle?) {
...
binding.chatHeaderView.addChatHeaderActionListener(this)
...
}
override fun eventCreateQuiz(userId: Int, question: String, answer1: String, answer2: String) {
// Do something when quizzes are created
}
override fun eventEnterQuiz(userId: Int, question: String, answer1: String, answer2: String) {
// Do something when quizzes are voted on
}
override fun eventActiveUsers(episodeId: Int, activeUsers: Int) {
// Do something with activeUsers count
}
}
class ChatActivity : AppCompatActivity(), ProfileActionListener {
override fun onCreate(savedInstanceState: Bundle?) {
...
binding.chatHeaderView.addProfileActionListener(this)
...
}
override fun eventViewBadges(userId: Int) {
// Do something when badges are viewed
}
}
- When a link is clicked in the chat view, the link and a subset of relevant metadata is available through the
DeepLinkActionListener
which you can listen on by implementing theDeepLinkActionListener
class ChatActivity : AppCompatActivity(), DeepLinkActionListener {
override fun onCreate(savedInstanceState: Bundle?) {
...
binding.chatHeaderView.addDeepLinkActionListener(this)
...
}
override fun eventWebLink(linkAndMetaDataPayload: Map<String, Any?>) {
// Do something when link is clicked
}
}
User Analytics
Logging user analytics is easy, simply write this piece of code in the eventOnUserAnalyticsRequested()
method after implementing ChatActionListener
as described in options above
class ChatActivity : AppCompatActivity(), ChatActionListener {
override fun onCreate(savedInstanceState: Bundle?) {
...
binding.chatView.addChatActionListener(this)
...
}
override fun eventOnUserAnalyticsRequested(analyticsInformation: Map<String, Any?>) {
val firebaseAnalytics = Firebase.analytics
val bundle = Bundle()
for ((key, value) in analyticsInformation) {
bundle.putString(key, value.toString())
}
firebaseAnalytics.logEvent("SAYTV_CHAT_SUBSCRIPTION", bundle)
}
}
Troubleshooting
Gradle Sync -> Jitpack.io 403 response:
Could not GET 'https://www.jitpack.io/org/bitbucket/square1/saytv_sdk_android/release/1.0.0-alpha01/release-1.0.0-alpha01.pom'. Received status code 403 from server: Forbidden****
Solution: Please check your
JITPACK_AUTH_TOKEN
variable insidegradle.properties
that has been set correctlyChat doesn't load
Solution: Please make sure the SDK initialized correctly and that you called
register
orlogin
methodsWe are not receiving messages - //TODO 😃
SayException.IllegalState
upon registering or logging inSolution: Please make sure the SDK initialized correctly. If you are using our Helper Components, please make sure you have correctly declared them in your
AndroidManifest.xml
Calling the
SayTVChatView
init method on a closed chat will result in an error. If a chat is closed, you need to either reopen it in the Admin panel or start a new chat with an unused externalID. NB: Atttempting to modify the start and end time on a closed chat and reentering the chat will result in an error