diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0a6eb3f1..98531032 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,5 +1,5 @@
# Global owners
-* @pavelreiter @nice-devone/DFO @hendrickson-tyler
+* @pavelreiter @davidberry-nice @nice-devone/DFO @hendrickson-tyler
# CI owners
-.github/workflows/* @pavelreiter @LukasSanda
+.github/workflows/* @pavelreiter @davidberry-nice @LukasSanda
diff --git a/.github/workflows/deploy-javadoc.yml b/.github/workflows/deploy-javadoc.yml
index 1d6ad742..418f5fba 100644
--- a/.github/workflows/deploy-javadoc.yml
+++ b/.github/workflows/deploy-javadoc.yml
@@ -14,16 +14,16 @@ jobs:
steps:
- name: Clone repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin" # aka adopt
- name: Set up Gradle
- uses: gradle/gradle-build-action@v2
+ uses: gradle/gradle-build-action@v3
- name: Run build
run: ./gradlew dokkaHtmlMultiModule -Pandroid.experimental.settings.executionProfile=ci
@@ -31,7 +31,7 @@ jobs:
GPR_USERNAME: ${{ github.repository_owner }}
GPR_TOKEN: ${{ github.token }}
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
with:
name: javadoc-html
path: dist
@@ -42,7 +42,7 @@ jobs:
steps:
- name: Clone repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Prepare Repository
run: |
@@ -50,12 +50,12 @@ jobs:
rm -rf .github .idea .gitignore .chglog
git checkout --orphan static-feature/pages
- - uses: actions/download-artifact@v3
+ - uses: actions/download-artifact@v4
with:
name: javadoc-html
- name: Add & Commit
- uses: EndBug/add-and-commit@v9.1.3
+ uses: EndBug/add-and-commit@v9.1.4
with:
push: origin static-feature/pages --force
message: 'Documentation'
diff --git a/.github/workflows/deploy-tag.yml b/.github/workflows/deploy-tag.yml
index f050ad1e..08379a8d 100644
--- a/.github/workflows/deploy-tag.yml
+++ b/.github/workflows/deploy-tag.yml
@@ -17,16 +17,16 @@ jobs:
steps:
- name: Clone repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin" # aka adopt
- name: Set up Gradle
- uses: gradle/gradle-build-action@v2
+ uses: gradle/gradle-build-action@v3
- name: Append Version
run: |
diff --git a/.gitignore b/.gitignore
index 3fff2ae4..f876ba48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
/local.properties
/.idea/
!/.idea/codeStyles
+!/.idea/copyright
+!/.idea/scopes
.DS_Store
/build
/captures
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77b9c15f..457e8bda 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,53 @@
## [Unreleased]
+## [Unreleased]
+### Bug Fixes
+- Set CustomerId type to String
+- consolidate differing kotlin tool versions on 1.9.21
+- Make date formatting thread safe
+- Use referential equality for enum comparison
+- Cancel start job in case of re-configuration
+- Update Chat to separate prepare and connect actions.
+- Display sender name and read/received status.
+- fix TreeField/CVHierarchicalField to not skip every other level.
+- Update Agent.isTyping only when agent is typing
+- Remove messages with duplicate id from thread
+- fix crash when restore suspended login dialog
+- Sockets created by SDK are tagged for TrafficStats
+- Delay SharedPreferences initialization
+- Fix unreliable unit tests depending on makeMessageModel being sequential
+- fix display of new agent messages
+- Disable sending empty messages. ([#454](https://github.com/nice-devone/nice-cxone-mobile-sdk-android/issues/454))
+- return error when receiving "invalid" server response on image upload
+- BREAKING CHANGE if uploaded filename has no extension, get one using MimeTypeMap
+- Fix crashes on some Qualcomm/Samsung devices
+
+
+### Dependency Change
+- Update Kotlin 1.9.20 -> 1.9.21
+- Bump com.squareup.okhttp3:okhttp from 4.11.0 to 4.12.0
+- Bump androidx.core:core-ktx from 1.10.1 to 1.12.0
+- Update Kotlin 1.8.21 -> 1.9.10
+
+
+### Features
+- Add ProxyLogger constructor with vararg param
+- Improve Java compatibility
+- Raise project compileSdk 33 -> 34
+- Improve logging of outgoing events
+- Pass server reported errors to integration
+- Process events on background thread
+- Allow to change users name
+- Message is updated when read by agent
+- Add seenAt and inferred state to message metadata
+- Add logger-android module
+- Extract logging library module
+- Add option to specify Logger for the SDK
+- Correct welcome message handling
+- replace dagger/hilt with Koin in UI and sample application components
+- Implement CaseStatusChanged event
+
## [1.2.1]
diff --git a/build.gradle b/build.gradle
index e0fd251a..7eb8dab3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,17 +8,20 @@ plugins {
id "com.android.library" version "$androidGradlePluginVersion" apply false
id "com.android.application" version "$androidGradlePluginVersion" apply false
id "org.jetbrains.dokka" version "$dokkaVersion" apply true
- id "com.vanniktech.maven.publish" version "0.25.3" apply false
- id "com.google.gms.google-services" version "4.3.15" apply false
- id "androidx.navigation.safeargs" version "2.6.0" apply false
+ id "com.vanniktech.maven.publish" version "0.27.0" apply false
+ id "com.google.gms.google-services" version "4.4.1" apply false
+ id "androidx.navigation.safeargs" version "2.7.7" apply false
id "io.gitlab.arturbosch.detekt" version "$detektVersion"
- id "nl.neotech.plugin.rootcoverage" version "1.6.0" apply false
+ id "nl.neotech.plugin.rootcoverage" version "1.7.1" apply false
id "com.dipien.semantic-version" version "2.0.0" apply false
- id "com.google.dagger.hilt.android" version "$daggerHiltVersion" apply false
+ id "com.google.firebase.appdistribution" version "4.0.1" apply false
+ id 'com.google.firebase.crashlytics' version '2.9.9' apply false
+ id "com.google.devtools.ksp" version "1.9.22-1.0.17" apply false
+ id "me.tylerbwong.gradle.metalava" version "0.3.5" apply false
}
group = GROUP
-version = "1.2.0" // Fallback version
+version = "1.3.0" // Fallback version
allprojects {
group = rootProject.group
@@ -34,6 +37,14 @@ tasks.dokkaHtmlMultiModule.configure {
outputDirectory.set(project.file("dist"))
}
+tasks.register('metalavaGenerateSignature') {
+ dependsOn subprojects.collect { it.tasks.matching { it.name == "metalavaGenerateSignatureRelease" } }
+}
+
+tasks.register('metalavaCheckCompatibility') {
+ dependsOn subprojects.collect { it.tasks.matching { it.name == "metalavaCheckCompatibilityRelease" } }
+}
+
// Disabled until the support for AGP 8 is resolved - https://github.com/NeoTech-Software/Android-Root-Coverage-Plugin/issues/82
//rootCoverage {
// generateXml true
diff --git a/buildSrc/src/main/groovy/android-application-conventions.gradle b/buildSrc/src/main/groovy/android-application-conventions.gradle
index fde995d1..f93306a4 100644
--- a/buildSrc/src/main/groovy/android-application-conventions.gradle
+++ b/buildSrc/src/main/groovy/android-application-conventions.gradle
@@ -5,7 +5,12 @@ plugins {
android {
defaultConfig {
- targetSdk 33
+ targetSdk 34
}
+ packagingOptions {
+ dex {
+ useLegacyPackaging false
+ }
+ }
}
diff --git a/buildSrc/src/main/groovy/android-docs-conventions.gradle b/buildSrc/src/main/groovy/android-docs-conventions.gradle
new file mode 100644
index 00000000..b5c5c401
--- /dev/null
+++ b/buildSrc/src/main/groovy/android-docs-conventions.gradle
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+plugins {
+ id "docs-conventions"
+}
+
+dokkaHtml {
+ configure {
+ dokkaSourceSets {
+ named("main") {
+ noAndroidSdkLink.set(false)
+ }
+ }
+ }
+}
diff --git a/chat-sdk-ui/src/main/java/com/nice/cxonechat/ui/di/ServiceBindings.kt b/buildSrc/src/main/groovy/android-kotlin-conventions.gradle
similarity index 57%
rename from chat-sdk-ui/src/main/java/com/nice/cxonechat/ui/di/ServiceBindings.kt
rename to buildSrc/src/main/groovy/android-kotlin-conventions.gradle
index babda3a4..30251172 100644
--- a/chat-sdk-ui/src/main/java/com/nice/cxonechat/ui/di/ServiceBindings.kt
+++ b/buildSrc/src/main/groovy/android-kotlin-conventions.gradle
@@ -13,18 +13,25 @@
* FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
*/
-package com.nice.cxonechat.ui.di
+plugins {
+ id "kotlin-android"
+ id "kotlin-conventions"
+}
+
+android {
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_11
+ targetCompatibility JavaVersion.VERSION_11
+ }
-import com.nice.cxonechat.ui.data.PinpointPushMessageParser
-import com.nice.cxonechat.ui.domain.PushMessageParser
-import dagger.Binds
-import dagger.Module
-import dagger.hilt.InstallIn
-import dagger.hilt.android.components.ServiceComponent
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+
+}
-@Module
-@InstallIn(ServiceComponent::class)
-internal interface ServiceBindings {
- @Binds
- fun pushParser(pinpointPushMessageParser: PinpointPushMessageParser): PushMessageParser
+kotlin {
+ // Required to make kapt use same JVM target as compiler
+ jvmToolchain(11)
}
diff --git a/buildSrc/src/main/groovy/android-library-conventions.gradle b/buildSrc/src/main/groovy/android-library-conventions.gradle
index 245fb924..9edab511 100644
--- a/buildSrc/src/main/groovy/android-library-conventions.gradle
+++ b/buildSrc/src/main/groovy/android-library-conventions.gradle
@@ -5,6 +5,6 @@ plugins {
android {
defaultConfig {
- targetSdk 33
+ targetSdk 34
}
}
diff --git a/buildSrc/src/main/groovy/android-library-style-conventions.gradle b/buildSrc/src/main/groovy/android-library-style-conventions.gradle
new file mode 100644
index 00000000..6ba72ce6
--- /dev/null
+++ b/buildSrc/src/main/groovy/android-library-style-conventions.gradle
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+plugins {
+ id "kotlin-android"
+ id "library-style-conventions"
+}
+
+android {
+ lint {
+ htmlReport true
+
+ enable "CheckResult"
+ baseline = file("lint-baseline.xml")
+ }
+}
diff --git a/buildSrc/src/main/groovy/android-test-conventions.gradle b/buildSrc/src/main/groovy/android-test-conventions.gradle
new file mode 100644
index 00000000..eda976a3
--- /dev/null
+++ b/buildSrc/src/main/groovy/android-test-conventions.gradle
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+plugins {
+ id "test-conventions"
+}
+
+android {
+ defaultConfig {
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ debug {
+ enableUnitTestCoverage true
+ }
+ }
+}
+
+dependencies {
+ androidTestImplementation "androidx.test:runner:1.5.2"
+ androidTestImplementation "androidx.test.espresso:espresso-core:3.5.1"
+}
diff --git a/buildSrc/src/main/groovy/android-ui-conventions.gradle b/buildSrc/src/main/groovy/android-ui-conventions.gradle
index 4d58a49f..daf97aee 100644
--- a/buildSrc/src/main/groovy/android-ui-conventions.gradle
+++ b/buildSrc/src/main/groovy/android-ui-conventions.gradle
@@ -14,16 +14,14 @@ android {
dependencies {
implementation "androidx.appcompat:appcompat:1.6.1"
- implementation "androidx.core:core-ktx:1.10.1"
+ implementation "androidx.core:core-ktx:1.12.0"
implementation "androidx.datastore:datastore-preferences:1.0.0"
- implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.1"
- implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
- implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
//Navigation
- def axNavigationVersion = "2.6.0"
+ def axNavigationVersion = "2.7.3"
implementation "androidx.navigation:navigation-fragment-ktx:$axNavigationVersion"
implementation "androidx.navigation:navigation-ui-ktx:$axNavigationVersion"
implementation "androidx.navigation:navigation-runtime-ktx:$axNavigationVersion"
diff --git a/buildSrc/src/main/groovy/api-conventions.gradle b/buildSrc/src/main/groovy/api-conventions.gradle
new file mode 100644
index 00000000..2b98f686
--- /dev/null
+++ b/buildSrc/src/main/groovy/api-conventions.gradle
@@ -0,0 +1,8 @@
+plugins {
+ id "me.tylerbwong.gradle.metalava"
+}
+
+metalava {
+ reportWarningsAsErrors.set(true)
+ reportLintsAsErrors.set(true)
+}
diff --git a/buildSrc/src/main/groovy/docs-conventions.gradle b/buildSrc/src/main/groovy/docs-conventions.gradle
index dc741873..fc731469 100644
--- a/buildSrc/src/main/groovy/docs-conventions.gradle
+++ b/buildSrc/src/main/groovy/docs-conventions.gradle
@@ -1,17 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
plugins {
id "org.jetbrains.dokka"
}
-dokkaHtml {
- configure {
- dokkaSourceSets {
- named("main") {
- noAndroidSdkLink.set(false)
- }
- }
- }
-}
-
dependencies {
dokkaHtmlPlugin "org.jetbrains.dokka:kotlin-as-java-plugin:$dokkaVersion"
}
diff --git a/buildSrc/src/main/groovy/java-library-conventions.gradle b/buildSrc/src/main/groovy/java-library-conventions.gradle
new file mode 100644
index 00000000..05bcaade
--- /dev/null
+++ b/buildSrc/src/main/groovy/java-library-conventions.gradle
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+plugins {
+ id("java-library")
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+}
diff --git a/buildSrc/src/main/groovy/jvm-kotlin-conventions.gradle b/buildSrc/src/main/groovy/jvm-kotlin-conventions.gradle
new file mode 100644
index 00000000..002f9403
--- /dev/null
+++ b/buildSrc/src/main/groovy/jvm-kotlin-conventions.gradle
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+plugins {
+ id("org.jetbrains.kotlin.jvm")
+}
+
+kotlin {
+ jvmToolchain(11)
+}
diff --git a/buildSrc/src/main/groovy/kapt-conventions.gradle b/buildSrc/src/main/groovy/kapt-conventions.gradle
deleted file mode 100644
index b8f749a2..00000000
--- a/buildSrc/src/main/groovy/kapt-conventions.gradle
+++ /dev/null
@@ -1,8 +0,0 @@
-plugins {
- id "kotlin-kapt"
-}
-
-// Allow references to generated code
-kapt {
- correctErrorTypes = true
-}
diff --git a/buildSrc/src/main/groovy/koin-conventions.gradle b/buildSrc/src/main/groovy/koin-conventions.gradle
new file mode 100644
index 00000000..1beb9b17
--- /dev/null
+++ b/buildSrc/src/main/groovy/koin-conventions.gradle
@@ -0,0 +1,11 @@
+dependencies {
+ def koinVersion = "3.5.1"
+ def koinAndroidVersion = "3.5.0"
+ def koinAnnotationsVersion = "1.3.0"
+
+ implementation platform("io.insert-koin:koin-bom:$koinVersion")
+ implementation "io.insert-koin:koin-android:$koinAndroidVersion"
+
+ implementation "io.insert-koin:koin-annotations:$koinAnnotationsVersion"
+ ksp "io.insert-koin:koin-ksp-compiler:$koinAnnotationsVersion"
+}
diff --git a/buildSrc/src/main/groovy/kotlin-conventions.gradle b/buildSrc/src/main/groovy/kotlin-conventions.gradle
index 25c89a46..5e480225 100644
--- a/buildSrc/src/main/groovy/kotlin-conventions.gradle
+++ b/buildSrc/src/main/groovy/kotlin-conventions.gradle
@@ -1,28 +1,21 @@
-plugins {
- id "kotlin-android"
-}
-
-android {
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
-
- kotlinOptions {
- jvmTarget = "11"
- }
-
-}
-
-kotlin {
- // Required to make kapt use same JVM target as compiler
- jvmToolchain(11)
-}
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
- implementation "org.jetbrains:annotations:13.0"
+ implementation "org.jetbrains:annotations:23.0.0"
}
diff --git a/buildSrc/src/main/groovy/ksp-conventions.gradle b/buildSrc/src/main/groovy/ksp-conventions.gradle
new file mode 100644
index 00000000..0d141ef4
--- /dev/null
+++ b/buildSrc/src/main/groovy/ksp-conventions.gradle
@@ -0,0 +1,3 @@
+plugins {
+ id "com.google.devtools.ksp"
+}
diff --git a/buildSrc/src/main/groovy/library-style-conventions.gradle b/buildSrc/src/main/groovy/library-style-conventions.gradle
index 0bd49fe2..1eae3bdc 100644
--- a/buildSrc/src/main/groovy/library-style-conventions.gradle
+++ b/buildSrc/src/main/groovy/library-style-conventions.gradle
@@ -1,6 +1,20 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
plugins {
id "io.gitlab.arturbosch.detekt"
- id "kotlin-android"
}
detekt {
@@ -12,14 +26,6 @@ detekt {
ignoredBuildTypes = ["release"]
}
-android {
- lint {
- htmlReport true
-
- enable "CheckResult"
- }
-}
-
dependencies {
detektPlugins "io.gitlab.arturbosch.detekt:detekt-formatting:$detektVersion"
detektPlugins "io.gitlab.arturbosch.detekt:detekt-rules-libraries:$detektVersion"
diff --git a/buildSrc/src/main/groovy/test-conventions.gradle b/buildSrc/src/main/groovy/test-conventions.gradle
index 34c19232..0640a11d 100644
--- a/buildSrc/src/main/groovy/test-conventions.gradle
+++ b/buildSrc/src/main/groovy/test-conventions.gradle
@@ -1,26 +1,22 @@
-android {
- defaultConfig {
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- }
- buildTypes {
- debug {
- enableUnitTestCoverage true
- }
- }
-}
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
dependencies {
-
+ testImplementation "io.github.diareuse:strucut:[1,2["
+ testImplementation "io.mockk:mockk:1.13.8"
testImplementation "junit:junit:4.13.2"
- testImplementation "org.mockito:mockito-core:3.12.4"
- testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
- testImplementation "org.mockito:mockito-inline:3.11.2"
- testImplementation "io.mockk:mockk:1.13.5"
- testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
testImplementation "org.jetbrains.kotlin:kotlin-reflect"
- testImplementation "io.github.diareuse:strucut:[1,2["
-
- androidTestImplementation "com.android.support.test:runner:1.0.2"
- androidTestImplementation "com.android.support.test.espresso:espresso-core:3.0.2"
-
+ testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
}
diff --git a/buildSrc/src/main/groovy/ui-compose-conventions.gradle b/buildSrc/src/main/groovy/ui-compose-conventions.gradle
index 459d693c..eb2573d0 100644
--- a/buildSrc/src/main/groovy/ui-compose-conventions.gradle
+++ b/buildSrc/src/main/groovy/ui-compose-conventions.gradle
@@ -4,20 +4,19 @@ android {
}
composeOptions {
- kotlinCompilerExtensionVersion = "1.4.7"
+ kotlinCompilerExtensionVersion = "1.5.8"
}
}
dependencies {
// Compose
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
- implementation platform('androidx.compose:compose-bom:2023.06.01')
+ implementation platform('androidx.compose:compose-bom:2023.10.01')
implementation "androidx.activity:activity-compose:1.7.2"
implementation "androidx.compose.material:material"
implementation "androidx.compose.material:material-icons-extended"
- implementation "androidx.compose.runtime:runtime-livedata"
- implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.1"
- implementation "androidx.compose.ui:ui:1.5.0-beta03" // Override to newer version
+ implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.2"
+ implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-graphics"
implementation "androidx.compose.ui:ui-tooling-preview"
diff --git a/chat-sdk-core/api.txt b/chat-sdk-core/api.txt
new file mode 100644
index 00000000..72690b6d
--- /dev/null
+++ b/chat-sdk-core/api.txt
@@ -0,0 +1,1043 @@
+// Signature format: 4.0
+package com.nice.cxonechat {
+
+ @com.nice.cxonechat.Public public interface Authorization {
+ method public default static operator com.nice.cxonechat.Authorization create(String code, String verifier);
+ method public String getCode();
+ method public String getVerifier();
+ property public abstract String code;
+ property public abstract String verifier;
+ field public static final com.nice.cxonechat.Authorization.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class Authorization.Companion {
+ method public operator com.nice.cxonechat.Authorization create(String code, String verifier);
+ }
+
+ @com.nice.cxonechat.Public public fun interface Cancellable {
+ method public void cancel();
+ field public static final com.nice.cxonechat.Cancellable.Companion Companion;
+ }
+
+ public static final class Cancellable.Companion {
+ }
+
+ @com.nice.cxonechat.Public public interface Chat extends java.lang.AutoCloseable {
+ method public com.nice.cxonechat.ChatActionHandler actions();
+ method public void close();
+ method public com.nice.cxonechat.Cancellable connect();
+ method public com.nice.cxonechat.ChatFieldHandler customFields();
+ method public com.nice.cxonechat.ChatEventHandler events();
+ method public default com.nice.cxonechat.ChatMode getChatMode();
+ method public com.nice.cxonechat.state.Configuration getConfiguration();
+ method public com.nice.cxonechat.state.Environment getEnvironment();
+ method public java.util.Collection getFields();
+ method @Deprecated public com.nice.cxonechat.Cancellable reconnect();
+ method public void setDeviceToken(String? token);
+ method public void setUserName(String firstName, String lastName);
+ method public void signOut();
+ method public com.nice.cxonechat.ChatThreadsHandler threads();
+ property public default com.nice.cxonechat.ChatMode chatMode;
+ property public abstract com.nice.cxonechat.state.Configuration configuration;
+ property public abstract com.nice.cxonechat.state.Environment environment;
+ property public abstract java.util.Collection fields;
+ }
+
+ @com.nice.cxonechat.Public public interface ChatActionHandler extends java.lang.AutoCloseable {
+ method public void close();
+ method public void onPopup(com.nice.cxonechat.ChatActionHandler.OnPopupActionListener listener);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatActionHandler.OnPopupActionListener {
+ method public void onShowPopup(java.util.Map variables, com.nice.cxonechat.analytics.ActionMetadata metadata);
+ }
+
+ @com.nice.cxonechat.Public public interface ChatBuilder {
+ method @Deprecated @CheckResult public com.nice.cxonechat.Cancellable build(com.nice.cxonechat.ChatBuilder.OnChatBuiltCallback callback);
+ method @CheckResult public com.nice.cxonechat.Cancellable build(com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback resultCallback);
+ method public default static operator com.nice.cxonechat.ChatBuilder getDefault(android.content.Context context, com.nice.cxonechat.SocketFactoryConfiguration config);
+ method public default static operator com.nice.cxonechat.ChatBuilder getDefault(android.content.Context context, com.nice.cxonechat.SocketFactoryConfiguration config, optional com.nice.cxonechat.log.Logger logger);
+ method public com.nice.cxonechat.ChatBuilder setAuthorization(com.nice.cxonechat.Authorization authorization);
+ method public com.nice.cxonechat.ChatBuilder setChatStateListener(com.nice.cxonechat.ChatStateListener listener);
+ method public com.nice.cxonechat.ChatBuilder setDevelopmentMode(boolean enabled);
+ method public com.nice.cxonechat.ChatBuilder setDeviceToken(String token);
+ method public com.nice.cxonechat.ChatBuilder setUserName(String first, String last);
+ field public static final com.nice.cxonechat.ChatBuilder.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class ChatBuilder.Companion {
+ method public operator com.nice.cxonechat.ChatBuilder getDefault(android.content.Context context, com.nice.cxonechat.SocketFactoryConfiguration config);
+ method public operator com.nice.cxonechat.ChatBuilder getDefault(android.content.Context context, com.nice.cxonechat.SocketFactoryConfiguration config, optional com.nice.cxonechat.log.Logger logger);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatBuilder.OnChatBuiltCallback {
+ method public void onChatBuilt(com.nice.cxonechat.Chat chat);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatBuilder.OnChatBuiltResultCallback {
+ method public void onChatBuiltResult(Object chat);
+ }
+
+ @com.nice.cxonechat.Public public interface ChatEventHandler {
+ method public void trigger(com.nice.cxonechat.event.ChatEvent event, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatEventHandler.OnEventErrorListener {
+ method public void onError(com.nice.cxonechat.exceptions.CXOneException exception);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatEventHandler.OnEventSentListener {
+ method public void onSent();
+ }
+
+ @com.nice.cxonechat.Public public final class ChatEventHandlerActions {
+ method @com.nice.cxonechat.Public public static void chatWindowOpen(com.nice.cxonechat.ChatEventHandler);
+ method @com.nice.cxonechat.Public public static void chatWindowOpen(com.nice.cxonechat.ChatEventHandler, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void chatWindowOpen(com.nice.cxonechat.ChatEventHandler, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void chatWindowOpen(com.nice.cxonechat.ChatEventHandler, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void conversion(com.nice.cxonechat.ChatEventHandler, String type, Number value);
+ method @com.nice.cxonechat.Public public static void conversion(com.nice.cxonechat.ChatEventHandler, String type, Number value, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void conversion(com.nice.cxonechat.ChatEventHandler, String type, Number value, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void conversion(com.nice.cxonechat.ChatEventHandler, String type, Number value, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void customVisitor(com.nice.cxonechat.ChatEventHandler, Object data);
+ method @com.nice.cxonechat.Public public static void customVisitor(com.nice.cxonechat.ChatEventHandler, Object data, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void customVisitor(com.nice.cxonechat.ChatEventHandler, Object data, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method public static void event(com.nice.cxonechat.ChatEventHandler, java.util.UUID id);
+ method public static void event(com.nice.cxonechat.ChatEventHandler, java.util.UUID id, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method public static void event(com.nice.cxonechat.ChatEventHandler, java.util.UUID id, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void pageView(com.nice.cxonechat.ChatEventHandler, String title, String uri);
+ method @com.nice.cxonechat.Public public static void pageView(com.nice.cxonechat.ChatEventHandler, String title, String uri, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void pageView(com.nice.cxonechat.ChatEventHandler, String title, String uri, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void pageView(com.nice.cxonechat.ChatEventHandler, String title, String uri, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void pageViewEnded(com.nice.cxonechat.ChatEventHandler, String title, String uri);
+ method @com.nice.cxonechat.Public public static void pageViewEnded(com.nice.cxonechat.ChatEventHandler, String title, String uri, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void pageViewEnded(com.nice.cxonechat.ChatEventHandler, String title, String uri, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void pageViewEnded(com.nice.cxonechat.ChatEventHandler, String title, String uri, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void proactiveActionClick(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data);
+ method @com.nice.cxonechat.Public public static void proactiveActionClick(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void proactiveActionClick(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void proactiveActionClick(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void proactiveActionDisplay(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data);
+ method @com.nice.cxonechat.Public public static void proactiveActionDisplay(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void proactiveActionDisplay(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void proactiveActionDisplay(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void proactiveActionFailure(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data);
+ method @com.nice.cxonechat.Public public static void proactiveActionFailure(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void proactiveActionFailure(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void proactiveActionFailure(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method @com.nice.cxonechat.Public public static void proactiveActionSuccess(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data);
+ method @com.nice.cxonechat.Public public static void proactiveActionSuccess(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date);
+ method @com.nice.cxonechat.Public public static void proactiveActionSuccess(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method @com.nice.cxonechat.Public public static void proactiveActionSuccess(com.nice.cxonechat.ChatEventHandler, com.nice.cxonechat.analytics.ActionMetadata data, optional java.util.Date date, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ method public static void refresh(com.nice.cxonechat.ChatEventHandler);
+ method public static void refresh(com.nice.cxonechat.ChatEventHandler, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener);
+ method public static void refresh(com.nice.cxonechat.ChatEventHandler, optional com.nice.cxonechat.ChatEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatEventHandler.OnEventErrorListener? errorListener);
+ field public static final com.nice.cxonechat.ChatEventHandlerActions INSTANCE;
+ }
+
+ @com.nice.cxonechat.Public public interface ChatFieldHandler {
+ method @kotlin.jvm.Throws(exceptionClasses={InvalidCustomFieldValue::class, UndefinedCustomField::class}) public void add(java.util.Map fields) throws com.nice.cxonechat.exceptions.InvalidCustomFieldValue, com.nice.cxonechat.exceptions.UndefinedCustomField;
+ }
+
+ @com.nice.cxonechat.Public public final class ChatInstanceProvider implements com.nice.cxonechat.ChatStateListener com.nice.cxonechat.log.LoggerScope {
+ method public void addListener(com.nice.cxonechat.ChatInstanceProvider.Listener listener);
+ method public void cancel();
+ method public void close();
+ method public void configure(android.content.Context context, kotlin.jvm.functions.Function1 super com.nice.cxonechat.ChatInstanceProvider.ConfigurationScope,kotlin.Unit> actions);
+ method @kotlin.jvm.Throws(exceptionClasses=InvalidStateException::class) public void connect() throws com.nice.cxonechat.exceptions.InvalidStateException;
+ method public com.nice.cxonechat.Authorization? getAuthorization();
+ method public com.nice.cxonechat.Chat? getChat();
+ method public com.nice.cxonechat.ChatState getChatState();
+ method public com.nice.cxonechat.SocketFactoryConfiguration? getConfiguration();
+ method public boolean getDevelopmentMode();
+ method public com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider? getDeviceTokenProvider();
+ method public com.nice.cxonechat.log.Logger getIdentity();
+ method public com.nice.cxonechat.log.Logger getLogger();
+ method public com.nice.cxonechat.UserName? getUserName();
+ method public void onChatRuntimeException(com.nice.cxonechat.exceptions.RuntimeChatException exception);
+ method public void onConnected();
+ method public void onReady();
+ method public void onUnexpectedDisconnect();
+ method @kotlin.jvm.Throws(exceptionClasses=InvalidStateException::class) public void prepare(android.content.Context context) throws com.nice.cxonechat.exceptions.InvalidStateException;
+ method @kotlin.jvm.Throws(exceptionClasses=InvalidStateException::class) public void prepare(android.content.Context context, optional com.nice.cxonechat.SocketFactoryConfiguration? newConfig) throws com.nice.cxonechat.exceptions.InvalidStateException;
+ method @Deprecated @kotlin.jvm.Throws(exceptionClasses=InvalidStateException::class) public void reconnect() throws com.nice.cxonechat.exceptions.InvalidStateException;
+ method public void removeListener(com.nice.cxonechat.ChatInstanceProvider.Listener listener);
+ method public com.nice.cxonechat.ChatInstanceProvider setCustomerValues(java.util.Map values);
+ method public void setUserName(com.nice.cxonechat.UserName name);
+ method public void signOut();
+ property public final com.nice.cxonechat.Authorization? authorization;
+ property public final com.nice.cxonechat.Chat? chat;
+ property public final com.nice.cxonechat.ChatState chatState;
+ property public final com.nice.cxonechat.SocketFactoryConfiguration? configuration;
+ property public final boolean developmentMode;
+ property public final com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider? deviceTokenProvider;
+ property public com.nice.cxonechat.log.Logger identity;
+ property public final com.nice.cxonechat.log.Logger logger;
+ property public final com.nice.cxonechat.UserName? userName;
+ field public static final com.nice.cxonechat.ChatInstanceProvider.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class ChatInstanceProvider.Companion {
+ method public com.nice.cxonechat.ChatInstanceProvider create(com.nice.cxonechat.SocketFactoryConfiguration? configuration);
+ method public com.nice.cxonechat.ChatInstanceProvider create(com.nice.cxonechat.SocketFactoryConfiguration? configuration, optional com.nice.cxonechat.Authorization? authorization);
+ method public com.nice.cxonechat.ChatInstanceProvider create(com.nice.cxonechat.SocketFactoryConfiguration? configuration, optional com.nice.cxonechat.Authorization? authorization, optional com.nice.cxonechat.UserName? userName);
+ method public com.nice.cxonechat.ChatInstanceProvider create(com.nice.cxonechat.SocketFactoryConfiguration? configuration, optional com.nice.cxonechat.Authorization? authorization, optional com.nice.cxonechat.UserName? userName, optional boolean developmentMode);
+ method public com.nice.cxonechat.ChatInstanceProvider create(com.nice.cxonechat.SocketFactoryConfiguration? configuration, optional com.nice.cxonechat.Authorization? authorization, optional com.nice.cxonechat.UserName? userName, optional boolean developmentMode, optional com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider? deviceTokenProvider);
+ method public com.nice.cxonechat.ChatInstanceProvider create(com.nice.cxonechat.SocketFactoryConfiguration? configuration, optional com.nice.cxonechat.Authorization? authorization, optional com.nice.cxonechat.UserName? userName, optional boolean developmentMode, optional com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider? deviceTokenProvider, optional com.nice.cxonechat.log.Logger logger);
+ method public com.nice.cxonechat.ChatInstanceProvider get();
+ }
+
+ @com.nice.cxonechat.Public public static interface ChatInstanceProvider.ConfigurationScope {
+ method public boolean getAuthenticationRequired();
+ method public com.nice.cxonechat.Authorization? getAuthorization();
+ method public com.nice.cxonechat.SocketFactoryConfiguration? getConfiguration();
+ method public boolean getDevelopmentMode();
+ method public com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider? getDeviceTokenProvider();
+ method public com.nice.cxonechat.log.Logger getLogger();
+ method public com.nice.cxonechat.UserName? getUserName();
+ method public void setAuthorization(com.nice.cxonechat.Authorization?);
+ method public void setConfiguration(com.nice.cxonechat.SocketFactoryConfiguration?);
+ method public void setDevelopmentMode(boolean);
+ method public void setDeviceTokenProvider(com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider?);
+ method public void setLogger(com.nice.cxonechat.log.Logger);
+ method public void setUserName(com.nice.cxonechat.UserName?);
+ property public abstract boolean authenticationRequired;
+ property public abstract com.nice.cxonechat.Authorization? authorization;
+ property public abstract com.nice.cxonechat.SocketFactoryConfiguration? configuration;
+ property public abstract boolean developmentMode;
+ property public abstract com.nice.cxonechat.ChatInstanceProvider.DeviceTokenProvider? deviceTokenProvider;
+ property public abstract com.nice.cxonechat.log.Logger logger;
+ property public abstract com.nice.cxonechat.UserName? userName;
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatInstanceProvider.DeviceTokenProvider {
+ method public void requestDeviceToken(kotlin.jvm.functions.Function1 super java.lang.String,kotlin.Unit> onComplete);
+ }
+
+ @com.nice.cxonechat.Public public static interface ChatInstanceProvider.Listener {
+ method public default void onChatChanged(com.nice.cxonechat.Chat? chat);
+ method public default void onChatRuntimeException(com.nice.cxonechat.exceptions.RuntimeChatException exception);
+ method public default void onChatStateChanged(com.nice.cxonechat.ChatState chatState);
+ }
+
+ @com.nice.cxonechat.Public public enum ChatMode {
+ method public static com.nice.cxonechat.ChatMode valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.ChatMode[] values();
+ enum_constant public static final com.nice.cxonechat.ChatMode MULTI_THREAD;
+ enum_constant public static final com.nice.cxonechat.ChatMode SINGLE_THREAD;
+ }
+
+ @com.nice.cxonechat.Public public enum ChatState {
+ method public static com.nice.cxonechat.ChatState valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.ChatState[] values();
+ enum_constant public static final com.nice.cxonechat.ChatState CONNECTED;
+ enum_constant public static final com.nice.cxonechat.ChatState CONNECTING;
+ enum_constant public static final com.nice.cxonechat.ChatState CONNECTION_LOST;
+ enum_constant public static final com.nice.cxonechat.ChatState INITIAL;
+ enum_constant public static final com.nice.cxonechat.ChatState PREPARED;
+ enum_constant public static final com.nice.cxonechat.ChatState PREPARING;
+ enum_constant public static final com.nice.cxonechat.ChatState READY;
+ }
+
+ @com.nice.cxonechat.Public public interface ChatStateListener {
+ method public void onChatRuntimeException(com.nice.cxonechat.exceptions.RuntimeChatException exception);
+ method public void onConnected();
+ method public void onReady();
+ method public void onUnexpectedDisconnect();
+ }
+
+ @com.nice.cxonechat.Public public interface ChatThreadEventHandler {
+ method public void trigger(com.nice.cxonechat.event.thread.ChatThreadEvent event, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener? errorListener);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatThreadEventHandler.OnEventErrorListener {
+ method public void onError(com.nice.cxonechat.exceptions.CXOneException exception);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatThreadEventHandler.OnEventSentListener {
+ method public void onSent();
+ }
+
+ @com.nice.cxonechat.Public public final class ChatThreadEventHandlerActions {
+ method public static void archiveThread(com.nice.cxonechat.ChatThreadEventHandler);
+ method public static void archiveThread(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener);
+ method public static void archiveThread(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener? errorListener);
+ method public static void loadMetadata(com.nice.cxonechat.ChatThreadEventHandler);
+ method public static void loadMetadata(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener);
+ method public static void loadMetadata(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener? errorListener);
+ method public static void markThreadRead(com.nice.cxonechat.ChatThreadEventHandler);
+ method public static void markThreadRead(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener);
+ method public static void markThreadRead(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener? errorListener);
+ method public static void typingEnd(com.nice.cxonechat.ChatThreadEventHandler);
+ method public static void typingEnd(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener);
+ method public static void typingEnd(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener? errorListener);
+ method public static void typingStart(com.nice.cxonechat.ChatThreadEventHandler);
+ method public static void typingStart(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener);
+ method public static void typingStart(com.nice.cxonechat.ChatThreadEventHandler, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener? listener, optional com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener? errorListener);
+ field public static final com.nice.cxonechat.ChatThreadEventHandlerActions INSTANCE;
+ }
+
+ @com.nice.cxonechat.Public public interface ChatThreadHandler {
+ method public com.nice.cxonechat.ChatFieldHandler customFields();
+ method public com.nice.cxonechat.ChatThreadEventHandler events();
+ method public com.nice.cxonechat.thread.ChatThread get();
+ method @CheckResult public com.nice.cxonechat.Cancellable get(com.nice.cxonechat.ChatThreadHandler.OnThreadUpdatedListener listener);
+ method public com.nice.cxonechat.ChatThreadMessageHandler messages();
+ method public void refresh();
+ method public void setName(String name);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatThreadHandler.OnThreadUpdatedListener {
+ method public void onUpdated(com.nice.cxonechat.thread.ChatThread thread);
+ }
+
+ @com.nice.cxonechat.Public public interface ChatThreadMessageHandler {
+ method public void loadMore();
+ method public void send(com.nice.cxonechat.message.OutboundMessage message, optional com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener? listener);
+ method public default void send(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments, optional String message, optional String? postback, optional com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener? listener);
+ method public default void send(String message, optional String? postback, optional com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener? listener);
+ }
+
+ @com.nice.cxonechat.Public public static interface ChatThreadMessageHandler.OnMessageTransferListener {
+ method public default static operator com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener createFrom(optional com.nice.cxonechat.ChatThreadMessageHandler.OnUUIDListener? onProcessed, optional com.nice.cxonechat.ChatThreadMessageHandler.OnUUIDListener? onSent);
+ method public default void onProcessed(java.util.UUID id);
+ method public default void onSent(java.util.UUID id);
+ field public static final com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class ChatThreadMessageHandler.OnMessageTransferListener.Companion {
+ method public operator com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener createFrom(optional com.nice.cxonechat.ChatThreadMessageHandler.OnUUIDListener? onProcessed, optional com.nice.cxonechat.ChatThreadMessageHandler.OnUUIDListener? onSent);
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatThreadMessageHandler.OnUUIDListener {
+ method public void onTriggered(java.util.UUID id);
+ }
+
+ @com.nice.cxonechat.Public public interface ChatThreadsHandler {
+ method @kotlin.jvm.Throws(exceptionClasses={UnsupportedChannelConfigException::class, MissingThreadListFetchException::class, MissingPreChatCustomFieldsException::class, InvalidCustomFieldValue::class, UndefinedCustomField::class}) public default com.nice.cxonechat.ChatThreadHandler create() throws com.nice.cxonechat.exceptions.InvalidCustomFieldValue, com.nice.cxonechat.exceptions.MissingPreChatCustomFieldsException, com.nice.cxonechat.exceptions.MissingThreadListFetchException, com.nice.cxonechat.exceptions.UndefinedCustomField, com.nice.cxonechat.exceptions.UnsupportedChannelConfigException;
+ method @kotlin.jvm.Throws(exceptionClasses={UnsupportedChannelConfigException::class, MissingThreadListFetchException::class, MissingPreChatCustomFieldsException::class, InvalidCustomFieldValue::class, UndefinedCustomField::class}) public default com.nice.cxonechat.ChatThreadHandler create(java.util.Map customFields) throws com.nice.cxonechat.exceptions.InvalidCustomFieldValue, com.nice.cxonechat.exceptions.MissingPreChatCustomFieldsException, com.nice.cxonechat.exceptions.MissingThreadListFetchException, com.nice.cxonechat.exceptions.UndefinedCustomField, com.nice.cxonechat.exceptions.UnsupportedChannelConfigException;
+ method @kotlin.jvm.Throws(exceptionClasses={UnsupportedChannelConfigException::class, MissingThreadListFetchException::class, MissingPreChatCustomFieldsException::class, InvalidCustomFieldValue::class, UndefinedCustomField::class}) public com.nice.cxonechat.ChatThreadHandler create(java.util.Map customFields, kotlin.sequences.Sequence extends com.nice.cxonechat.prechat.PreChatSurveyResponse extends com.nice.cxonechat.state.FieldDefinition,?>> preChatSurveyResponse) throws com.nice.cxonechat.exceptions.InvalidCustomFieldValue, com.nice.cxonechat.exceptions.MissingPreChatCustomFieldsException, com.nice.cxonechat.exceptions.MissingThreadListFetchException, com.nice.cxonechat.exceptions.UndefinedCustomField, com.nice.cxonechat.exceptions.UnsupportedChannelConfigException;
+ method @kotlin.jvm.Throws(exceptionClasses={UnsupportedChannelConfigException::class, MissingThreadListFetchException::class, MissingPreChatCustomFieldsException::class, InvalidCustomFieldValue::class, UndefinedCustomField::class}) public default com.nice.cxonechat.ChatThreadHandler create(kotlin.sequences.Sequence extends com.nice.cxonechat.prechat.PreChatSurveyResponse extends com.nice.cxonechat.state.FieldDefinition,?>> preChatSurveyResponse) throws com.nice.cxonechat.exceptions.InvalidCustomFieldValue, com.nice.cxonechat.exceptions.MissingPreChatCustomFieldsException, com.nice.cxonechat.exceptions.MissingThreadListFetchException, com.nice.cxonechat.exceptions.UndefinedCustomField, com.nice.cxonechat.exceptions.UnsupportedChannelConfigException;
+ method public com.nice.cxonechat.prechat.PreChatSurvey? getPreChatSurvey();
+ method public void refresh();
+ method public com.nice.cxonechat.ChatThreadHandler thread(com.nice.cxonechat.thread.ChatThread thread);
+ method @CheckResult public com.nice.cxonechat.Cancellable threads(com.nice.cxonechat.ChatThreadsHandler.OnThreadsUpdatedListener listener);
+ property public abstract com.nice.cxonechat.prechat.PreChatSurvey? preChatSurvey;
+ }
+
+ @com.nice.cxonechat.Public public static fun interface ChatThreadsHandler.OnThreadsUpdatedListener {
+ method public void onThreadsUpdated(java.util.List extends com.nice.cxonechat.thread.ChatThread> threads);
+ }
+
+ @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface Public {
+ }
+
+ @com.nice.cxonechat.Public public interface SocketFactoryConfiguration {
+ method public default static operator com.nice.cxonechat.SocketFactoryConfiguration create(com.nice.cxonechat.state.Environment environment, long brandId, String channelId);
+ method @Deprecated public default static operator com.nice.cxonechat.SocketFactoryConfiguration create(com.nice.cxonechat.state.Environment environment, long brandId, String channelId, optional String version);
+ method public long getBrandId();
+ method public String getChannelId();
+ method public com.nice.cxonechat.state.Environment getEnvironment();
+ method @Deprecated public String getVersion();
+ property public abstract long brandId;
+ property public abstract String channelId;
+ property public abstract com.nice.cxonechat.state.Environment environment;
+ property @Deprecated public abstract String version;
+ field public static final com.nice.cxonechat.SocketFactoryConfiguration.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class SocketFactoryConfiguration.Companion {
+ method public operator com.nice.cxonechat.SocketFactoryConfiguration create(com.nice.cxonechat.state.Environment environment, long brandId, String channelId);
+ method @Deprecated public operator com.nice.cxonechat.SocketFactoryConfiguration create(com.nice.cxonechat.state.Environment environment, long brandId, String channelId, optional String version);
+ }
+
+ @com.nice.cxonechat.Public public interface UserName {
+ method public default static operator com.nice.cxonechat.UserName create(String lastName, String firstName);
+ method public String getFirstName();
+ method public default String getFullName();
+ method public String getLastName();
+ method public default boolean getValid();
+ property public abstract String firstName;
+ property public default String fullName;
+ property public abstract String lastName;
+ property public default boolean valid;
+ field public static final com.nice.cxonechat.UserName.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class UserName.Companion {
+ method public operator com.nice.cxonechat.UserName create(String lastName, String firstName);
+ method public com.nice.cxonechat.UserName getAnonymous();
+ property public final com.nice.cxonechat.UserName Anonymous;
+ }
+
+}
+
+package com.nice.cxonechat.analytics {
+
+ @com.nice.cxonechat.Public public sealed interface ActionMetadata {
+ }
+
+}
+
+package com.nice.cxonechat.enums {
+
+ @com.nice.cxonechat.Public public enum CXOneEnvironment {
+ method public final com.nice.cxonechat.state.Environment! getValue();
+ method public static com.nice.cxonechat.enums.CXOneEnvironment valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.enums.CXOneEnvironment[] values();
+ property public final com.nice.cxonechat.state.Environment! value;
+ enum_constant public static final com.nice.cxonechat.enums.CXOneEnvironment AU1;
+ enum_constant public static final com.nice.cxonechat.enums.CXOneEnvironment CA1;
+ enum_constant public static final com.nice.cxonechat.enums.CXOneEnvironment EU1;
+ enum_constant public static final com.nice.cxonechat.enums.CXOneEnvironment JP1;
+ enum_constant public static final com.nice.cxonechat.enums.CXOneEnvironment NA1;
+ enum_constant public static final com.nice.cxonechat.enums.CXOneEnvironment UK1;
+ }
+
+}
+
+package com.nice.cxonechat.event {
+
+ @com.nice.cxonechat.Public public abstract sealed class ChatEvent {
+ }
+
+ @com.nice.cxonechat.Public public final class CustomVisitorEvent extends com.nice.cxonechat.event.ChatEvent {
+ ctor public CustomVisitorEvent(Object data);
+ }
+
+ @com.nice.cxonechat.Public public final class TriggerEvent extends com.nice.cxonechat.event.ChatEvent {
+ ctor public TriggerEvent(java.util.UUID id);
+ }
+
+}
+
+package com.nice.cxonechat.event.thread {
+
+ @com.nice.cxonechat.Public public final class ArchiveThreadEvent extends com.nice.cxonechat.event.thread.ChatThreadEvent {
+ field public static final com.nice.cxonechat.event.thread.ArchiveThreadEvent INSTANCE;
+ }
+
+ @com.nice.cxonechat.Public public abstract sealed class ChatThreadEvent {
+ }
+
+ @com.nice.cxonechat.Public public final class LoadThreadMetadataEvent extends com.nice.cxonechat.event.thread.ChatThreadEvent {
+ field public static final com.nice.cxonechat.event.thread.LoadThreadMetadataEvent INSTANCE;
+ }
+
+ @com.nice.cxonechat.Public public final class MarkThreadReadEvent extends com.nice.cxonechat.event.thread.ChatThreadEvent {
+ field public static final com.nice.cxonechat.event.thread.MarkThreadReadEvent INSTANCE;
+ }
+
+ @com.nice.cxonechat.Public public final class TypingEndEvent extends com.nice.cxonechat.event.thread.ChatThreadEvent {
+ field public static final com.nice.cxonechat.event.thread.TypingEndEvent INSTANCE;
+ }
+
+ @com.nice.cxonechat.Public public final class TypingStartEvent extends com.nice.cxonechat.event.thread.ChatThreadEvent {
+ field public static final com.nice.cxonechat.event.thread.TypingStartEvent INSTANCE;
+ }
+
+}
+
+package com.nice.cxonechat.exceptions {
+
+ @com.nice.cxonechat.Public public final class AnalyticsEventDispatchException extends com.nice.cxonechat.exceptions.CXOneException {
+ ctor public AnalyticsEventDispatchException(String message, Throwable? throwable);
+ }
+
+ @com.nice.cxonechat.Public public abstract sealed class CXOneException extends java.lang.Exception {
+ field public static final long serialVersionUID = -7049214473807003049L; // 0x9e2c28c8cf310257L
+ }
+
+ @com.nice.cxonechat.Public public final class InternalError extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public final class InvalidCustomFieldValue extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public final class InvalidParameterException extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public final class InvalidStateException extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public final class MissingCustomerId extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public final class MissingPreChatCustomFieldsException extends com.nice.cxonechat.exceptions.CXOneException {
+ method public Iterable getMissing();
+ property public final Iterable missing;
+ }
+
+ @com.nice.cxonechat.Public public final class MissingThreadListFetchException extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public abstract sealed class RuntimeChatException extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public static final class RuntimeChatException.AttachmentUploadError extends com.nice.cxonechat.exceptions.RuntimeChatException {
+ method public String? getAttachmentName();
+ property public final String? attachmentName;
+ }
+
+ @com.nice.cxonechat.Public public static final class RuntimeChatException.AuthorizationError extends com.nice.cxonechat.exceptions.RuntimeChatException {
+ }
+
+ @com.nice.cxonechat.Public public static final class RuntimeChatException.ServerCommunicationError extends com.nice.cxonechat.exceptions.RuntimeChatException {
+ }
+
+ @com.nice.cxonechat.Public public final class UndefinedCustomField extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+ @com.nice.cxonechat.Public public final class UnsupportedChannelConfigException extends com.nice.cxonechat.exceptions.CXOneException {
+ }
+
+}
+
+package com.nice.cxonechat.message {
+
+ @com.nice.cxonechat.Public public interface Action {
+ }
+
+ @com.nice.cxonechat.Public public static interface Action.ReplyButton extends com.nice.cxonechat.message.Action {
+ method public String? getDescription();
+ method public com.nice.cxonechat.message.Media? getMedia();
+ method public String? getPostback();
+ method public String getText();
+ property public abstract String? description;
+ property public abstract com.nice.cxonechat.message.Media? media;
+ property public abstract String? postback;
+ property public abstract String text;
+ }
+
+ @com.nice.cxonechat.Public public interface Attachment {
+ method public String getFriendlyName();
+ method public String? getMimeType();
+ method public String getUrl();
+ property public abstract String friendlyName;
+ property public abstract String? mimeType;
+ property public abstract String url;
+ }
+
+ @com.nice.cxonechat.Public public interface ContentDescriptor {
+ method public default static operator com.nice.cxonechat.message.ContentDescriptor create(android.net.Uri content, android.content.Context context, String mimeType, String fileName, optional String? friendlyName);
+ method public default static operator com.nice.cxonechat.message.ContentDescriptor create(byte[] content, String mimeType, String fileName, String? friendlyName);
+ method public com.nice.cxonechat.message.ContentDescriptor.DataSource getContent();
+ method public String getFileName();
+ method public String? getFriendlyName();
+ method public String getMimeType();
+ property public abstract com.nice.cxonechat.message.ContentDescriptor.DataSource content;
+ property public abstract String fileName;
+ property public abstract String? friendlyName;
+ property public abstract String mimeType;
+ field public static final com.nice.cxonechat.message.ContentDescriptor.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class ContentDescriptor.Companion {
+ method public operator com.nice.cxonechat.message.ContentDescriptor create(android.net.Uri content, android.content.Context context, String mimeType, String fileName, optional String? friendlyName);
+ method public operator com.nice.cxonechat.message.ContentDescriptor create(byte[] content, String mimeType, String fileName, String? friendlyName);
+ }
+
+ @com.nice.cxonechat.Public public abstract static sealed class ContentDescriptor.DataSource {
+ }
+
+ @com.nice.cxonechat.Public public interface Media {
+ method public String getFileName();
+ method public String getMimeType();
+ method public String getUrl();
+ property public abstract String fileName;
+ property public abstract String mimeType;
+ property public abstract String url;
+ }
+
+ @com.nice.cxonechat.Public public abstract sealed class Message {
+ method public abstract Iterable getAttachments();
+ method public abstract com.nice.cxonechat.message.MessageAuthor? getAuthor();
+ method public abstract java.util.Date getCreatedAt();
+ method public abstract com.nice.cxonechat.message.MessageDirection getDirection();
+ method public abstract String? getFallbackText();
+ method public abstract java.util.UUID getId();
+ method public abstract com.nice.cxonechat.message.MessageMetadata getMetadata();
+ method public abstract java.util.UUID getThreadId();
+ property public abstract Iterable attachments;
+ property public abstract com.nice.cxonechat.message.MessageAuthor? author;
+ property public abstract java.util.Date createdAt;
+ property public abstract com.nice.cxonechat.message.MessageDirection direction;
+ property public abstract String? fallbackText;
+ property public abstract java.util.UUID id;
+ property public abstract com.nice.cxonechat.message.MessageMetadata metadata;
+ property public abstract java.util.UUID threadId;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class Message.ListPicker extends com.nice.cxonechat.message.Message {
+ ctor public Message.ListPicker();
+ method public abstract Iterable getActions();
+ method public abstract String getText();
+ method public abstract String getTitle();
+ property public abstract Iterable actions;
+ property public abstract String text;
+ property public abstract String title;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class Message.Plugin extends com.nice.cxonechat.message.Message {
+ ctor public Message.Plugin();
+ method public abstract com.nice.cxonechat.message.PluginElement? getElement();
+ method public abstract String? getPostback();
+ property public abstract com.nice.cxonechat.message.PluginElement? element;
+ property public abstract String? postback;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class Message.QuickReplies extends com.nice.cxonechat.message.Message {
+ ctor public Message.QuickReplies();
+ method public abstract Iterable getActions();
+ method public abstract String getTitle();
+ property public abstract Iterable actions;
+ property public abstract String title;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class Message.RichLink extends com.nice.cxonechat.message.Message {
+ ctor public Message.RichLink();
+ method public abstract com.nice.cxonechat.message.Media getMedia();
+ method public abstract String getTitle();
+ method public abstract String getUrl();
+ property public abstract com.nice.cxonechat.message.Media media;
+ property public abstract String title;
+ property public abstract String url;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class Message.Text extends com.nice.cxonechat.message.Message {
+ ctor public Message.Text();
+ method public abstract String getText();
+ property public abstract String text;
+ }
+
+ @com.nice.cxonechat.Public public abstract class MessageAuthor {
+ ctor public MessageAuthor();
+ method public abstract String getFirstName();
+ method public abstract String getId();
+ method public abstract String? getImageUrl();
+ method public abstract String getLastName();
+ method public final String getName();
+ property public abstract String firstName;
+ property public abstract String id;
+ property public abstract String? imageUrl;
+ property public abstract String lastName;
+ property public final String name;
+ }
+
+ @com.nice.cxonechat.Public public enum MessageDirection {
+ method public static com.nice.cxonechat.message.MessageDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.message.MessageDirection[] values();
+ enum_constant public static final com.nice.cxonechat.message.MessageDirection ToAgent;
+ enum_constant public static final com.nice.cxonechat.message.MessageDirection ToClient;
+ }
+
+ @com.nice.cxonechat.Public public interface MessageMetadata {
+ method public java.util.Date? getReadAt();
+ method public java.util.Date? getSeenAt();
+ method public com.nice.cxonechat.message.MessageStatus getStatus();
+ property public abstract java.util.Date? readAt;
+ property public abstract java.util.Date? seenAt;
+ property public abstract com.nice.cxonechat.message.MessageStatus status;
+ }
+
+ @com.nice.cxonechat.Public public enum MessageStatus {
+ method public static com.nice.cxonechat.message.MessageStatus valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.message.MessageStatus[] values();
+ enum_constant public static final com.nice.cxonechat.message.MessageStatus FAILED_TO_DELIVER;
+ enum_constant public static final com.nice.cxonechat.message.MessageStatus READ;
+ enum_constant public static final com.nice.cxonechat.message.MessageStatus SEEN;
+ enum_constant public static final com.nice.cxonechat.message.MessageStatus SENDING;
+ enum_constant public static final com.nice.cxonechat.message.MessageStatus SENT;
+ }
+
+ @com.nice.cxonechat.Public public interface OutboundMessage {
+ method public default static operator com.nice.cxonechat.message.OutboundMessage create(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments);
+ method public default static operator com.nice.cxonechat.message.OutboundMessage create(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments, optional String message);
+ method public default static operator com.nice.cxonechat.message.OutboundMessage create(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments, optional String message, optional String? postback);
+ method public default static operator com.nice.cxonechat.message.OutboundMessage create(String message);
+ method public default static operator com.nice.cxonechat.message.OutboundMessage create(String message, optional String? postback);
+ method public Iterable getAttachments();
+ method public String getMessage();
+ method public String? getPostback();
+ property public abstract Iterable attachments;
+ property public abstract String message;
+ property public abstract String? postback;
+ field public static final com.nice.cxonechat.message.OutboundMessage.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class OutboundMessage.Companion {
+ method public operator com.nice.cxonechat.message.OutboundMessage create(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments);
+ method public operator com.nice.cxonechat.message.OutboundMessage create(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments, optional String message);
+ method public operator com.nice.cxonechat.message.OutboundMessage create(Iterable extends com.nice.cxonechat.message.ContentDescriptor> attachments, optional String message, optional String? postback);
+ method public operator com.nice.cxonechat.message.OutboundMessage create(String message);
+ method public operator com.nice.cxonechat.message.OutboundMessage create(String message, optional String? postback);
+ }
+
+ @com.nice.cxonechat.Public public abstract sealed class PluginElement {
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Button extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Button();
+ method public abstract String? getDeepLink();
+ method public abstract boolean getDisplayInApp();
+ method public abstract String? getPostback();
+ method public abstract String getText();
+ property public abstract String? deepLink;
+ property public abstract boolean displayInApp;
+ property public abstract String? postback;
+ property public abstract String text;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Countdown extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Countdown();
+ method public abstract java.util.Date getEndsAt();
+ method public abstract boolean isExpired();
+ property public abstract java.util.Date endsAt;
+ property public abstract boolean isExpired;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Custom extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Custom();
+ method public abstract String? getFallbackText();
+ method public abstract java.util.Map getVariables();
+ property public abstract String? fallbackText;
+ property public abstract java.util.Map variables;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.File extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.File();
+ method public abstract String getMimeType();
+ method public abstract String getName();
+ method public abstract String getUrl();
+ property public abstract String mimeType;
+ property public abstract String name;
+ property public abstract String url;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Gallery extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Gallery();
+ method public abstract Iterable getElements();
+ property public abstract Iterable elements;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.InactivityPopup extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.InactivityPopup();
+ method public abstract Iterable getButtons();
+ method public abstract com.nice.cxonechat.message.PluginElement.Countdown getCountdown();
+ method public abstract com.nice.cxonechat.message.PluginElement.Subtitle? getSubtitle();
+ method public abstract Iterable getTexts();
+ method public abstract com.nice.cxonechat.message.PluginElement.Title getTitle();
+ property public abstract Iterable buttons;
+ property public abstract com.nice.cxonechat.message.PluginElement.Countdown countdown;
+ property public abstract com.nice.cxonechat.message.PluginElement.Subtitle? subtitle;
+ property public abstract Iterable texts;
+ property public abstract com.nice.cxonechat.message.PluginElement.Title title;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Menu extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Menu();
+ method public abstract Iterable getButtons();
+ method public abstract Iterable getFiles();
+ method public abstract Iterable getSubtitles();
+ method public abstract Iterable getTexts();
+ method public abstract Iterable getTitles();
+ property public abstract Iterable buttons;
+ property public abstract Iterable files;
+ property public abstract Iterable subtitles;
+ property public abstract Iterable texts;
+ property public abstract Iterable titles;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.QuickReplies extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.QuickReplies();
+ method public abstract Iterable getButtons();
+ method public abstract com.nice.cxonechat.message.PluginElement.Text? getText();
+ property public abstract Iterable buttons;
+ property public abstract com.nice.cxonechat.message.PluginElement.Text? text;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.SatisfactionSurvey extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.SatisfactionSurvey();
+ method public abstract com.nice.cxonechat.message.PluginElement.Button getButton();
+ method public abstract String? getPostback();
+ method public abstract com.nice.cxonechat.message.PluginElement.Text? getText();
+ property public abstract com.nice.cxonechat.message.PluginElement.Button button;
+ property public abstract String? postback;
+ property public abstract com.nice.cxonechat.message.PluginElement.Text? text;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Subtitle extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Subtitle();
+ method public abstract String getText();
+ property public abstract String text;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Text extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Text();
+ method public abstract com.nice.cxonechat.message.TextFormat getFormat();
+ method public abstract String getText();
+ method @Deprecated public abstract boolean isHtml();
+ method @Deprecated public abstract boolean isMarkdown();
+ property public abstract com.nice.cxonechat.message.TextFormat format;
+ property @Deprecated public abstract boolean isHtml;
+ property @Deprecated public abstract boolean isMarkdown;
+ property public abstract String text;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.TextAndButtons extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.TextAndButtons();
+ method public abstract Iterable getButtons();
+ method public abstract com.nice.cxonechat.message.PluginElement.Text getText();
+ property public abstract Iterable buttons;
+ property public abstract com.nice.cxonechat.message.PluginElement.Text text;
+ }
+
+ @com.nice.cxonechat.Public public abstract static class PluginElement.Title extends com.nice.cxonechat.message.PluginElement {
+ ctor public PluginElement.Title();
+ method public abstract String getText();
+ property public abstract String text;
+ }
+
+ @com.nice.cxonechat.Public public enum TextFormat {
+ method public final String! getMimeType();
+ method public final boolean isHtml();
+ method public final boolean isMarkdown();
+ method public static com.nice.cxonechat.message.TextFormat valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.message.TextFormat[] values();
+ property public final boolean isHtml;
+ property public final boolean isMarkdown;
+ property public final String! mimeType;
+ enum_constant public static final com.nice.cxonechat.message.TextFormat Html;
+ enum_constant public static final com.nice.cxonechat.message.TextFormat Markdown;
+ enum_constant public static final com.nice.cxonechat.message.TextFormat Plain;
+ }
+
+}
+
+package com.nice.cxonechat.prechat {
+
+ @com.nice.cxonechat.Public public interface PreChatSurvey {
+ method public kotlin.sequences.Sequence getFields();
+ method public String getName();
+ property public abstract kotlin.sequences.Sequence fields;
+ property public abstract String name;
+ }
+
+ @com.nice.cxonechat.Public public sealed interface PreChatSurveyResponse {
+ method public T getQuestion();
+ method public R getResponse();
+ property public abstract T question;
+ property public abstract R response;
+ }
+
+ @com.nice.cxonechat.Public public static interface PreChatSurveyResponse.Hierarchy extends com.nice.cxonechat.prechat.PreChatSurveyResponse> {
+ method public default static operator com.nice.cxonechat.prechat.PreChatSurveyResponse.Hierarchy create(com.nice.cxonechat.state.FieldDefinition.Hierarchy question, com.nice.cxonechat.state.HierarchyNode response);
+ field public static final com.nice.cxonechat.prechat.PreChatSurveyResponse.Hierarchy.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class PreChatSurveyResponse.Hierarchy.Companion {
+ method public operator com.nice.cxonechat.prechat.PreChatSurveyResponse.Hierarchy create(com.nice.cxonechat.state.FieldDefinition.Hierarchy question, com.nice.cxonechat.state.HierarchyNode response);
+ }
+
+ @com.nice.cxonechat.Public public static interface PreChatSurveyResponse.Selector extends com.nice.cxonechat.prechat.PreChatSurveyResponse {
+ method public default static operator com.nice.cxonechat.prechat.PreChatSurveyResponse.Selector create(com.nice.cxonechat.state.FieldDefinition.Selector question, com.nice.cxonechat.state.SelectorNode response);
+ field public static final com.nice.cxonechat.prechat.PreChatSurveyResponse.Selector.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class PreChatSurveyResponse.Selector.Companion {
+ method public operator com.nice.cxonechat.prechat.PreChatSurveyResponse.Selector create(com.nice.cxonechat.state.FieldDefinition.Selector question, com.nice.cxonechat.state.SelectorNode response);
+ }
+
+ @com.nice.cxonechat.Public public static interface PreChatSurveyResponse.Text extends com.nice.cxonechat.prechat.PreChatSurveyResponse {
+ method public default static operator com.nice.cxonechat.prechat.PreChatSurveyResponse.Text create(com.nice.cxonechat.state.FieldDefinition.Text question, String response);
+ field public static final com.nice.cxonechat.prechat.PreChatSurveyResponse.Text.Companion Companion;
+ }
+
+ @com.nice.cxonechat.Public public static final class PreChatSurveyResponse.Text.Companion {
+ method public operator com.nice.cxonechat.prechat.PreChatSurveyResponse.Text create(com.nice.cxonechat.state.FieldDefinition.Text question, String response);
+ }
+
+}
+
+package com.nice.cxonechat.state {
+
+ @com.nice.cxonechat.Public public interface Configuration {
+ method public default boolean allowsFieldId(String fieldId);
+ method public default kotlin.sequences.Sequence getAllCustomFields();
+ method public kotlin.sequences.Sequence getContactCustomFields();
+ method public kotlin.sequences.Sequence getCustomerCustomFields();
+ method public boolean getHasMultipleThreadsPerEndUser();
+ method public boolean isAuthorizationEnabled();
+ method public boolean isProactiveChatEnabled();
+ property public default kotlin.sequences.Sequence allCustomFields;
+ property public abstract kotlin.sequences.Sequence contactCustomFields;
+ property public abstract kotlin.sequences.Sequence customerCustomFields;
+ property public abstract boolean hasMultipleThreadsPerEndUser;
+ property public abstract boolean isAuthorizationEnabled;
+ property public abstract boolean isProactiveChatEnabled;
+ }
+
+ @com.nice.cxonechat.Public public interface Connection {
+ method public int getBrandId();
+ method public String getChannelId();
+ method public String? getCustomerId();
+ method public com.nice.cxonechat.state.Environment getEnvironment();
+ method public String getFirstName();
+ method public String getLastName();
+ method public java.util.UUID getVisitorId();
+ property public abstract int brandId;
+ property public abstract String channelId;
+ property public abstract String? customerId;
+ property public abstract com.nice.cxonechat.state.Environment environment;
+ property public abstract String firstName;
+ property public abstract String lastName;
+ property public abstract java.util.UUID visitorId;
+ }
+
+ @com.nice.cxonechat.Public public interface Environment {
+ method public String getBaseUrl();
+ method public String getChatUrl();
+ method public String getLocation();
+ method public String getName();
+ method public String getOriginHeader();
+ method public String getSocketUrl();
+ property public abstract String baseUrl;
+ property public abstract String chatUrl;
+ property public abstract String location;
+ property public abstract String name;
+ property public abstract String originHeader;
+ property public abstract String socketUrl;
+ }
+
+ @com.nice.cxonechat.Public public interface FieldDefinition {
+ method public String getFieldId();
+ method public String getLabel();
+ method public boolean isRequired();
+ method @kotlin.jvm.Throws(exceptionClasses=InvalidCustomFieldValue::class) public void validate(String value) throws com.nice.cxonechat.exceptions.InvalidCustomFieldValue;
+ property public abstract String fieldId;
+ property public abstract boolean isRequired;
+ property public abstract String label;
+ }
+
+ @com.nice.cxonechat.Public public static interface FieldDefinition.Hierarchy extends com.nice.cxonechat.state.FieldDefinition {
+ method public kotlin.sequences.Sequence> getValues();
+ property public abstract kotlin.sequences.Sequence> values;
+ }
+
+ @com.nice.cxonechat.Public public static interface FieldDefinition.Selector extends com.nice.cxonechat.state.FieldDefinition {
+ method public kotlin.sequences.Sequence getValues();
+ property public abstract kotlin.sequences.Sequence values;
+ }
+
+ @com.nice.cxonechat.Public public static interface FieldDefinition.Text extends com.nice.cxonechat.state.FieldDefinition {
+ method public boolean isEMail();
+ property public abstract boolean isEMail;
+ }
+
+ public final class FieldDefinitionListKt {
+ method @com.nice.cxonechat.Public @kotlin.jvm.Throws(exceptionClasses=MissingPreChatCustomFieldsException::class) public static void checkRequired(kotlin.sequences.Sequence extends com.nice.cxonechat.state.FieldDefinition>, java.util.Map values) throws com.nice.cxonechat.exceptions.MissingPreChatCustomFieldsException;
+ method @com.nice.cxonechat.Public public static boolean containsField(kotlin.sequences.Sequence extends com.nice.cxonechat.state.FieldDefinition>, String fieldId);
+ method @com.nice.cxonechat.Public public static com.nice.cxonechat.state.FieldDefinition? lookup(kotlin.sequences.Sequence extends com.nice.cxonechat.state.FieldDefinition>, String fieldId);
+ method @com.nice.cxonechat.Public @kotlin.jvm.Throws(exceptionClasses=UndefinedCustomField::class) public static void validate(kotlin.sequences.Sequence extends com.nice.cxonechat.state.FieldDefinition>, java.util.Map values) throws com.nice.cxonechat.exceptions.UndefinedCustomField;
+ }
+
+ @com.nice.cxonechat.Public public interface HierarchyNode {
+ method public kotlin.sequences.Sequence> getChildren();
+ method public String getLabel();
+ method public T getNodeId();
+ method public boolean isLeaf();
+ property public abstract kotlin.sequences.Sequence> children;
+ property public abstract boolean isLeaf;
+ property public abstract String label;
+ property public abstract T nodeId;
+ }
+
+ public final class HierarchyNodeKt {
+ method @com.nice.cxonechat.Public public static com.nice.cxonechat.state.HierarchyNode? lookup(com.nice.cxonechat.state.HierarchyNode, T nodeId);
+ method @com.nice.cxonechat.Public public static com.nice.cxonechat.state.HierarchyNode? lookup(kotlin.sequences.Sequence extends com.nice.cxonechat.state.HierarchyNode>, T nodeId);
+ }
+
+ @com.nice.cxonechat.Public public interface SelectorNode {
+ method public String getLabel();
+ method public String getNodeId();
+ property public abstract String label;
+ property public abstract String nodeId;
+ }
+
+ public final class SelectorNodeKt {
+ method @com.nice.cxonechat.Public public static boolean contains(kotlin.sequences.Sequence extends com.nice.cxonechat.state.SelectorNode>, String nodeId);
+ method @com.nice.cxonechat.Public public static com.nice.cxonechat.state.SelectorNode? lookup(kotlin.sequences.Sequence extends com.nice.cxonechat.state.SelectorNode>, String nodeId);
+ }
+
+}
+
+package com.nice.cxonechat.thread {
+
+ @com.nice.cxonechat.Public public abstract class Agent {
+ ctor public Agent();
+ method public abstract String? getEmailAddress();
+ method public abstract String getFirstName();
+ method public final String getFullName();
+ method public abstract int getId();
+ method public abstract String getImageUrl();
+ method public abstract java.util.UUID? getInContactId();
+ method public abstract String getLastName();
+ method public abstract String? getNickname();
+ method public abstract boolean isBotUser();
+ method public abstract boolean isSurveyUser();
+ method public abstract boolean isTyping();
+ property public abstract String? emailAddress;
+ property public abstract String firstName;
+ property public final String fullName;
+ property public abstract int id;
+ property public abstract String imageUrl;
+ property public abstract java.util.UUID? inContactId;
+ property public abstract boolean isBotUser;
+ property public abstract boolean isSurveyUser;
+ property public abstract boolean isTyping;
+ property public abstract String lastName;
+ property public abstract String? nickname;
+ }
+
+ @com.nice.cxonechat.Public public abstract class ChatThread {
+ ctor public ChatThread();
+ method public abstract boolean getCanAddMoreMessages();
+ method public abstract java.util.List getFields();
+ method public final boolean getHasMoreMessagesToLoad();
+ method public abstract java.util.UUID getId();
+ method public abstract java.util.List getMessages();
+ method public abstract String getScrollToken();
+ method public abstract com.nice.cxonechat.thread.Agent? getThreadAgent();
+ method public abstract String? getThreadName();
+ method public abstract com.nice.cxonechat.thread.ChatThreadState getThreadState();
+ property public abstract boolean canAddMoreMessages;
+ property public abstract java.util.List fields;
+ property public final boolean hasMoreMessagesToLoad;
+ property public abstract java.util.UUID id;
+ property public abstract java.util.List messages;
+ property public abstract String scrollToken;
+ property public abstract com.nice.cxonechat.thread.Agent? threadAgent;
+ property public abstract String? threadName;
+ property public abstract com.nice.cxonechat.thread.ChatThreadState threadState;
+ }
+
+ @com.nice.cxonechat.Public public enum ChatThreadState {
+ method public static com.nice.cxonechat.thread.ChatThreadState valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+ method public static com.nice.cxonechat.thread.ChatThreadState[] values();
+ enum_constant public static final com.nice.cxonechat.thread.ChatThreadState Loaded;
+ enum_constant public static final com.nice.cxonechat.thread.ChatThreadState Pending;
+ enum_constant public static final com.nice.cxonechat.thread.ChatThreadState Ready;
+ enum_constant public static final com.nice.cxonechat.thread.ChatThreadState Received;
+ }
+
+ @com.nice.cxonechat.Public public interface CustomField {
+ method public String getId();
+ method public java.util.Date getUpdatedAt();
+ method public String getValue();
+ property public abstract String id;
+ property public abstract java.util.Date updatedAt;
+ property public abstract String value;
+ }
+
+}
+
diff --git a/chat-sdk-core/build.gradle b/chat-sdk-core/build.gradle
index 74395542..9e850848 100644
--- a/chat-sdk-core/build.gradle
+++ b/chat-sdk-core/build.gradle
@@ -1,14 +1,17 @@
plugins {
id "android-library-conventions"
- id "kotlin-conventions"
- id "docs-conventions"
- id "test-conventions"
- id "library-style-conventions"
+ id "android-kotlin-conventions"
+ id "android-docs-conventions"
+ id "android-test-conventions"
+ id "android-library-style-conventions"
id "publish-conventions"
+ id "api-conventions"
+}
+metalava {
+ hiddenPackages = ["com.nice.cxonechat.internal"]
}
-
android {
- namespace 'com.nice.cxonechat'
+ namespace 'com.nice.cxonechat.core'
defaultConfig {
consumerProguardFiles "consumer-rules.pro"
@@ -34,15 +37,17 @@ android {
}
}
- kotlinOptions {
- freeCompilerArgs = ['-Xjvm-default=all']
- }
-
buildFeatures {
buildConfig true // Library version is used for device fingerprint
}
}
+kotlin {
+ compilerOptions {
+ freeCompilerArgs = ['-Xjvm-default=all']
+ }
+}
+
// Setup publishing of all library variants.
// Dependant will get matching variant automatically (eg.: buildType:debug will get buildType:debug)
// Alternatively they can provide transformation mapping.
@@ -51,9 +56,12 @@ mavenPublishing {
}
dependencies {
- implementation "androidx.core:core-ktx:1.10.1"
+ implementation "androidx.core:core-ktx:1.12.0"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
- implementation 'com.squareup.okhttp3:okhttp:4.11.0'
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
+ implementation project(':utilities')
+ api project(':logger')
+ implementation project(':logger-android')
}
diff --git a/chat-sdk-core/gradle.properties b/chat-sdk-core/gradle.properties
index 0d9d0781..b2e398f0 100644
--- a/chat-sdk-core/gradle.properties
+++ b/chat-sdk-core/gradle.properties
@@ -1 +1,16 @@
+#
+# Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+#
+# Licensed under the NICE License;
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+#
+# TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+# AN ?AS IS? BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+# OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+#
+
POM_ARTIFACT_ID=chat-core
diff --git a/chat-sdk-core/lint-baseline.xml b/chat-sdk-core/lint-baseline.xml
new file mode 100644
index 00000000..f32fed49
--- /dev/null
+++ b/chat-sdk-core/lint-baseline.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/chat-sdk-core/notes/CXOneChatError.kt b/chat-sdk-core/notes/CXOneChatError.kt
deleted file mode 100644
index cb86d61b..00000000
--- a/chat-sdk-core/notes/CXOneChatError.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
- *
- * Licensed under the NICE License;
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
- *
- * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
- * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
- * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
- */
-
-package com.nice.cxonechat.enums
-
-/**
- * The different types of errors that may be experienced.
- */
-internal enum class CXOneChatError(val value: Exception) {
- // When calling any method
-
- /** An attempt was made to use a method without connecting first. Make sure you call the `connect` method first. */
- NotConnected(
- Exception("You are trying to call a method without connecting first. Make sure you call connect first.")
- ),
-
- /** The provided attachment was unable to be sent. */
- AttachmentError(Exception("The provided attachment wasn't able to be sent.")),
-
- /** The server experienced an internal error and was unable to perform the action. */
- ServerError(Exception("Internal server error.")),
-
- // Errors when calling connect
-
- /** The WebSocket refused to connect. */
- WebSocketConnectionFailure(
- Exception(
- "Something went wrong and the WebSocket refused to connect. If you are providing your own chatURL or" +
- " socketURL, double check that these URLs are correct."
- )
- ),
-
- /** The customer could not be authorized anonymously. */
- AnonymousAuthorizationFailure(Exception("Something went wrong and the customer could not be authorized.")),
-
- /** The customer could not be authorized using the OAuth details configured on the channel. */
- OAuthAuthorizationFailure(Exception("Something went wrong and the channel configuration could not be retrieved.")),
-
- /** The auth code has not been set, but an attempt has been made to authorize. */
- MissingAuthCode(
- Exception(
- "You are trying to authorize a customer through OAuth, but haven’t provided the authorization code yet." +
- " Make sure you call setAuthCode before calling connect."
- )
- ),
-
- /** The returning customer could not be reconnected. */
- ReconnectFailure(Exception("Something went wrong and the returning customer could not be reconnected.")),
-
- /** The customer was successfully authorized, but an access token wasn't returned. */
- MissingAccessToken(
- Exception("The customer was successfully authorized using OAuth, but an access token wasn’t returned.")
- ),
-
- /** The customer could not be associated with a visitor. */
- CustomerVisitorAssociationFailure(Exception("The customer could not be successfully associated with a visitor.")),
-
- /** The request was invalid and couldn't be completed. */
- InvalidRequest(Exception("Could not make the request because the URL was malformed.")),
-
- InvalidOldestDate(Exception("No oldest message date is saved."))
-}
diff --git a/chat-sdk-core/src/androidTest/java/com/nice/cxonechat/ChatBuilderIntegrationTest.kt b/chat-sdk-core/src/androidTest/java/com/nice/cxonechat/ChatBuilderIntegrationTest.kt
index b5fefdc8..644a6544 100644
--- a/chat-sdk-core/src/androidTest/java/com/nice/cxonechat/ChatBuilderIntegrationTest.kt
+++ b/chat-sdk-core/src/androidTest/java/com/nice/cxonechat/ChatBuilderIntegrationTest.kt
@@ -1,20 +1,36 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
-import androidx.test.InstrumentationRegistry
+import android.app.Application
+import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
+import com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback
import com.nice.cxonechat.internal.model.EnvironmentInternal
+import org.junit.Assert.assertTrue
import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit.SECONDS
-@RunWith(AndroidJUnit4::class)
@SmallTest
-class ChatBuilderIntegrationTest {
+internal class ChatBuilderIntegrationTest {
@Test
fun connectsToServer() {
- val context = InstrumentationRegistry.getContext()
+ val context = ApplicationProvider.getApplicationContext()
val environment = EnvironmentInternal(
name = "",
location = "",
@@ -25,14 +41,15 @@ class ChatBuilderIntegrationTest {
)
val config = SocketFactoryConfiguration(environment, 6450, "chat_f62c9eaf-f030-4d0d-aa87-6e8a5aed3c55")
val latch = CountDownLatch(1)
- ChatBuilder(context, config)
+ val cancellable = ChatBuilder(context, config)
.setDevelopmentMode(true)
.setUserName("john", "doe")
- .build {
- it.close()
+ .build(resultCallback = {
+ it.getOrThrow().close()
latch.countDown()
- }
- latch.await()
+ })
+ assertTrue(latch.await(10, SECONDS))
+ cancellable.cancel()
}
}
diff --git a/chat-sdk-core/src/main/AndroidManifest.xml b/chat-sdk-core/src/main/AndroidManifest.xml
index 5e7684f5..f47ad8a4 100644
--- a/chat-sdk-core/src/main/AndroidManifest.xml
+++ b/chat-sdk-core/src/main/AndroidManifest.xml
@@ -1,4 +1,19 @@
+
+
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/Cancellable.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/Cancellable.kt
index 24ded1d3..c0d666b9 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/Cancellable.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/Cancellable.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
import androidx.annotation.CheckResult
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/Chat.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/Chat.kt
index 20ddfba3..51c92d66 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/Chat.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/Chat.kt
@@ -1,5 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
+import com.nice.cxonechat.ChatMode.MULTI_THREAD
+import com.nice.cxonechat.ChatMode.SINGLE_THREAD
import com.nice.cxonechat.state.Configuration
import com.nice.cxonechat.state.Environment
import com.nice.cxonechat.thread.ChatThread
@@ -47,6 +64,12 @@ interface Chat : AutoCloseable {
*/
val fields: Collection
+ /**
+ * Current mode of the chat.
+ */
+ val chatMode: ChatMode
+ get() = if (configuration.hasMultipleThreadsPerEndUser) MULTI_THREAD else SINGLE_THREAD
+
/**
* Sets device token (notification push token) to this instance and transmits it
* to the server. It's not guaranteed that the token is delivered to the server
@@ -89,11 +112,10 @@ interface Chat : AutoCloseable {
/**
* Closes the connection to the chat backend and removes all listeners, even those
- * the client forgot to unregister. The instance is considered dead after calling
- * this method.
+ * the client forgot to unregister.
*
- * Interacting with any handlers or methods in this class can lead to unspecified,
- * untested and further unwanted behavior, this includes [reconnect] method.
+ * Further interaction with any handlers or methods other than [events()] or [connect()] in this class can lead
+ * to unspecified, untested and further unwanted behavior.
*/
override fun close()
@@ -109,5 +131,26 @@ interface Chat : AutoCloseable {
*
* @return An instance of [Cancellable] which can be used to interrupt background operation.
*/
+ @Deprecated("Deprecated, use connect() instead.", replaceWith = ReplaceWith("connect()"))
fun reconnect(): Cancellable
+
+ /**
+ * Attempts to connect the chat session using existing configuration, the attempt will be made on background thread.
+ * Successful connection will be announced to the [ChatStateListener.onConnected] which was
+ * supplied in [ChatBuilder].
+ * If there is an issue during/after reconnection the [ChatStateListener.onUnexpectedDisconnect] will be called,
+ * it is responsibility of application to perform a repeated reconnection attempt, if it is desirable.
+ * Reconnect attempts should be performed only if the device is connected to the internet.
+ * If the repeated reconnection attempts are made, they should be called with exponential backoff,
+ * in order to prevent backend overload.
+ *
+ * @return An instance of [Cancellable] which can be used to interrupt background operation.
+ */
+ fun connect(): Cancellable
+
+ /**
+ * Attempts to change username if the channel configuration allows setting of the username.
+ * All subsequent events sent from chat will have new value filled out.
+ */
+ fun setUserName(firstName: String, lastName: String)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatActionHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatActionHandler.kt
index 1dd49ebb..7a9b432d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatActionHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatActionHandler.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
import com.nice.cxonechat.analytics.ActionMetadata
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatBuilder.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatBuilder.kt
index c6013200..0932606d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatBuilder.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatBuilder.kt
@@ -19,11 +19,14 @@ import android.content.Context
import androidx.annotation.CheckResult
import com.nice.cxonechat.internal.ChatBuilderDefault
import com.nice.cxonechat.internal.ChatBuilderLogging
-import com.nice.cxonechat.internal.ChatBuilderRepeating
+import com.nice.cxonechat.internal.ChatBuilderThreading
import com.nice.cxonechat.internal.ChatEntrails
import com.nice.cxonechat.internal.ChatEntrailsAndroid
import com.nice.cxonechat.internal.socket.SocketFactory
import com.nice.cxonechat.internal.socket.SocketFactoryDefault
+import com.nice.cxonechat.log.Logger
+import com.nice.cxonechat.log.LoggerNoop
+import com.nice.cxonechat.utilities.TaggingSocketFactory
import okhttp3.OkHttpClient
/**
@@ -76,10 +79,24 @@ interface ChatBuilder {
fun setDeviceToken(token: String): ChatBuilder
/**
- * Builds an instance of chat asynchronously. It's guaranteed to retrieve an
- * instance of the chat. The method continuously polls the server when failure
- * occurs with exponential backoff where the base is equal to 2 seconds. All
- * failures are logged if [setDevelopmentMode] is set.
+ * Build an instance of chat asynchronously.
+ * Previously this method guaranteed an instance to be returned via [callback], this is no
+ * longer the case. If there is an communication issue with the server, this method will throw a runtime exception.
+ */
+ @CheckResult
+ @Deprecated(
+ message = "Please migrate to build method with OnChatBuildResultCallback",
+ replaceWith = ReplaceWith(
+ expression = "build(resultCallback = OnChatBuiltResultCallback { callback.onChatBuilt(it.getOrThrow()) })",
+ imports = ["com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback"]
+ )
+ )
+ fun build(callback: OnChatBuiltCallback): Cancellable
+
+ /**
+ * Builds an instance of chat asynchronously.
+ * Any standard issue which may happen during will be reported as [IllegalStateException] in [Result.onFailure].
+ * All failures are logged if [setDevelopmentMode] is set.
*
* If the instance is not retrieved within a reasonable amount of time, the
* device is not connected to the internet, or the chat provider experiences
@@ -89,9 +106,11 @@ interface ChatBuilder {
* Can be called from any thread, but will change to non-main thread immediately.
*
* @see OnChatBuiltCallback.onChatBuilt
+ *
+ * @return A [Cancellable] which allows to cancel the asynchronous operation.
*/
@CheckResult
- fun build(callback: OnChatBuiltCallback): Cancellable
+ fun build(resultCallback: OnChatBuiltResultCallback): Cancellable
/**
* Callback allowing to listen to chat instance provisioning.
@@ -106,23 +125,47 @@ interface ChatBuilder {
fun onChatBuilt(chat: Chat)
}
+ /**
+ * Callback allowing to listen to chat instance provisioning.
+ */
+ @Public
+ fun interface OnChatBuiltResultCallback {
+ /**
+ * Notifies the consumer if the chat instance preparation has succeeded and provides the instance in the
+ * case of the success.
+ * It's always called on the main thread.
+ */
+ fun onChatBuiltResult(chat: Result)
+ }
+
@Public
companion object {
/**
* Returns an instance of [ChatBuilder] with Android specific parameters.
+ *
+ * @param context The [Context] used for persistent storage of values by the SDK.
+ * @param config [SocketFactoryConfiguration] connection configuration of the chat.
+ * @param logger [Logger] which will be used by the builder and the SDK, default is no-op implementation.
+ *
* @see build
* @see OnChatBuiltCallback
* @see OnChatBuiltCallback.onChatBuilt
* */
@JvmName("getDefault")
+ @JvmOverloads
+ @JvmStatic
operator fun invoke(
context: Context,
config: SocketFactoryConfiguration,
+ logger: Logger = LoggerNoop,
): ChatBuilder {
val sharedClient = OkHttpClient()
+ .newBuilder()
+ .socketFactory(TaggingSocketFactory)
+ .build()
val factory = SocketFactoryDefault(config, sharedClient)
- val entrails = ChatEntrailsAndroid(context.applicationContext, factory, config, sharedClient)
+ val entrails = ChatEntrailsAndroid(context.applicationContext, factory, config, sharedClient, logger)
return invoke(
entrails = entrails,
factory = factory
@@ -137,7 +180,7 @@ interface ChatBuilder {
var builder: ChatBuilder
builder = ChatBuilderDefault(entrails, factory)
builder = ChatBuilderLogging(builder, entrails)
- builder = ChatBuilderRepeating(builder, entrails)
+ builder = ChatBuilderThreading(builder, entrails)
return builder
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandler.kt
index e3959bb8..d2275bc4 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandler.kt
@@ -17,6 +17,7 @@ package com.nice.cxonechat
import com.google.gson.JsonIOException
import com.nice.cxonechat.event.ChatEvent
+import com.nice.cxonechat.exceptions.CXOneException
import com.nice.cxonechat.exceptions.MissingCustomerId
/**
@@ -28,33 +29,44 @@ import com.nice.cxonechat.exceptions.MissingCustomerId
interface ChatEventHandler {
/**
- * Sends an [event] to server without further delays. If sending of the
- * event fails, the event is considered consumed anyway.
+ * Sends an [event] to server without further delays from background thread.
+ * If sending of the event fails, the event is considered consumed anyway.
*
* If the event is sent to the server (not to be confused with processed
- * by the server), the [listener] is invoked.
+ * by the server), the [listener] is invoked (from background thread).
*
* @param event [ChatEvent] subclass which generates an event model.
* @param listener nullable listener if the client wants to know when it was sent.
- *
- * @throws MissingCustomerId in case of internal invalid state of the SDK.
- * @throws JsonIOException in case of internal SDK error during
- * the events' serialization.
+ * @param errorListener An optional listener for errors encountered when handling the event.
*/
- @Throws(
- MissingCustomerId::class,
- JsonIOException::class
- )
- fun trigger(event: ChatEvent, listener: OnEventSentListener? = null)
+ fun trigger(event: ChatEvent, listener: OnEventSentListener? = null, errorListener: OnEventErrorListener? = null)
/**
- * Listener to be notified when the triggered event is sent.
+ * Listener to be notified when the triggered event is considered sent.
*/
@Public
fun interface OnEventSentListener {
/**
- * Notifies about event being sent to the server.
+ * Notifies about event being sent to the server, or if the sending has failed and event is considered consumed.
+ * Method will be invoked on main thread.
*/
fun onSent()
}
+
+ /**
+ * Listener which will be notified when the triggered event has failed with an error.
+ */
+ @Public
+ fun interface OnEventErrorListener {
+
+ /**
+ * Notifies about event the reason why the event wasn't sent successfully to the server.
+ *
+ * @param exception The cause of failure. Possible causes are:
+ * * [MissingCustomerId] in case of internal invalid state of the SDK.
+ * * [JsonIOException] in case of internal SDK error during
+ * the events' serialization.
+ */
+ fun onError(exception: CXOneException)
+ }
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandlerActions.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandlerActions.kt
index 969dd684..9b4a0aae 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandlerActions.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatEventHandlerActions.kt
@@ -15,6 +15,7 @@
package com.nice.cxonechat
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
import com.nice.cxonechat.analytics.ActionMetadata
import com.nice.cxonechat.event.ChatWindowOpenEvent
@@ -46,7 +47,8 @@ object ChatEventHandlerActions {
* window.
*
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -55,7 +57,8 @@ object ChatEventHandlerActions {
fun ChatEventHandler.chatWindowOpen(
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(ChatWindowOpenEvent(date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ChatWindowOpenEvent(date), listener, errorListener)
/**
* Send a conversion event to the analytics server.
@@ -70,7 +73,8 @@ object ChatEventHandlerActions {
* @param value application-specific value of the conversion. Typically this will
* be the sale or subscription price.
* @param date date of the conversion event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -81,7 +85,8 @@ object ChatEventHandlerActions {
value: Number,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(ConversionEvent(type, value, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ConversionEvent(type, value, date), listener, errorListener)
/**
* Send an arbitrary custom analytics event to the analytics server.
@@ -90,7 +95,8 @@ object ChatEventHandlerActions {
* visitor event.
*
* @param data data to be sent in the custom event. Must be json encodable.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -99,7 +105,8 @@ object ChatEventHandlerActions {
fun ChatEventHandler.customVisitor(
data: Any,
listener: OnEventSentListener? = null,
- ) = trigger(CustomVisitorEvent(data), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(CustomVisitorEvent(data), listener, errorListener)
/**
* send a page viewed event to the server.
@@ -122,7 +129,8 @@ object ChatEventHandlerActions {
* Examples might include "com.nice.cxonechat.sample://category/cellphones" or
* "/details/4568".
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -133,7 +141,8 @@ object ChatEventHandlerActions {
uri: String,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(PageViewEvent(title, uri, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(PageViewEvent(title, uri, date), listener, errorListener)
/**
* send a page view ended event to the server when a previously viewed page
@@ -149,7 +158,8 @@ object ChatEventHandlerActions {
* Examples might include "com.nice.cxonechat.sample://category/cellphones" or
* "/details/4568".
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -160,7 +170,8 @@ object ChatEventHandlerActions {
uri: String,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(PageViewEndedEvent(title, uri, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(PageViewEndedEvent(title, uri, date), listener, errorListener)
/**
* Send a proactive action click event to the analytics.
@@ -170,7 +181,8 @@ object ChatEventHandlerActions {
*
* @param data [ActionMetadata] provided in [ChatActionHandler.onPopup] listener.
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -180,7 +192,8 @@ object ChatEventHandlerActions {
data: ActionMetadata,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(ProactiveActionClickEvent(data, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ProactiveActionClickEvent(data, date), listener, errorListener)
/**
* Send a proactive action display event to the analytics.
@@ -190,7 +203,8 @@ object ChatEventHandlerActions {
*
* @param data [ActionMetadata] provided in [ChatActionHandler.onPopup] listener.
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -200,7 +214,8 @@ object ChatEventHandlerActions {
data: ActionMetadata,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(ProactiveActionDisplayEvent(data, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ProactiveActionDisplayEvent(data, date), listener, errorListener)
/**
* Send a proactive action failure event to the analytics.
@@ -212,7 +227,8 @@ object ChatEventHandlerActions {
*
* @param data [ActionMetadata] provided in [ChatActionHandler.onPopup] listener.
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -222,7 +238,8 @@ object ChatEventHandlerActions {
data: ActionMetadata,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(ProactiveActionFailureEvent(data, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ProactiveActionFailureEvent(data, date), listener, errorListener)
/**
* Send a proactive action success event to the analytics.
@@ -233,7 +250,8 @@ object ChatEventHandlerActions {
*
* @param data [ActionMetadata] provided in [ChatActionHandler.onPopup] listener.
* @param date date of the event.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -243,19 +261,22 @@ object ChatEventHandlerActions {
data: ActionMetadata,
date: Date = Date(),
listener: OnEventSentListener? = null,
- ) = trigger(ProactiveActionSuccessEvent(data, date), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ProactiveActionSuccessEvent(data, date), listener, errorListener)
/**
* Refresh the authentication token associated with the chat.
*
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@JvmStatic
fun ChatEventHandler.refresh(
listener: OnEventSentListener? = null,
- ) = trigger(RefreshToken, listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(RefreshToken, listener, errorListener)
/**
* Trigger event specified in agent console or elsewhere as per your
@@ -263,7 +284,8 @@ object ChatEventHandlerActions {
* representative for more information.
*
* @param id ID of event to trigger per representative instructions.
- * @param listener listener to be notified after the event has been sent.
+ * @param listener an optional listener to be notified after the event has been sent.
+ * @param errorListener an optional error listener to be notified about errors encountered when event is handled.
* @see ChatEventHandler.trigger
*/
@JvmOverloads
@@ -271,5 +293,6 @@ object ChatEventHandlerActions {
fun ChatEventHandler.event(
id: UUID,
listener: OnEventSentListener? = null,
- ) = trigger(TriggerEvent(id), listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(TriggerEvent(id), listener, errorListener)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatFieldHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatFieldHandler.kt
index 98369b4f..add94915 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatFieldHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatFieldHandler.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
import com.nice.cxonechat.exceptions.InvalidCustomFieldValue
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatInstanceProvider.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatInstanceProvider.kt
index c4726427..ca9aa412 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatInstanceProvider.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatInstanceProvider.kt
@@ -18,10 +18,19 @@ package com.nice.cxonechat
import android.content.Context
import com.nice.cxonechat.ChatState.CONNECTED
import com.nice.cxonechat.ChatState.CONNECTING
-import com.nice.cxonechat.ChatState.CONNECTION_CLOSED
import com.nice.cxonechat.ChatState.CONNECTION_LOST
import com.nice.cxonechat.ChatState.INITIAL
-import com.nice.cxonechat.state.lookup
+import com.nice.cxonechat.ChatState.PREPARED
+import com.nice.cxonechat.ChatState.PREPARING
+import com.nice.cxonechat.ChatState.READY
+import com.nice.cxonechat.exceptions.InvalidStateException
+import com.nice.cxonechat.exceptions.RuntimeChatException
+import com.nice.cxonechat.log.Logger
+import com.nice.cxonechat.log.LoggerNoop
+import com.nice.cxonechat.log.LoggerScope
+import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.warning
+import com.nice.cxonechat.state.containsField
import com.nice.cxonechat.state.validate
import java.lang.ref.WeakReference
@@ -34,16 +43,23 @@ import java.lang.ref.WeakReference
* @param developmentMode True if in development mode to get extra logging.
* @param deviceTokenProvider Provider of device tokens for push messages, default implementation will
* disable push notifications.
+ * @param logger The [Logger] used by the SDK, default is no-op implementation.
+ * @param chatBuilderProvider **INTERNAL USAGE ONLY** Provides [ChatBuilder]. For internal testing usage only.
*/
-@Suppress("TooManyFunctions")
+@Suppress(
+ "TooManyFunctions",
+ "LongParameterList"
+)
@Public
-class ChatInstanceProvider(
+class ChatInstanceProvider private constructor(
configuration: SocketFactoryConfiguration?,
- authorization: Authorization? = null,
- userName: UserName? = null,
- developmentMode: Boolean = false,
- deviceTokenProvider: DeviceTokenProvider? = null,
-) : ChatStateListener {
+ authorization: Authorization?,
+ userName: UserName?,
+ developmentMode: Boolean,
+ deviceTokenProvider: DeviceTokenProvider?,
+ logger: Logger,
+ private val chatBuilderProvider: (Context, SocketFactoryConfiguration, Logger) -> ChatBuilder,
+) : ChatStateListener, LoggerScope by LoggerScope(TAG, logger) {
/** those interested in ChatInstanceProvider updates. */
@Public
interface Listener {
@@ -60,9 +76,15 @@ class ChatInstanceProvider(
* @param chatState New chat state.
*/
fun onChatStateChanged(chatState: ChatState) {}
+
+ /**
+ * Invoked when chat reports runtime exception which was encounter in background thread.
+ * @see [ChatStateListener.onChatRuntimeException].
+ */
+ fun onChatRuntimeException(exception: RuntimeChatException) {}
}
- /** Defines provider of device token for push notifications, typically this will [Firebase.messaging.token]. */
+ /** Defines provider of device token for push notifications, typically this will be `Firebase.messaging.token`. */
@Public
fun interface DeviceTokenProvider {
/**
@@ -93,6 +115,9 @@ class ChatInstanceProvider(
/** Current deviceToken provider. */
var deviceTokenProvider: DeviceTokenProvider?
+
+ /** Current [Logger]. */
+ var logger: Logger
}
/** Current configuration. */
@@ -115,6 +140,13 @@ class ChatInstanceProvider(
var deviceTokenProvider: DeviceTokenProvider? = deviceTokenProvider
private set
+ /** Current [Logger]. */
+ var logger: Logger = logger
+ private set
+
+ override val identity: Logger
+ get() = logger
+
/** token provided by deviceTokenProvider. */
private var deviceToken: String? = null
set(value) {
@@ -122,12 +154,6 @@ class ChatInstanceProvider(
chat?.setDeviceToken(value)
}
- /** Cancellable creating chat instance. */
- private var createJob: Cancellable? = null
-
- /** Cancellable establishing new chat connection. */
- private var reconnectJob: Cancellable? = null
-
/** List of listeners to be notified. */
private var listeners = listOf>()
@@ -136,18 +162,20 @@ class ChatInstanceProvider(
private set(value) {
if (field != value) {
field = value
- eachListener { onChatChanged(field) }
+ eachListener(value, Listener::onChatChanged)
}
}
+ private data class ChatStateInternal(
+ val state: ChatState,
+ val cancellable: Cancellable? = null,
+ )
+
+ private var state = ChatStateInternal(INITIAL)
+
/** Current chat state. */
- var chatState: ChatState = INITIAL
- private set(value) {
- if (field != value) {
- field = value
- eachListener { onChatStateChanged(value) }
- }
- }
+ val chatState: ChatState
+ get() = state.state
/**
* Add a listener to receive notifications of chat and state changes.
@@ -167,71 +195,161 @@ class ChatInstanceProvider(
* @param listener Listener to remove.
*/
fun removeListener(listener: Listener) {
- listeners = listeners.filter { it !== listener }
+ listeners = listeners.filter { it.get() !== listener }
}
+ private fun assertState(state: (ChatState) -> Boolean, generator: () -> String) {
+ if (!state(chatState)) {
+ throw InvalidStateException(generator())
+ }
+ }
+
+ private fun assertState(state: ChatState, generator: () -> String) =
+ assertState({ it === state }, generator)
+
/**
* Reestablish a chat connection if one does not currently exist.
* @param context Application context for resource access.
+ * @param newConfig Optional configuration which will be used to prepare [Chat] instance. If supplied, it will take precedence over
+ * previously set configuration.
+ * @throws InvalidStateException if the connection is not in the initial state, i.e.:
+ * * it has already been prepared or connected;
+ * * the [ChatInstanceProvider] was not provided with a configuration at creation time.
*/
- fun start(context: Context) {
- if (setOf(CONNECTED, CONNECTING).contains(chatState)) {
- return
+ @Throws(InvalidStateException::class)
+ @JvmOverloads
+ fun prepare(context: Context, newConfig: SocketFactoryConfiguration? = null) = scope("prepare") {
+ if (state.state == PREPARED) {
+ warning("Ignoring prepare in PREPARED state")
+ return@scope
}
- configuration?.let { configuration ->
- chatState = CONNECTING
+ assertState(INITIAL) {
+ "ChatInstanceProvider.prepare called in an incorrect state ($chatState). " +
+ "It is only valid from the INITIAL state."
+ }
- createJob = ChatBuilder(context = context, config = configuration).apply {
+ val currentConfig = configuration
+ val configuration = newConfig ?: currentConfig ?: throw InvalidStateException(
+ "ChatInstanceProvider called with no valid configuration. Insure the ChatInstanceProvider is " +
+ "properly configured before calling prepare."
+ )
+
+ chatBuilderProvider(context, configuration, logger)
+ .setChatStateListener(this@ChatInstanceProvider)
+ .setDevelopmentMode(developmentMode)
+ .apply {
userName?.run {
setUserName(first = firstName, last = lastName)
}
+ }
+ .apply {
authorization?.let(::setAuthorization)
- setDevelopmentMode(developmentMode)
- setChatStateListener(this@ChatInstanceProvider)
+ }
+ .apply {
deviceTokenProvider?.requestDeviceToken { token ->
deviceToken = token
setDeviceToken(token)
}
- }.build { result ->
- chat = result
- deviceToken?.let { chat?.setDeviceToken(it) }
}
- }
+ .build { result: Result ->
+ result.onSuccess { newChat ->
+ chat = newChat
+ advanceState(PREPARED)
+ deviceToken?.let { chat?.setDeviceToken(it) }
+ }.onFailure {
+ warning("Failed to prepare Chat", it)
+ chat = null
+ advanceState(INITIAL)
+ }
+ }
+ .also {
+ // if build is synchronous, the chat will have already advanced
+ // to PREPARED, so just skip PREPARING.
+ if (it != Cancellable.noop) {
+ advanceState(PREPARING, it)
+ }
+ }
}
/**
- * Cancel a pending start request.
+ * Connect the chat web socket so chat functions are available.
+ * @throws InvalidStateException if the connection is not in the correct state:
+ * * it has not been prepared;
+ * * it is already connected or connecting.
*/
- fun cancelStart() {
- createJob?.cancel()
- createJob = null
+ @Throws(InvalidStateException::class)
+ fun connect() = scope("connect") {
+ if (state.state == CONNECTED) {
+ warning("Ignoring connect in CONNECTED state")
+ return@scope
+ }
- chatState = INITIAL
+ assertState({ setOf(PREPARED, CONNECTION_LOST).contains(it) }) {
+ "ChatInstanceProvider.connect called in invalid state ($chatState). " +
+ "It is only allowed when the connection is either PREPARED or LOST_CONNECTION."
+ }
+
+ doConnect()
+ }
+
+ private fun doConnect() {
+ chat?.run {
+ val cancellable = connect()
+
+ if (cancellable != Cancellable.noop) {
+ // if connect is synchronous skip CONNECTING state
+ advanceState(CONNECTING, cancellable = cancellable, cancel = false)
+ }
+ }
}
/**
* Reconnect a broken connection.
+ * @throws InvalidStateException if the connection was not previously reported as lost
+ * or [connect] has already been called since it was reported lost.
*/
+ @Throws(InvalidStateException::class)
+ @Deprecated(
+ "ChatInstanceProvider.reconnect() has been deprecated. Replace with ChatInstanceProvider.connect()",
+ replaceWith = ReplaceWith("connect()")
+ )
fun reconnect() {
- reconnectJob = chat?.reconnect()?.also {
- chatState = CONNECTING
+ assertState(CONNECTION_LOST) {
+ "ChatInstanceProvider.reconnect called in invalid state ($chatState). " +
+ "It is only allowed after when the connection has been closed by the server. "
}
+
+ doConnect()
}
/**
- * Stop any existing chat attempts and reset the state to CONNECTION_CLOSED.
+ * Close any connected chat web sockets.
+ *
+ * After `close()` is called, only usage of [Chat.events] is allowed.
+ *
+ * The [state] is moved to [PREPARED].
*/
- fun stop() {
- reconnectJob?.cancel()
- reconnectJob = null
+ fun close() {
+ chat?.close()
- createJob?.cancel()
- createJob = null
+ advanceState(PREPARED)
+ }
- chat?.close()
- chat = null
- chatState = CONNECTION_CLOSED
+ /**
+ * Cancel any pending prepare or connect action and return the state
+ * to an appropriate starting point.
+ */
+ fun cancel() {
+ when (chatState) {
+ INITIAL -> Unit
+ PREPARING -> advanceState(INITIAL)
+ PREPARED -> Unit
+ CONNECTING -> advanceState(PREPARED)
+ CONNECTED -> Unit
+ CONNECTION_LOST -> advanceState(PREPARED)
+ READY -> Unit
+ }
}
/**
@@ -242,9 +360,10 @@ class ChatInstanceProvider(
authorization = null
userName = null
- chatState = CONNECTION_CLOSED
chat?.signOut()
chat = null
+
+ advanceState(INITIAL)
}
}
@@ -260,9 +379,7 @@ class ChatInstanceProvider(
fun setCustomerValues(values: Map) = apply {
chat?.run {
val customerCustomFields = configuration.customerCustomFields
- val fields = values.filter {
- customerCustomFields.lookup(it.key) != null
- }
+ val fields = values.filterKeys(customerCustomFields::containsField)
runCatching { customerCustomFields.validate(fields) }
.onSuccess {
@@ -274,7 +391,8 @@ class ChatInstanceProvider(
/**
* Update the configuration of chat.
*
- * 1. Stops any current chat.
+ * 1. Stops any current chat. This will result in discarding any stored [Authorization]
+ * or [UserName]. Any such details must be provided in the configuration block once again.
* 2. Executes the configuration actions block.
* 3. Restarts chat.
*
@@ -284,16 +402,14 @@ class ChatInstanceProvider(
fun configure(context: Context, actions: ConfigurationScope.() -> Unit) {
val provider = this
- chat?.signOut()
- chat = null
-
- object : ConfigurationScope {
- override val authenticationRequired: Boolean
- get() = provider.chat?.configuration?.isAuthorizationEnabled == true
+ val scope = object : ConfigurationScope {
+ override val authenticationRequired = provider.chat?.configuration?.isAuthorizationEnabled == true
override var configuration: SocketFactoryConfiguration?
get() = provider.configuration
- set(value) { provider.configuration = value }
+ set(value) {
+ provider.configuration = value
+ }
override var userName: UserName?
get() = provider.userName
@@ -318,50 +434,95 @@ class ChatInstanceProvider(
set(value) {
provider.deviceTokenProvider = value
}
- }.actions()
- restart(context)
+ override var logger: Logger
+ get() = provider.logger
+ set(value) {
+ provider.logger = value
+ }
+ }
+
+ signOut()
+
+ scope.actions()
+
+ prepare(context)
+ }
+
+ @JvmSynthetic
+ internal fun advanceState(next: ChatState, cancellable: Cancellable? = null, cancel: Boolean = true) {
+ if (chatState != next) {
+ if (cancel) {
+ state.cancellable?.cancel()
+ }
+
+ if (next in setOf(PREPARING, CONNECTING)) {
+ assert(cancellable != null) {
+ "Internal error: advanceState($next) requires a cancellable."
+ }
+ } else {
+ assert(cancellable == null) {
+ "Internal error: advanceState($next) prohibits a cancellable."
+ }
+ }
+
+ state = ChatStateInternal(next, cancellable)
+
+ eachListener(next, Listener::onChatStateChanged)
+ }
}
/**
* Iterate over the list of listeners, forwarding the given
* action or removing the listener if it's no longer valid.
*
+ * @param T An object which is passed to all listeners as part of an [action].
+ * @param actionParameter An object with will be passed to the action.
* @param action Action to perform on each listener.
*/
- private fun eachListener(action: Listener.() -> Unit) {
- listeners = listeners.filter {
- it.get()?.run {
- action()
- true
- } ?: false
+ private fun eachListener(actionParameter: T, action: Listener.(T) -> Unit) {
+ listeners = listeners.filter { listenerWeakReference ->
+ listenerWeakReference.get()?.also { listener -> listener.action(actionParameter) } != null
}
}
- /**
- * Stop any current connection under way and start a new connection attempt.
- *
- * @param context Application context for resource access.
- */
- private fun restart(context: Context) {
- stop()
- start(context)
- }
-
//
// ChatStateListener Implementation
//
override fun onConnected() {
- chatState = CONNECTED
+ advanceState(CONNECTED)
+ }
+
+ override fun onReady() {
+ advanceState(READY)
}
override fun onUnexpectedDisconnect() {
- chatState = CONNECTION_LOST
+ advanceState(CONNECTION_LOST)
+ }
+
+ override fun onChatRuntimeException(exception: RuntimeChatException) {
+ eachListener(exception, Listener::onChatRuntimeException)
+ }
+
+ /**
+ * Sets [UserName] which will be used during creation of [Chat] instance
+ * and will apply it to current instance of [Chat], if it exists.
+ * The username will be applied only if the chat channel configuration allows it.
+ *
+ * @param name A username which should be set.
+ * @see [Chat.setUserName].
+ */
+ fun setUserName(name: UserName) {
+ userName = name
+ chat?.setUserName(name.firstName, name.lastName)
}
@Public
companion object {
+ private const val TAG = "ChatInstanceProvider"
+
@Suppress("LateinitUsage")
private lateinit var instance: ChatInstanceProvider
@@ -376,8 +537,12 @@ class ChatInstanceProvider(
* @param userName Initial user name to use.
* @param developmentMode True if in development mode to get extra logging.
* @param deviceTokenProvider Provider of device tokens for push messages.
+ * @param logger [Logger] to be used by the ChatInstanceProvider and Chat.
* @return the newly created ChatInstanceProvider singleton.
*/
+ @Suppress(
+ "LongParameterList" // Most of the parameters have default values provided.
+ )
@JvmOverloads
fun create(
configuration: SocketFactoryConfiguration?,
@@ -385,12 +550,47 @@ class ChatInstanceProvider(
userName: UserName? = null,
developmentMode: Boolean = false,
deviceTokenProvider: DeviceTokenProvider? = null,
+ logger: Logger = LoggerNoop,
+ ) = create(
+ configuration,
+ authorization,
+ userName,
+ developmentMode,
+ deviceTokenProvider,
+ logger,
+ ChatBuilder.Companion::invoke,
+ )
+
+ /**
+ * Create the ChatInstanceProvider singleton.
+ *
+ * @param configuration Initial Sdk Configuration to use.
+ * @param authorization Initial authorization to use.
+ * @param userName Initial user name to use.
+ * @param developmentMode True if in development mode to get extra logging.
+ * @param deviceTokenProvider Provider of device tokens for push messages.
+ * @param logger [Logger] to be used by the ChatInstanceProvider and Chat.
+ * @param chatBuilderProvider **INTERNAL USAGE ONLY** Provides [ChatBuilder]. For internal testing usage only.
+ * @return the newly created ChatInstanceProvider singleton.
+ */
+ @Suppress("LongParameterList")
+ @JvmSynthetic
+ internal fun create(
+ configuration: SocketFactoryConfiguration?,
+ authorization: Authorization? = null,
+ userName: UserName? = null,
+ developmentMode: Boolean = false,
+ deviceTokenProvider: DeviceTokenProvider? = null,
+ logger: Logger = LoggerNoop,
+ chatBuilderProvider: (Context, SocketFactoryConfiguration, Logger) -> ChatBuilder,
) = ChatInstanceProvider(
configuration,
authorization,
userName,
developmentMode,
deviceTokenProvider,
+ logger,
+ chatBuilderProvider,
).also {
instance = it
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatMode.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatMode.kt
new file mode 100644
index 00000000..5ceaf2a0
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatMode.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat
+
+/** Chat mode in use, only valid when state is connected. */
+@Public
+enum class ChatMode {
+ /**
+ * Chat is single-threaded.
+ *
+ * Creating and archiving threads is not allowed. The single thread will be automatically
+ * created if necessary.
+ */
+ SINGLE_THREAD,
+
+ /** Chat is multi-threaded. */
+ MULTI_THREAD,
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatState.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatState.kt
index ba1395cc..09cf8a27 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatState.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatState.kt
@@ -23,15 +23,40 @@ enum class ChatState {
/** Not yet configured enough to connect. */
INITIAL,
- /** in the process of connecting. */
+ /**
+ * In the process of preparing the chat by performing initial configuration
+ * checks fetching the channel configuration.
+ */
+ PREPARING,
+
+ /**
+ * The chat is "prepared" but no web socket is open.
+ *
+ * In the prepared state it is acceptable to generate analytics events via
+ * [[ChatEventHandlerActions]] and to attempt to connect the web socket via
+ * [Chat.connect], but chat functionality via [Chat.threads] is
+ * unavailable.
+ */
+ PREPARED,
+
+ /** In the process of connecting the websocket. */
CONNECTING,
- /** a connection has been established. */
+ /**
+ * A websocket connection has been established.
+ *
+ * In the CONNECTED state it is acceptable to generate analytics events via
+ * [[ChatEventHandlerActions]] or to access chat functionality available via
+ * [Chat.threads].
+ */
CONNECTED,
+ /**
+ * A chat state was recovered (if there was anything to recover).
+ * If there were any thread/s recovered, then this fact should have signaled via listener.
+ */
+ READY,
+
/** the connection was involuntarily lost. */
CONNECTION_LOST,
-
- /** the connection was closed by the user. */
- CONNECTION_CLOSED
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatStateListener.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatStateListener.kt
index 53f03c66..bcae04b2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatStateListener.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatStateListener.kt
@@ -1,5 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
+import com.nice.cxonechat.exceptions.RuntimeChatException
+
/**
* Listener for [Chat] instance state changes.
* The current main purpose of this listener is to provide callbacks which notify integrating application about
@@ -25,4 +42,17 @@ interface ChatStateListener {
* This happens once initial connection is established or after [Chat.reconnect] is called.
*/
fun onConnected()
+
+ /**
+ * Method is invoked when chat instance has finished performing background tasks after connection was established.
+ */
+ fun onReady()
+
+ /**
+ * Method is invoked when [Chat] instance encounters possible exception in a background process.
+ * Application should handle these exceptions according to the description of each [RuntimeChatException].
+ * Some of these exceptions can indicate issues during transfer of messages while others may indicate that further
+ * interactions with [Chat] will be ignored.
+ */
+ fun onChatRuntimeException(exception: RuntimeChatException)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandler.kt
index 077d86d0..70ac9111 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandler.kt
@@ -16,6 +16,7 @@
package com.nice.cxonechat
import com.nice.cxonechat.event.thread.ChatThreadEvent
+import com.nice.cxonechat.exceptions.CXOneException
import com.nice.cxonechat.exceptions.MissingCustomerId
import com.nice.cxonechat.thread.ChatThread
@@ -38,13 +39,14 @@ interface ChatThreadEventHandler {
* @param event [ChatThreadEvent] subclass which generates an event model.
* @param listener nullable listener if the client wants to know when it
* was sent.
- *
- * @throws MissingCustomerId in case of internal invalid state.
+ * @param errorListener An optional listener if the client wants to know about errors encountered when handling
+ * the event.
*/
- @Throws(
- MissingCustomerId::class
+ fun trigger(
+ event: ChatThreadEvent,
+ listener: OnEventSentListener? = null,
+ errorListener: OnEventErrorListener? = null,
)
- fun trigger(event: ChatThreadEvent, listener: OnEventSentListener? = null)
/**
* A listener to be notified when the triggered event is sent.
@@ -56,4 +58,18 @@ interface ChatThreadEventHandler {
*/
fun onSent()
}
+
+ /**
+ * Listener which will be notified when the triggered event has failed with an error.
+ */
+ @Public
+ fun interface OnEventErrorListener {
+
+ /**
+ * Notifies about event the reason why the event wasn't sent successfully to the server.
+ * @param exception The cause of failure. Possible cause can be:
+ * * [MissingCustomerId] in case of internal invalid state.
+ */
+ fun onError(exception: CXOneException)
+ }
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandlerActions.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandlerActions.kt
index a8811542..8bedde77 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandlerActions.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadEventHandlerActions.kt
@@ -1,5 +1,21 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener
import com.nice.cxonechat.event.thread.ArchiveThreadEvent
import com.nice.cxonechat.event.thread.LoadThreadMetadataEvent
@@ -22,7 +38,8 @@ object ChatThreadEventHandlerActions {
@JvmStatic
fun ChatThreadEventHandler.archiveThread(
listener: OnEventSentListener? = null,
- ) = trigger(ArchiveThreadEvent, listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(ArchiveThreadEvent, listener, errorListener)
/**
* @see ChatThreadEventHandler.trigger
@@ -32,7 +49,8 @@ object ChatThreadEventHandlerActions {
@JvmStatic
fun ChatThreadEventHandler.markThreadRead(
listener: OnEventSentListener? = null,
- ) = trigger(MarkThreadReadEvent, listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(MarkThreadReadEvent, listener, errorListener)
/**
* @see ChatThreadEventHandler.trigger
@@ -42,7 +60,8 @@ object ChatThreadEventHandlerActions {
@JvmStatic
fun ChatThreadEventHandler.typingEnd(
listener: OnEventSentListener? = null,
- ) = trigger(TypingEndEvent, listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(TypingEndEvent, listener, errorListener)
/**
* @see ChatThreadEventHandler.trigger
@@ -52,7 +71,8 @@ object ChatThreadEventHandlerActions {
@JvmStatic
fun ChatThreadEventHandler.typingStart(
listener: OnEventSentListener? = null,
- ) = trigger(TypingStartEvent, listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(TypingStartEvent, listener, errorListener)
/**
* Send a [LoadThreadMetadataEvent] requesting additional thread information.
@@ -64,5 +84,6 @@ object ChatThreadEventHandlerActions {
@JvmStatic
fun ChatThreadEventHandler.loadMetadata(
listener: OnEventSentListener? = null,
- ) = trigger(LoadThreadMetadataEvent, listener)
+ errorListener: OnEventErrorListener? = null,
+ ) = trigger(LoadThreadMetadataEvent, listener, errorListener)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadHandler.kt
index 2cbe0627..da6a75d1 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadHandler.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
import androidx.annotation.CheckResult
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadMessageHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadMessageHandler.kt
index 72f5a203..e7247f6d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadMessageHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadMessageHandler.kt
@@ -64,13 +64,16 @@ interface ChatThreadMessageHandler {
* background thread, though [listener] will always be invoked on a
* foreground thread.
*
+ * Note that messages with no test, attachments, or postback specified will
+ * be silently ignored.
+ *
* If you are supplying attachments for upload, then be aware of the following.
*
- * If attachment misses file name, the file is named to "document"
+ * * If attachment misses file name, the file is named to "document"
* upon being sent to the server. Please take care to provide localized
* file names if you want to display them to the user.
*
- * The upload of files is performed at most **once** before subsequent
+ * * The upload of files is performed at most **once** before subsequent
* processing of the message and sending it to the server. If the file
* call succeeds, it's cached internally to avoid doubling uploads.
* Therefore, subsequent calls (if the primary were to fail) are much
@@ -79,12 +82,19 @@ interface ChatThreadMessageHandler {
* upload. This cache is active as long as the [ChatBuilder] instance
* remains the same. Reinitializing the [Chat] doesn't clear the cache.
*
- * If any upload of any attachment fails by connection error, [listener]
+ * * If any upload of any attachment fails by connection error, [listener]
* will **not** be invoked for even processing triggers. The error is
- * muted and consumed within the thread.
+ * passed to the [ChatStateListener.onChatRuntimeException] as
+ * an instance of [com.nice.cxonechat.exceptions.RuntimeChatException.AttachmentUploadError]
+ * with information about the failed attachment upload.
*
- * If any upload of any attachment fails by server error (returns but an
+ * * If any upload of any attachment fails by server error (returns but an
* empty body), then the attachment is skipped, and execution continues.
+ *
+ * @param message Message to be sent.
+ * @param listener listener to be notified when the message has been sent.
+ * @throws InvalidParameterException if the message is empty, ie., has no attachment,
+ * message, or postback.
*/
fun send(message: OutboundMessage, listener: OnMessageTransferListener? = null)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadingImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadingImpl.kt
index bb5bcb96..7339731e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadingImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadingImpl.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
import com.nice.cxonechat.internal.ChatWithParameters
@@ -5,7 +20,7 @@ import com.nice.cxonechat.internal.ChatWithParameters
internal class ChatThreadingImpl(
private val origin: ChatWithParameters
) : ChatWithParameters by origin {
- override fun reconnect(): Cancellable = origin.entrails.threading.background {
- origin.reconnect()
+ override fun connect(): Cancellable = origin.entrails.threading.background {
+ origin.connect()
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadsHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadsHandler.kt
index 601c25fb..da1df29e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadsHandler.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/ChatThreadsHandler.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
import androidx.annotation.CheckResult
@@ -32,8 +47,11 @@ interface ChatThreadsHandler {
val preChatSurvey: PreChatSurvey?
/**
- * Sends a request to refresh the thread-list. It's important that you register
- * a callback with [threads], which returns the newly refreshed values.
+ * Sends a request to refresh the thread-list.
+ *
+ * This method will be called once per [ChatThreadsHandler] creation. Subsequently,
+ * the owner can call [refresh] again to update the threads list. One possible use
+ * might be to use it whenever a threads list is redisplayed after a long idle period.
*
* Client needs to register only one [OnThreadsUpdatedListener] per chat instance.
* All subsequent [refresh] calls will notify listeners registered in this instance.
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/SocketFactoryConfiguration.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/SocketFactoryConfiguration.kt
index 8c8a2526..72810f59 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/SocketFactoryConfiguration.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/SocketFactoryConfiguration.kt
@@ -1,5 +1,21 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat
+import com.nice.cxonechat.core.BuildConfig
import com.nice.cxonechat.enums.CXOneEnvironment
import com.nice.cxonechat.state.Environment
@@ -36,6 +52,7 @@ interface SocketFactoryConfiguration {
* The library always supplies its own version, though you might be asked
* (or willing to try) to change it in case of beta features, for example.
*/
+ @Deprecated("This field is deprecated for public usage and will be removed from public API.")
val version: String
@Public
@@ -48,7 +65,21 @@ interface SocketFactoryConfiguration {
*/
@JvmName("create")
@JvmStatic
- @JvmOverloads
+ @Suppress("DEPRECATION")
+ operator fun invoke(
+ environment: Environment,
+ brandId: Long,
+ channelId: String,
+ ) = invoke(environment, brandId, channelId, BuildConfig.VERSION_NAME)
+
+ /**
+ * Helper method to create a new configuration.
+ *
+ * @see SocketFactoryConfiguration
+ */
+ @JvmName("create")
+ @JvmStatic
+ @Deprecated("This method is deprecated for public usage and will be removed from public API.")
operator fun invoke(
environment: Environment,
brandId: Long,
@@ -58,6 +89,8 @@ interface SocketFactoryConfiguration {
override val environment = environment
override val brandId = brandId
override val channelId = channelId
+
+ @Deprecated("This field is deprecated for public usage and will be removed from public API.")
override val version = version
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/api/RemoteServiceCaching.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/api/RemoteServiceCaching.kt
index 0c5be1fa..5d5ff0d2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/api/RemoteServiceCaching.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/api/RemoteServiceCaching.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.api
import com.nice.cxonechat.api.model.AttachmentUploadResponse
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/api/model/AttachmentUploadResponse.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/api/model/AttachmentUploadResponse.kt
index 94e01d89..6edb33fb 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/api/model/AttachmentUploadResponse.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/api/model/AttachmentUploadResponse.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.api.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ActionType.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ActionType.kt
index 8e731dd3..84e8b1bb 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ActionType.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ActionType.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.enums
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/CXOneEnvironment.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/CXOneEnvironment.kt
index 3cf01f7c..9ff40278 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/CXOneEnvironment.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/CXOneEnvironment.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.enums
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ErrorType.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ErrorType.kt
new file mode 100644
index 00000000..fd0b0d4c
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/ErrorType.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.enums
+
+import com.google.gson.annotations.SerializedName
+
+/**
+ * Definition of all errors reported by the server.
+ */
+internal enum class ErrorType(val value: String) {
+
+ @SerializedName("ConsumerReconnectionFailed")
+ ConsumerReconnectionFailed("ConsumerReconnectionFailed"),
+
+ @SerializedName("TokenRefreshingFailed")
+ TokenRefreshingFailed("TokenRefreshingFailed"),
+
+ @SerializedName("SendingMessageFailed")
+ SendingMessageFailed("SendingMessageFailed"),
+
+ @SerializedName("RecoveringLivechatFailed")
+ RecoveringLivechatFailed("RecoveringLivechatFailed"),
+
+ @SerializedName("RecoveringThreadFailed")
+ RecoveringThreadFailed("RecoveringThreadFailed"),
+
+ @SerializedName("SendingOutboundFailed")
+ SendingOutboundFailed("SendingOutboundFailed"),
+
+ @SerializedName("UpdatingThreadFailed")
+ UpdatingThreadFailed("UpdatingThreadFailed"),
+
+ @SerializedName("ArchivingThreadFailed")
+ ArchivingThreadFailed("ArchivingThreadFailed"),
+
+ @SerializedName("SendingTranscriptFailed")
+ SendingTranscriptFailed("SendingTranscriptFailed"),
+
+ @SerializedName("SendingOfflineMessageFailed")
+ SendingOfflineMessageFailed("SendingOfflineMessageFailed"),
+
+ MetadataLoadFailed("MetadataLoadFailed"),
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventAction.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventAction.kt
index f4cf1c4b..9ddf0acb 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventAction.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventAction.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.enums
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventType.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventType.kt
index fe049381..be468549 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventType.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/EventType.kt
@@ -129,6 +129,9 @@ internal enum class EventType(val value: String) {
@SerializedName("CaseCreated")
CaseCreated("CaseCreated"), // TODO: Remove?
+ @SerializedName("CaseStatusChanged")
+ CaseStatusChanged("CaseStatusChanged"),
+
// Custom Fields
/** An event to send to set custom field values for a contact (thread). */
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/MessageContentType.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/MessageContentType.kt
index 2f67838f..137e27fa 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/MessageContentType.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/enums/MessageContentType.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.enums
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/AuthorizeCustomerEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/AuthorizeCustomerEvent.kt
index 9acc96c2..4fc76796 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/AuthorizeCustomerEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/AuthorizeCustomerEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event
import com.nice.cxonechat.internal.model.network.ActionAuthorizeCustomer
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ChatEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ChatEvent.kt
index ac189b24..83d65625 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ChatEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ChatEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/CustomVisitorEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/CustomVisitorEvent.kt
index 50d767f7..9b513d88 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/CustomVisitorEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/CustomVisitorEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ReconnectCustomerEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ReconnectCustomerEvent.kt
index d942a42e..5808e465 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ReconnectCustomerEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/ReconnectCustomerEvent.kt
@@ -26,7 +26,7 @@ internal object ReconnectCustomerEvent : ChatEvent() {
storage: ValueStorage,
) = ActionReconnectCustomer(
connection = connection,
- token = storage.authToken.let(::requireNotNull),
+ token = storage.authToken,
visitor = storage.visitorId
)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/SetCustomerCustomFieldEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/SetCustomerCustomFieldEvent.kt
index b2d92c95..47a556e6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/SetCustomerCustomFieldEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/SetCustomerCustomFieldEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event
import com.nice.cxonechat.internal.model.CustomFieldModel
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/TriggerEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/TriggerEvent.kt
index 936f0ee5..bcb2ee7b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/TriggerEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/TriggerEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/ChatThreadEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/ChatThreadEvent.kt
index 272ed514..bb3a437f 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/ChatThreadEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/ChatThreadEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event.thread
import com.nice.cxonechat.ChatThreadEventHandler
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/MessageEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/MessageEvent.kt
index 8dbe9621..b6c31e6d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/MessageEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/MessageEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event.thread
import com.nice.cxonechat.internal.model.AttachmentModel
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SendOutboundEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SendOutboundEvent.kt
index 635d9656..c0b5f976 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SendOutboundEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SendOutboundEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event.thread
import com.nice.cxonechat.internal.model.network.ActionOutboundMessage
@@ -8,6 +23,7 @@ import java.util.UUID
internal class SendOutboundEvent(
private val message: String,
private val authToken: String?,
+ private val id: UUID = UUID.randomUUID(),
) : ChatThreadEvent() {
override fun getModel(
@@ -16,7 +32,7 @@ internal class SendOutboundEvent(
) = ActionOutboundMessage(
connection = connection,
thread = thread,
- id = UUID.randomUUID(),
+ id = id,
message = message,
attachments = emptyList(),
fields = emptyList(), // SendOutboundEvent can't have customer data (for now).
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SetContactCustomFieldEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SetContactCustomFieldEvent.kt
index 1612aff1..166fa1cc 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SetContactCustomFieldEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/SetContactCustomFieldEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event.thread
import com.nice.cxonechat.internal.model.CustomFieldModel
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/UpdateThreadEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/UpdateThreadEvent.kt
index c0f6151b..d816a663 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/UpdateThreadEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/event/thread/UpdateThreadEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.event.thread
import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.asCopyable
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/exceptions/CXOneException.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/exceptions/CXOneException.kt
index c638b889..0c3c1ef8 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/exceptions/CXOneException.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/exceptions/CXOneException.kt
@@ -25,9 +25,6 @@ import com.nice.cxonechat.Public
sealed class CXOneException : Exception {
constructor(message: String?) : super(message)
- @Suppress(
- "UNUSED" // Reserved for future usage
- )
constructor(message: String?, cause: Throwable?) : super(message, cause)
@Suppress(
@@ -43,13 +40,34 @@ sealed class CXOneException : Exception {
}
}
+/**
+ * An action was attempted when a [ChatInstanceProvider] was in an invalid state.
+ *
+ * Some examples of invalid states might be:
+ * * calling [ChatInstanceProvider.connect] on an unprepared provider;
+ * * calling [ChatInstanceProvider.prepare] on a prepared or connected provider;
+ *
+ * Further details are available in the exception description.
+ */
+@Public
+class InvalidStateException internal constructor(message: String) : CXOneException(message)
+
+/**
+ * An action was attempted with an invalid parameter.
+ *
+ * Some examples of invalid parameters are:
+ * * calling [ChatThreadMessageHandler.send] with a message with no message, attachment, or postback text.
+ */
+@Public
+class InvalidParameterException internal constructor(message: String) : CXOneException(message)
+
/**
* The method being called is not supported with the current channel configuration.
*/
@Public
class UnsupportedChannelConfigException internal constructor() : CXOneException(
"The method you are trying to call is not supported with your current channel configuration." +
- " For example, archiving a thread is only supported on a channel configured for multiple threads."
+ " For example, archiving a thread is only supported on a channel configured for multiple threads."
)
/**
@@ -115,3 +133,57 @@ class MissingCustomerId internal constructor() : CXOneException(
*/
@Public
class InternalError internal constructor(message: String) : CXOneException(message)
+
+/**
+ * The SDK was unable to dispatch analytics event to server, due to some kind of connectivity issue.
+ */
+@Public
+class AnalyticsEventDispatchException(message: String, throwable: Throwable?) : CXOneException(message, throwable)
+
+/**
+ *
+ */
+@Public
+sealed class RuntimeChatException(message: String, cause: Throwable? = null) : CXOneException(message, cause) {
+
+ /**
+ * Exception reported when the SDK was unable to upload supplied attachment.
+ *
+ * @property attachmentName Name of file as it was specified in the
+ * [com.nice.cxonechat.message.ContentDescriptor.fileName] supplied for upload.
+ * @param cause In case of networking error it will be [java.io.IOException] or [java.lang.RuntimeException], in
+ * case of backend error it will be [InvalidStateException].
+ */
+ @Public
+ class AttachmentUploadError internal constructor(val attachmentName: String?, cause: Throwable?) : RuntimeChatException(
+ message = "Failure during upload of an attachment: $attachmentName",
+ cause = cause
+ )
+
+ /**
+ * Exception reported when server reports error in response to an action (e.g. sending of a message).
+ *
+ * The message will contain a simple code string which marks reported error.
+ * Errors:
+ * - SendingMessageFailed
+ * - RecoveringLivechatFailed
+ * - RecoveringThreadFailed
+ * - SendingOutboundFailed
+ * - UpdatingThreadFailed
+ * - ArchivingThreadFailed
+ * - SendingTranscriptFailed
+ * - SendingOfflineMessageFailed
+ * - MetadataLoadFailed
+ */
+ @Public
+ class ServerCommunicationError internal constructor(message: String) : RuntimeChatException(message)
+
+ /**
+ * SDK has received information from server that authorization of user has failed.
+ * SDK instance should be considered in invalid state. New instance should be created before connection attempt is
+ * made again.
+ * Integrators should also check if their authorization setup is correct.
+ */
+ @Public
+ class AuthorizationError internal constructor(message: String) : RuntimeChatException(message)
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/CaseStatusChangedHandlerActions.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/CaseStatusChangedHandlerActions.kt
new file mode 100644
index 00000000..3579d2ed
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/CaseStatusChangedHandlerActions.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.asCopyable
+import com.nice.cxonechat.internal.model.ChatThreadMutable
+import com.nice.cxonechat.internal.model.network.EventCaseStatusChanged
+import com.nice.cxonechat.internal.model.network.EventCaseStatusChanged.CaseStatus.CLOSED
+import com.nice.cxonechat.thread.ChatThread
+
+internal object CaseStatusChangedHandlerActions {
+ inline fun handleCaseClosed(
+ thread: ChatThreadMutable,
+ event: EventCaseStatusChanged,
+ crossinline onThreadUpdate: (ChatThread) -> Unit,
+ ) {
+ if (event.inThread(thread)) {
+ val notArchived = event.status !== CLOSED
+ val canAddMoreMessagesChanged = notArchived != thread.canAddMoreMessages
+ if (canAddMoreMessagesChanged) {
+ thread.update(thread.asCopyable().copy(canAddMoreMessages = notArchived))
+ onThreadUpdate(thread)
+ }
+ }
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerImpl.kt
index 2c91cfa9..ab4b3111 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerImpl.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatActionHandler
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerLogging.kt
index d7b57219..cb7bd3c6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatActionHandlerLogging.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatActionHandler
@@ -5,8 +20,8 @@ import com.nice.cxonechat.ChatActionHandler.OnPopupActionListener
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
internal class ChatActionHandlerLogging(
private val origin: ChatActionHandler,
@@ -14,14 +29,14 @@ internal class ChatActionHandlerLogging(
) : ChatActionHandler, LoggerScope by LoggerScope(logger) {
init {
- finest("Initialized")
+ verbose("Initialized")
}
override fun onPopup(listener: OnPopupActionListener) = scope("onPopup") {
- finest("Registered")
+ verbose("Registered")
origin.onPopup { params, metadata ->
scope("onShowPopup") {
- finest("params=$params, metadata=$metadata")
+ verbose("params=$params, metadata=$metadata")
duration { listener.onShowPopup(params, metadata) }
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatAuthorization.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatAuthorization.kt
index a44fa17c..f6f0613c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatAuthorization.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatAuthorization.kt
@@ -1,14 +1,32 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Authorization
import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.enums.ErrorType
import com.nice.cxonechat.enums.EventType.CustomerAuthorized
import com.nice.cxonechat.enums.EventType.TokenRefreshed
import com.nice.cxonechat.event.AuthorizeCustomerEvent
import com.nice.cxonechat.event.ReconnectCustomerEvent
+import com.nice.cxonechat.exceptions.RuntimeChatException.AuthorizationError
import com.nice.cxonechat.internal.copy.ConnectionCopyable.Companion.asCopyable
import com.nice.cxonechat.internal.model.network.EventCustomerAuthorized
import com.nice.cxonechat.internal.model.network.EventTokenRefreshed
+import com.nice.cxonechat.internal.socket.ErrorCallback.Companion.addErrorCallback
import com.nice.cxonechat.internal.socket.EventCallback.Companion.addCallback
import java.util.UUID
@@ -42,9 +60,17 @@ internal class ChatAuthorization(
storage.authTokenExpDate = model.expiresAt
}
+ private val customerReconnectFailed = socketListener.addErrorCallback(ErrorType.ConsumerReconnectionFailed) {
+ origin.chatStateListener?.onChatRuntimeException(AuthorizationError("Failed to reconnect authorized customer."))
+ }
+
+ private val tokenRefreshFailed = socketListener.addErrorCallback(ErrorType.TokenRefreshingFailed) {
+ origin.chatStateListener?.onChatRuntimeException(AuthorizationError("Failed to refresh authorization token."))
+ }
+
init {
if (storage.customerId == null) {
- connection = connection.asCopyable().copy(customerId = UUID.randomUUID())
+ connection = connection.asCopyable().copy(customerId = UUID.randomUUID().toString())
}
authorizeCustomer()
}
@@ -60,10 +86,12 @@ internal class ChatAuthorization(
override fun close() {
customerAuthorized.cancel()
tokenRefresh.cancel()
+ customerReconnectFailed.cancel()
+ tokenRefreshFailed.cancel()
origin.close()
}
- override fun reconnect(): Cancellable = origin.reconnect().also {
+ override fun connect(): Cancellable = origin.connect().also {
authorizeCustomer()
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderDefault.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderDefault.kt
index 2a5e72e9..3373fbba 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderDefault.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderDefault.kt
@@ -19,15 +19,19 @@ import com.nice.cxonechat.Authorization
import com.nice.cxonechat.Cancellable
import com.nice.cxonechat.ChatBuilder
import com.nice.cxonechat.ChatBuilder.OnChatBuiltCallback
+import com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback
+import com.nice.cxonechat.ChatMode.MULTI_THREAD
+import com.nice.cxonechat.ChatMode.SINGLE_THREAD
import com.nice.cxonechat.ChatStateListener
import com.nice.cxonechat.ChatThreadingImpl
import com.nice.cxonechat.internal.copy.ConnectionCopyable.Companion.asCopyable
+import com.nice.cxonechat.internal.model.ChannelConfiguration
import com.nice.cxonechat.internal.socket.SocketFactory
import com.nice.cxonechat.internal.socket.StateReportingSocketFactory
+import com.nice.cxonechat.state.Connection
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
-import java.io.IOException
internal class ChatBuilderDefault(
private val entrails: ChatEntrails,
@@ -62,8 +66,27 @@ internal class ChatBuilderDefault(
deviceToken = token
}
- @Throws(IllegalStateException::class, IOException::class, RuntimeException::class)
- override fun build(callback: OnChatBuiltCallback): Cancellable {
+ @Deprecated(
+ message = "Please migrate to build method with OnChatBuildResultCallback",
+ replaceWith = ReplaceWith(
+ expression = "build(resultCallback = OnChatBuiltResultCallback { callback.onChatBuilt(it.getOrThrow()) })",
+ imports = ["com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback"]
+ )
+ )
+ override fun build(callback: OnChatBuiltCallback): Cancellable =
+ build(resultCallback = { chatResult -> callback.onChatBuilt(chatResult.getOrThrow()) })
+
+ override fun build(resultCallback: OnChatBuiltResultCallback): Cancellable {
+ resultCallback.onChatBuiltResult(
+ runCatching {
+ val chatParameters = prepareChatParameters()
+ createChatInstance(chatParameters)
+ }
+ )
+ return Cancellable.noop
+ }
+
+ private fun prepareChatParameters(): ChatParameters {
val socketFactory = chatStateListener?.let { StateReportingSocketFactory(it, factory) } ?: factory
var connection = socketFactory.getConfiguration(entrails.storage)
val firstName = firstName
@@ -79,24 +102,44 @@ internal class ChatBuilderDefault(
check(response.isSuccessful) { "Response from the server was not successful" }
val body = checkNotNull(response.body()) { "Response body was null" }
val storeVisitorCallback = if (isDevelopment) StoreVisitorCallback(entrails.logger) else IgnoredCallback
+ return ChatParameters(connection, socketFactory, body, storeVisitorCallback)
+ }
+
+ private fun createChatInstance(
+ chatParameters: ChatParameters,
+ ): ChatWithParameters {
+ val storeVisitorCallback: Callback = chatParameters.storeVisitorCallback
var chat: ChatWithParameters
chat = ChatImpl(
- connection = connection,
+ connection = chatParameters.connection,
entrails = entrails,
- socketFactory = socketFactory,
- configuration = body.toConfiguration(connection.channelId),
- callback = storeVisitorCallback
+ socketFactory = chatParameters.socketFactory,
+ configuration = chatParameters.body.toConfiguration(chatParameters.connection.channelId),
+ callback = storeVisitorCallback,
+ chatStateListener = chatStateListener
)
+ chat = ChatMemoizeThreadsHandler(chat)
chat = ChatAuthorization(chat, authorization)
chat = ChatStoreVisitor(chat, storeVisitorCallback)
chat = ChatWelcomeMessageUpdate(chat)
+ chat = ChatServerErrorReporting(chat)
+ chat = when (chat.chatMode) {
+ SINGLE_THREAD -> ChatSingleThread(chat)
+ MULTI_THREAD -> ChatMultiThread(chat)
+ }
chat = ChatThreadingImpl(chat)
- if (isDevelopment) chat = ChatLogging(chat, entrails.logger)
- callback.onChatBuilt(chat)
- return Cancellable.noop
+ if (isDevelopment) chat = ChatLogging(chat)
+ return chat
}
}
+private data class ChatParameters(
+ val connection: Connection,
+ val socketFactory: SocketFactory,
+ val body: ChannelConfiguration,
+ val storeVisitorCallback: Callback,
+)
+
private object IgnoredCallback : Callback {
override fun onResponse(call: Call, response: Response) = Unit
override fun onFailure(p0: Call, p1: Throwable) = Unit
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderLogging.kt
index 7a64f725..317be4e5 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderLogging.kt
@@ -19,11 +19,12 @@ import com.nice.cxonechat.Authorization
import com.nice.cxonechat.Cancellable
import com.nice.cxonechat.ChatBuilder
import com.nice.cxonechat.ChatBuilder.OnChatBuiltCallback
+import com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback
import com.nice.cxonechat.ChatStateListener
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
+import com.nice.cxonechat.log.error
import com.nice.cxonechat.log.scope
-import com.nice.cxonechat.log.severe
internal class ChatBuilderLogging(
private val origin: ChatBuilder,
@@ -36,7 +37,7 @@ internal class ChatBuilderLogging(
origin.setAuthorization(authorization)
}
- override fun setDevelopmentMode(enabled: Boolean) = scope("setDevelopmentMode") {
+ override fun setDevelopmentMode(enabled: Boolean): ChatBuilder = scope("setDevelopmentMode") {
this@ChatBuilderLogging.developmentMode = enabled
origin.setDevelopmentMode(enabled)
}
@@ -53,11 +54,27 @@ internal class ChatBuilderLogging(
origin.setDeviceToken(token)
}
+ @Deprecated(
+ "Please migrate to build method with OnChatBuildResultCallback",
+ replaceWith = ReplaceWith(
+ "build(resultCallback = OnChatBuiltResultCallback { callback.onChatBuilt(it.getOrThrow()) })",
+ "com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback"
+ )
+ )
override fun build(callback: OnChatBuiltCallback): Cancellable = scope("build") {
return try {
- duration { origin.build(callback) }
+ duration { origin.build(resultCallback = { callback.onChatBuilt(it.getOrThrow()) }) }
} catch (expected: Throwable) {
- if (developmentMode) severe("Failed to initialize", expected)
+ if (developmentMode) error("Failed to initialize", expected)
+ throw expected
+ }
+ }
+
+ override fun build(resultCallback: OnChatBuiltResultCallback): Cancellable = scope("build") {
+ return try {
+ duration { origin.build(resultCallback) }
+ } catch (expected: Throwable) {
+ if (developmentMode) error("Failed to initialize", expected)
throw expected
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderRepeating.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderThreading.kt
similarity index 59%
rename from chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderRepeating.kt
rename to chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderThreading.kt
index cb2e44ec..f85d0d4d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderRepeating.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatBuilderThreading.kt
@@ -15,28 +15,22 @@
package com.nice.cxonechat.internal
+import android.annotation.SuppressLint
import com.nice.cxonechat.Authorization
import com.nice.cxonechat.Cancellable
import com.nice.cxonechat.Chat
import com.nice.cxonechat.ChatBuilder
import com.nice.cxonechat.ChatBuilder.OnChatBuiltCallback
+import com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback
import com.nice.cxonechat.ChatStateListener
-import java.io.IOException
import java.util.concurrent.CountDownLatch
-import kotlin.math.pow
-import kotlin.time.Duration
-import kotlin.time.Duration.Companion.seconds
-import kotlin.time.DurationUnit.SECONDS
-internal class ChatBuilderRepeating(
+internal class ChatBuilderThreading(
private val origin: ChatBuilder,
private val entrails: ChatEntrails,
- private val backoff: Duration = 2.seconds,
) : ChatBuilder {
- init {
- check(backoff.inWholeSeconds >= 1) { "Backoff can't be lower than 1 second" }
- }
+ private var listener: ChatStateListener? = null
override fun setAuthorization(authorization: Authorization) = apply {
origin.setAuthorization(authorization)
@@ -51,6 +45,7 @@ internal class ChatBuilderRepeating(
}
override fun setChatStateListener(listener: ChatStateListener): ChatBuilder = apply {
+ this.listener = listener
origin.setChatStateListener(listener)
}
@@ -58,46 +53,40 @@ internal class ChatBuilderRepeating(
origin.setDeviceToken(token)
}
- override fun build(callback: OnChatBuiltCallback): Cancellable {
+ @Deprecated(
+ "Please migrate to build method with OnChatBuildResultCallback",
+ replaceWith = ReplaceWith(
+ "build(resultCallback = OnChatBuiltResultCallback { callback.onChatBuilt(it.getOrThrow()) })",
+ "com.nice.cxonechat.ChatBuilder.OnChatBuiltResultCallback"
+ )
+ )
+ override fun build(callback: OnChatBuiltCallback): Cancellable =
+ build(resultCallback = { chatResult -> callback.onChatBuilt(chatResult.getOrThrow()) })
+
+ override fun build(
+ resultCallback: OnChatBuiltResultCallback,
+ ): Cancellable {
val threading = entrails.threading
return threading.background {
- val chat = awaitBuild()
+ val chat = buildSynchronous()
threading.foreground {
- callback.onChatBuilt(chat)
+ resultCallback.onChatBuiltResult(chat)
}
}
}
// ---
- private fun awaitBuild(): Chat {
- var exponent = 0
- @Suppress("UnconditionalJumpStatementInLoop") // We need to retry, since we don't have return value
- while (true) {
- return try {
- buildSynchronous()
- } catch (ignore: IllegalStateException) {
- val currentBackoff = backoff.toDouble(SECONDS).pow(exponent++).seconds
- Thread.sleep(currentBackoff.inWholeMilliseconds)
- continue
- }
- }
- }
-
- @Throws(IllegalStateException::class)
- private fun buildSynchronous(): Chat {
+ @SuppressLint(
+ "CheckResult" // Result is not used intentionally as cancellation is done via interrupt.
+ )
+ private fun buildSynchronous(): Result {
val latch = CountDownLatch(1)
- var chat: Chat? = null
- try {
- origin.build {
- chat = it
- latch.countDown()
- }
- } catch (expected: RuntimeException) {
- throw IllegalStateException(expected)
- } catch (e: IOException) {
- throw IllegalStateException(e)
- }
+ var chat: Result? = null
+ origin.build(resultCallback = {
+ chat = it
+ latch.countDown()
+ })
latch.await()
return checkNotNull(chat)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrails.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrails.kt
index 9e790c12..4079eabe 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrails.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrails.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.api.RemoteService
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrailsAndroid.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrailsAndroid.kt
index 71c86a03..e9c62e8c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrailsAndroid.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEntrailsAndroid.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import android.content.Context
@@ -7,7 +22,6 @@ import com.nice.cxonechat.SocketFactoryConfiguration
import com.nice.cxonechat.api.RemoteService
import com.nice.cxonechat.internal.socket.SocketFactory
import com.nice.cxonechat.log.Logger
-import com.nice.cxonechat.log.LoggerAndroid
import com.nice.cxonechat.state.Environment
import com.nice.cxonechat.storage.PreferencesValueStorage
import com.nice.cxonechat.storage.ValueStorage
@@ -20,16 +34,18 @@ internal class ChatEntrailsAndroid(
factory: SocketFactory,
config: SocketFactoryConfiguration,
sharedClient: OkHttpClient,
+ override val logger: Logger,
) : ChatEntrails {
- override val storage: ValueStorage = PreferencesValueStorage(context)
- override val service: RemoteService = RemoteServiceBuilder()
+ override val storage: ValueStorage by lazy { PreferencesValueStorage(context) }
+ override val service: RemoteService by lazy {
+ RemoteServiceBuilder()
.setSharedOkHttpClient(sharedClient)
.setConnection(factory.getConfiguration(storage))
.build()
+ }
override val threading: Threading = Threading(AndroidExecutor())
override val environment: Environment = config.environment
- override val logger: Logger = LoggerAndroid()
private class AndroidExecutor : AbstractExecutorService() {
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerImpl.kt
index d7b040e8..ad442297 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerImpl.kt
@@ -15,36 +15,54 @@
package com.nice.cxonechat.internal
+import com.google.gson.JsonParseException
import com.nice.cxonechat.ChatEventHandler
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
import com.nice.cxonechat.event.AnalyticsEvent
import com.nice.cxonechat.event.ChatEvent
import com.nice.cxonechat.event.LocalEvent
+import com.nice.cxonechat.exceptions.AnalyticsEventDispatchException
+import com.nice.cxonechat.exceptions.CXOneException
+import com.nice.cxonechat.exceptions.InternalError
import com.nice.cxonechat.internal.socket.send
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
+import java.text.ParseException
internal class ChatEventHandlerImpl(
private val chat: ChatWithParameters,
) : ChatEventHandler {
- override fun trigger(event: ChatEvent, listener: OnEventSentListener?) {
+ override fun trigger(event: ChatEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
// Is this an internal event that doesn't get broadcast any further?
if (event is LocalEvent) return
- when (val model = event.getModel(chat.connection, chat.storage)) {
+ val model = runCatching {
+ event.getModel(chat.connection, chat.storage)
+ }.onFailure { throwable ->
+ when (throwable) {
+ is CXOneException -> errorListener?.onError(throwable)
+ is ParseException, is JsonParseException -> errorListener?.onError(InternalError("Serialization error"))
+ }
+ }.getOrNull() ?: return
+ when (model) {
is LocalEvent -> Unit
- is AnalyticsEvent -> postAnalyticsEvent(model, listener)
+ is AnalyticsEvent -> postAnalyticsEvent(model, listener, errorListener)
else -> postWSSEvent(model, listener)
}
}
private fun postWSSEvent(model: Any, listener: OnEventSentListener?) {
- chat.socket.send(model, listener?.run { ::onSent })
+ chat.socket?.send(model, listener?.run { ::onSent })
}
- private fun postAnalyticsEvent(event: AnalyticsEvent, listener: OnEventSentListener?) {
+ private fun postAnalyticsEvent(
+ event: AnalyticsEvent,
+ listener: OnEventSentListener?,
+ errorListener: OnEventErrorListener?,
+ ) {
chat.service.postEvent(
chat.connection.brandId.toString(),
chat.storage.visitorId.toString(),
@@ -56,6 +74,7 @@ internal class ChatEventHandlerImpl(
override fun onFailure(call: Call, t: Throwable) {
listener?.onSent()
+ errorListener?.onError(AnalyticsEventDispatchException(t.message ?: "Failed to dispatch event.", t))
}
})
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerLogging.kt
index 9ed40393..0419d99c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerLogging.kt
@@ -1,27 +1,57 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatEventHandler
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
import com.nice.cxonechat.event.ChatEvent
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
+import com.nice.cxonechat.log.warning
internal class ChatEventHandlerLogging(
private val origin: ChatEventHandler,
private val logger: Logger,
-) : ChatEventHandler, LoggerScope by LoggerScope(logger) {
+) : ChatEventHandler, LoggerScope by LoggerScope(logger) {
- override fun trigger(event: ChatEvent, listener: OnEventSentListener?) = scope("trigger") {
- finest("Dispatching (event=$event)")
- origin.trigger(event) {
- scope("onSent") {
- duration {
- listener?.onSent()
+ override fun trigger(
+ event: ChatEvent,
+ listener: OnEventSentListener?,
+ errorListener: OnEventErrorListener?,
+ ) = scope("trigger") {
+ verbose("Dispatching (event=$event)")
+ duration {
+ origin.trigger(
+ event = event,
+ listener = {
+ scope("onSent") {
+ listener?.onSent()
+ }
+ },
+ errorListener = { exception ->
+ scope("onError") {
+ warning("Failed to dispatch (event=$event)", exception)
+ errorListener?.onError(exception)
+ }
}
- }
+ )
}
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerThreading.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerThreading.kt
new file mode 100644
index 00000000..b1413e7b
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerThreading.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.ChatEventHandler
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
+import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
+import com.nice.cxonechat.event.ChatEvent
+import com.nice.cxonechat.exceptions.CXOneException
+
+internal class ChatEventHandlerThreading(
+ private val origin: ChatEventHandler,
+ private val chat: ChatWithParameters,
+) : ChatEventHandler {
+ override fun trigger(event: ChatEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
+ chat.entrails.threading.background {
+ try {
+ origin.trigger(event, listener, errorListener)
+ } catch (exception: CXOneException) {
+ errorListener?.onError(exception)
+ }
+ }
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTimeOnPage.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTimeOnPage.kt
index d7007c6b..0a415a93 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTimeOnPage.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTimeOnPage.kt
@@ -16,6 +16,7 @@
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatEventHandler
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
import com.nice.cxonechat.event.ChatEvent
import com.nice.cxonechat.event.PageViewEndedEvent
@@ -27,15 +28,15 @@ internal class ChatEventHandlerTimeOnPage(
private val origin: ChatEventHandler,
private val chat: ChatWithParameters,
) : ChatWithParameters by chat, ChatEventHandler {
- override fun trigger(event: ChatEvent, listener: OnEventSentListener?) {
+ override fun trigger(event: ChatEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
when (event) {
- is PageViewEvent -> onPageViewed(event, listener)
- is PageViewEndedEvent -> onPageEnded(event, listener)
- else -> origin.trigger(event, listener)
+ is PageViewEvent -> onPageViewed(event, listener, errorListener)
+ is PageViewEndedEvent -> onPageEnded(event, listener, errorListener)
+ else -> origin.trigger(event, listener, errorListener)
}
}
- private fun onPageViewed(event: PageViewEvent, listener: OnEventSentListener?) {
+ private fun onPageViewed(event: PageViewEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
// Ignore a duplicate event
if (event.uri == lastPageViewed?.uri && event.title == lastPageViewed?.title) {
listener?.onSent()
@@ -43,14 +44,14 @@ internal class ChatEventHandlerTimeOnPage(
}
lastPageViewed?.let { last ->
- onPageEnded(PageViewEndedEvent(last.title, last.uri, event.date), listener)
+ onPageEnded(PageViewEndedEvent(last.title, last.uri, event.date), listener, errorListener)
}
lastPageViewed = event
- origin.trigger(event, listener)
+ origin.trigger(event, listener, errorListener)
}
- private fun onPageEnded(event: PageViewEndedEvent, listener: OnEventSentListener?) {
+ private fun onPageEnded(event: PageViewEndedEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
val last = lastPageViewed
if (last != null &&
@@ -58,13 +59,14 @@ internal class ChatEventHandlerTimeOnPage(
last.title == event.title
) {
origin.trigger(
- TimeSpentOnPageEvent(
+ event = TimeSpentOnPageEvent(
uri = event.uri,
title = event.title,
timeSpentOnPage = max(1, (event.date.time - last.date.time) / 1000),
date = event.date
),
- listener
+ listener = listener,
+ errorListener = errorListener,
)
} else {
listener?.onSent()
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTokenGuard.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTokenGuard.kt
index 41a57bfa..de485fbc 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTokenGuard.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerTokenGuard.kt
@@ -1,6 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatEventHandler
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
import com.nice.cxonechat.event.ChatEvent
import com.nice.cxonechat.event.RefreshToken
@@ -13,11 +29,11 @@ internal class ChatEventHandlerTokenGuard(
private val chat: ChatWithParameters,
) : ChatEventHandler by origin {
- override fun trigger(event: ChatEvent, listener: OnEventSentListener?) {
+ override fun trigger(event: ChatEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
val expiresAt = chat.storage.authTokenExpDate ?: Date(Long.MAX_VALUE)
if (expiresAt.expiresWithin(10.seconds) && event !is RefreshToken) {
origin.trigger(RefreshToken)
}
- origin.trigger(event, listener)
+ origin.trigger(event, listener, errorListener)
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerVisitGuard.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerVisitGuard.kt
index a86b81e1..a792dcc0 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerVisitGuard.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatEventHandlerVisitGuard.kt
@@ -16,6 +16,7 @@
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatEventHandler
+import com.nice.cxonechat.ChatEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatEventHandler.OnEventSentListener
import com.nice.cxonechat.event.ChatEvent
import com.nice.cxonechat.event.PageViewEvent
@@ -28,11 +29,11 @@ internal class ChatEventHandlerVisitGuard(
private val origin: ChatEventHandler,
private val chat: ChatWithParameters,
) : ChatEventHandler by origin {
- override fun trigger(event: ChatEvent, listener: OnEventSentListener?) {
+ override fun trigger(event: ChatEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
if (event is PageViewEvent) {
validateVisit(event.date)
}
- origin.trigger(event, listener)
+ origin.trigger(event, listener, errorListener)
}
private fun validateVisit(date: Date) {
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerGlobal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerGlobal.kt
index c7add50f..c271803c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerGlobal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerGlobal.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatFieldHandler
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerLogging.kt
index 6b4dfadf..5e445c6e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerLogging.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatFieldHandler
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
internal class ChatFieldHandlerLogging(
private val origin: ChatFieldHandler,
@@ -13,7 +28,7 @@ internal class ChatFieldHandlerLogging(
) : ChatFieldHandler, LoggerScope by LoggerScope(logger) {
override fun add(fields: Map): Unit = scope("add") {
- finest("fields=$fields")
+ verbose("fields=$fields")
duration {
origin.add(fields)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerThread.kt
index 185576a5..c19894c4 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerThread.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatFieldHandlerThread.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Chat
@@ -18,10 +33,14 @@ internal class ChatFieldHandlerThread(
override fun add(fields: Map) {
chat.configuration.allCustomFields.validate(fields)
val customFields = fields.map(::CustomFieldModel)
- handler.events().trigger(SetContactCustomFieldEvent(customFields)) {
- val mappedFields = customFields
- .map(CustomFieldModel::toCustomField)
- thread += thread.asCopyable().copy(fields = mappedFields)
- }
+ handler.events().trigger(
+ event = SetContactCustomFieldEvent(customFields),
+ listener = {
+ val mappedFields = customFields
+ .map(CustomFieldModel::toCustomField)
+ thread += thread.asCopyable().copy(fields = mappedFields)
+ },
+ errorListener = null,
+ )
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatImpl.kt
index 47f06019..34f135f6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatImpl.kt
@@ -19,17 +19,21 @@ import com.nice.cxonechat.Cancellable
import com.nice.cxonechat.ChatActionHandler
import com.nice.cxonechat.ChatEventHandler
import com.nice.cxonechat.ChatFieldHandler
+import com.nice.cxonechat.ChatStateListener
import com.nice.cxonechat.ChatThreadsHandler
import com.nice.cxonechat.event.PageViewEvent
+import com.nice.cxonechat.internal.copy.ConnectionCopyable.Companion.asCopyable
import com.nice.cxonechat.internal.model.ConfigurationInternal
import com.nice.cxonechat.internal.model.Visitor
import com.nice.cxonechat.internal.socket.ProxyWebSocketListener
import com.nice.cxonechat.internal.socket.SocketFactory
import com.nice.cxonechat.internal.socket.WebSocketSpec
+import com.nice.cxonechat.internal.socket.WebsocketLogging
import com.nice.cxonechat.state.Connection
import com.nice.cxonechat.thread.CustomField
import okhttp3.WebSocket
import retrofit2.Callback
+import java.util.concurrent.atomic.AtomicReference
internal class ChatImpl(
override var connection: Connection,
@@ -37,18 +41,19 @@ internal class ChatImpl(
private val socketFactory: SocketFactory,
override val configuration: ConfigurationInternal,
private val callback: Callback,
+ override val chatStateListener: ChatStateListener?,
) : ChatWithParameters {
override val socketListener: ProxyWebSocketListener = socketFactory.createProxyListener()
- override val socket: WebSocket
- get() = socketSession
+ override val socket: WebSocket?
+ get() = socketSession.get()
override var fields = listOf()
override val environment get() = entrails.environment
private val actions = ChatActionHandlerImpl(this)
- private var socketSession: WebSocket = socketFactory.create(socketListener)
+ private val socketSession: AtomicReference = AtomicReference(null)
override var lastPageViewed: PageViewEvent? = null
@@ -69,8 +74,9 @@ internal class ChatImpl(
handler = ChatThreadsHandlerImpl(this, configuration.preContactSurvey)
handler = ChatThreadsHandlerReplayLastEmpty(handler)
handler = ChatThreadsHandlerConfigProxy(handler, this)
- handler = ChatThreadsHandlerWelcome(handler, this)
handler = ChatThreadsHandlerMessages(handler)
+ handler = ChatThreadsHandlerMetadata(handler, this)
+ handler = ChatThreadsHandlerMemoizeHandlers(handler)
return handler
}
@@ -80,6 +86,7 @@ internal class ChatImpl(
handler = ChatEventHandlerTokenGuard(handler, this)
handler = ChatEventHandlerVisitGuard(handler, this)
handler = ChatEventHandlerTimeOnPage(handler, this)
+ handler = ChatEventHandlerThreading(handler, this)
return handler
}
@@ -93,11 +100,25 @@ internal class ChatImpl(
}
override fun close() {
- socketSession.close(WebSocketSpec.CLOSE_NORMAL_CODE, null)
+ socketSession.getAndSet(null)?.close(WebSocketSpec.CLOSE_NORMAL_CODE, null)
}
- override fun reconnect(): Cancellable {
- socketSession = socketFactory.create(socketListener)
+ @Deprecated("Deprecated in Chat", replaceWith = ReplaceWith("connect()"))
+ override fun reconnect() = connect()
+
+ override fun connect(): Cancellable {
+ socketSession.set(
+ WebsocketLogging(
+ socket = socketFactory.create(socketListener),
+ logger = entrails.logger,
+ )
+ )
return Cancellable.noop
}
+
+ override fun setUserName(firstName: String, lastName: String) {
+ if (!configuration.isAuthorizationEnabled) {
+ connection = connection.asCopyable().copy(firstName = firstName, lastName = lastName)
+ }
+ }
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatLogging.kt
index d3216db3..d7559aa6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatLogging.kt
@@ -17,25 +17,23 @@ package com.nice.cxonechat.internal
import com.nice.cxonechat.Chat
import com.nice.cxonechat.internal.socket.EventLogger
-import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
internal class ChatLogging(
private val origin: ChatWithParameters,
- logger: Logger,
-) : ChatWithParameters by origin, LoggerScope by LoggerScope(logger) {
+) : ChatWithParameters by origin, LoggerScope by LoggerScope(origin.entrails.logger) {
init {
- finest("Initialized (config=$configuration,environment=$environment)")
- origin.socketListener.addListener(EventLogger(origin.entrails.logger))
+ verbose("Initialized (config=$configuration,environment=$environment)")
+ origin.socketListener.addListener(EventLogger(identity))
}
override fun setDeviceToken(token: String?) = scope("setDeviceToken") {
duration {
- finest("token=${token ?: "null"}")
+ verbose("token=${token ?: "null"}")
origin.setDeviceToken(token)
}
}
@@ -78,6 +76,12 @@ internal class ChatLogging(
}
}
+ override fun connect() = scope("connect") {
+ duration {
+ origin.connect()
+ }
+ }
+
override fun close() = scope("close") {
duration {
origin.close()
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatMemoizeThreadsHandler.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatMemoizeThreadsHandler.kt
new file mode 100644
index 00000000..775bfa1c
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatMemoizeThreadsHandler.kt
@@ -0,0 +1,17 @@
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.ChatThreadsHandler
+
+/**
+ * Implementation of the [ChatWithParameters] which assures that only one instance of [ChatThreadsHandler] is ever
+ * created.
+ *
+ * It memorizes the first instance which is created and prevents further calls to the supplied
+ * [ChatWithParameters.threads] method.
+ */
+internal class ChatMemoizeThreadsHandler(private val origin: ChatWithParameters) : ChatWithParameters by origin {
+
+ private val chatThreadsHandlerMemoized by lazy(origin::threads)
+
+ override fun threads(): ChatThreadsHandler = chatThreadsHandlerMemoized
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatMultiThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatMultiThread.kt
new file mode 100644
index 00000000..6cc3a3d1
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatMultiThread.kt
@@ -0,0 +1,16 @@
+package com.nice.cxonechat.internal
+
+/**
+ * Handle Multi thread chat specific functionality.
+ *
+ * A chat in multithread mode is ready once connected. The process of fetching the thread
+ * list and metadata will be initiated once the client indicates an interest in threads by
+ * calling [com.nice.cxonechat.Chat.threads]
+ *
+ * @param origin Existing implementation of [ChatWithParameters] used for delegation.
+ */
+internal class ChatMultiThread(private val origin: ChatWithParameters) : ChatWithParameters by origin {
+ override fun connect() = origin.connect().also {
+ origin.chatStateListener?.onReady()
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatServerErrorReporting.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatServerErrorReporting.kt
new file mode 100644
index 00000000..0e8df1a8
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatServerErrorReporting.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.enums.ErrorType
+import com.nice.cxonechat.enums.ErrorType.ArchivingThreadFailed
+import com.nice.cxonechat.enums.ErrorType.RecoveringLivechatFailed
+import com.nice.cxonechat.enums.ErrorType.RecoveringThreadFailed
+import com.nice.cxonechat.enums.ErrorType.SendingMessageFailed
+import com.nice.cxonechat.enums.ErrorType.SendingOfflineMessageFailed
+import com.nice.cxonechat.enums.ErrorType.SendingOutboundFailed
+import com.nice.cxonechat.enums.ErrorType.SendingTranscriptFailed
+import com.nice.cxonechat.enums.ErrorType.UpdatingThreadFailed
+import com.nice.cxonechat.exceptions.RuntimeChatException.ServerCommunicationError
+import com.nice.cxonechat.internal.socket.ErrorCallback.Companion.addErrorCallback
+import com.nice.cxonechat.internal.socket.ProxyWebSocketListener
+
+/**
+ * Class registers callbacks for error events which can't be directly associated with any action, either because of the
+ * nature of the error or because of the missing metadata in the error and asynchronous nature of the actions.
+ *
+ * The need for the callbacks can be in the future eliminated either by adding metadata to the error or by preventing
+ * parallel execution of (some) actions.
+ *
+ * @param origin Wrapped original [ChatWithParameters].
+ */
+internal class ChatServerErrorReporting(private val origin: ChatWithParameters) : ChatWithParameters by origin {
+
+ private val callbacks = Cancellable(
+ socketListener.addErrorCallback(SendingMessageFailed),
+ socketListener.addErrorCallback(RecoveringLivechatFailed),
+ socketListener.addErrorCallback(RecoveringThreadFailed),
+ socketListener.addErrorCallback(SendingOutboundFailed),
+ socketListener.addErrorCallback(UpdatingThreadFailed),
+ socketListener.addErrorCallback(ArchivingThreadFailed),
+ socketListener.addErrorCallback(SendingTranscriptFailed),
+ socketListener.addErrorCallback(SendingOfflineMessageFailed),
+ )
+
+ override fun close() {
+ callbacks.cancel()
+ origin.close()
+ }
+
+ private fun ProxyWebSocketListener.addErrorCallback(type: ErrorType): Cancellable = addErrorCallback(type) {
+ chatStateListener?.onChatRuntimeException(ServerCommunicationError(type.value))
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatSingleThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatSingleThread.kt
new file mode 100644
index 00000000..e5ac8a00
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatSingleThread.kt
@@ -0,0 +1,73 @@
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.ChatThreadHandler
+import com.nice.cxonechat.thread.ChatThreadState.Loaded
+import com.nice.cxonechat.thread.ChatThreadState.Pending
+import com.nice.cxonechat.thread.ChatThreadState.Ready
+
+/**
+ * This implementation of [com.nice.cxonechat.Chat] adds behavior which triggers early thread recovery if there is an
+ * existing thread.
+ * Once the [origin] [com.nice.cxonechat.Chat.connect] is finished, the mandatory [com.nice.cxonechat.Chat.threads] call
+ * is performed and the first existing thread is then `refreshed` once it's metadata are loaded.
+ * In order for these tasks to be of any use to the [com.nice.cxonechat.Chat] user, the [com.nice.cxonechat.Chat] has to
+ * memoize both the [com.nice.cxonechat.ChatThreadsHandler] and the [com.nice.cxonechat.ChatThreadHandler].
+ *
+ * @param origin Existing implementation of [ChatWithParameters] used for delegation.
+ */
+internal class ChatSingleThread(private val origin: ChatWithParameters) : ChatWithParameters by origin {
+
+ private var recoverCalled: Boolean = false
+
+ override fun connect(): Cancellable {
+ origin.connect()
+ recoverCalled = false
+ return tryToRecoverThread()
+ }
+
+ /**
+ * Attempts to recover the single thread if it exists and notifies [com.nice.cxonechat.ChatStateListener] once
+ * the task is done.
+ */
+ private fun tryToRecoverThread() = origin.entrails.threading.background {
+ var threadsCancellable: Cancellable? = null
+ val threadsHandler = origin.threads()
+ threadsCancellable = threadsHandler.threads { threadList ->
+ val threadHandler = threadList.firstOrNull()?.let(threadsHandler::thread)
+ val threadState = threadHandler?.get()?.threadState
+ if (threadHandler != null && threadState !== Ready && threadState !== Pending) {
+ recoverThread(threadHandler)
+ } else {
+ // Either there is no thread or the thread is already recovered or it was user created.
+ origin.chatStateListener?.onReady()
+ }
+ // Cleanup after the first thread list update.
+ threadsCancellable?.cancel()
+ }
+ // Assuming that `threadsHandler.refresh` is called as part of the `threads` method.
+ }
+
+ private fun recoverThread(threadHandler: ChatThreadHandler) {
+ var threadHandlerCancellable: Cancellable? = null
+ threadHandlerCancellable = threadHandler.get { thread ->
+ if (thread.threadState === Ready) {
+ // The thread was recovered, signal listener and cleanup.
+ origin.chatStateListener?.onReady()
+ threadHandlerCancellable?.cancel()
+ } else {
+ // The metadata were just loaded, recover the thread.
+ requestRecoverThread(threadHandler)
+ }
+ }
+ // Recover the thread if the metadata are already Loaded.
+ requestRecoverThread(threadHandler)
+ }
+
+ private fun requestRecoverThread(threadHandler: ChatThreadHandler) {
+ if (!recoverCalled && threadHandler.get().threadState === Loaded) {
+ recoverCalled = true
+ threadHandler.refresh()
+ }
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatStoreVisitor.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatStoreVisitor.kt
index 6fe7eb9e..a18cd182 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatStoreVisitor.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatStoreVisitor.kt
@@ -30,10 +30,15 @@ internal class ChatStoreVisitor(
callback: Callback,
) : ChatWithParameters by origin {
init {
- entrails.service.createOrUpdateVisitor(
+ val createOrUpdateVisitor = entrails.service.createOrUpdateVisitor(
brandId = connection.brandId,
visitorId = entrails.storage.visitorId.toString(),
visitor = Visitor(connection, origin.storage.deviceToken)
- ).enqueue(callback)
+ )
+ runCatching {
+ callback.onResponse(createOrUpdateVisitor, createOrUpdateVisitor.execute())
+ }.onFailure {
+ callback.onFailure(createOrUpdateVisitor, it)
+ }
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerArchival.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerArchival.kt
index 7f6779e2..bc7151f6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerArchival.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerArchival.kt
@@ -16,6 +16,7 @@
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadEventHandler
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener
import com.nice.cxonechat.event.thread.ArchiveThreadEvent
import com.nice.cxonechat.event.thread.ChatThreadEvent
@@ -29,22 +30,28 @@ internal class ChatThreadEventHandlerArchival(
private val chat: ChatWithParameters,
private val thread: ChatThreadMutable
): ChatThreadEventHandler by origin {
- override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?) {
- origin.trigger(event) {
- if(event is ArchiveThreadEvent) {
- handleArchiveThread()
- }
- listener?.onSent()
- }
+ override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
+ origin.trigger(
+ event = event,
+ listener = {
+ if (event is ArchiveThreadEvent) {
+ handleArchiveThread()
+ }
+ listener?.onSent()
+ },
+ errorListener = errorListener
+ )
}
private fun handleArchiveThread() {
+ val socket = chat.socket ?: return
+
// mark this thread as archived
thread += thread.asCopyable().copy(canAddMoreMessages = false)
// send thread updated to host application
chat.socketListener.onMessage(
- chat.socket,
+ socket,
serializer.toJson(EventThreadUpdated(thread))
)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerImpl.kt
index 659608ca..215994bf 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerImpl.kt
@@ -1,6 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadEventHandler
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener
import com.nice.cxonechat.event.thread.ChatThreadEvent
import com.nice.cxonechat.internal.socket.send
@@ -11,11 +27,13 @@ internal class ChatThreadEventHandlerImpl(
private val thread: ChatThread,
) : ChatThreadEventHandler {
- override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?) {
+ override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
+ val socket = chat.socket ?: return
+
val model = event.getModel(thread, chat.connection)
when (listener) {
- null -> chat.socket.send(model)
- else -> chat.socket.send(model) { listener.onSent() }
+ null -> socket.send(model)
+ else -> socket.send(model, listener::onSent)
}
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerLogging.kt
index cbad8103..2eac281c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerLogging.kt
@@ -1,13 +1,30 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadEventHandler
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener
import com.nice.cxonechat.event.thread.ChatThreadEvent
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
+import com.nice.cxonechat.log.warning
internal class ChatThreadEventHandlerLogging(
private val origin: ChatThreadEventHandler,
@@ -15,18 +32,27 @@ internal class ChatThreadEventHandlerLogging(
) : ChatThreadEventHandler, LoggerScope by LoggerScope(logger) {
init {
- finest("Initialized")
+ verbose("Initialized")
}
override fun trigger(
event: ChatThreadEvent,
listener: OnEventSentListener?,
+ errorListener: OnEventErrorListener?,
) = scope("trigger") {
- finest("Dispatching (event=$event)")
- origin.trigger(event) {
- scope("onSent") {
- duration {
- listener?.onSent()
+ verbose("Dispatching (event=$event)")
+ duration {
+ origin.trigger(
+ event = event,
+ listener = {
+ scope("onSent") {
+ listener?.onSent()
+ }
+ }
+ ) { exception ->
+ scope("onError") {
+ warning("Failed to dispatch (event=$event)", exception)
+ errorListener?.onError(exception)
}
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerThreading.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerThreading.kt
new file mode 100644
index 00000000..711fff73
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerThreading.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.ChatThreadEventHandler
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener
+import com.nice.cxonechat.event.thread.ChatThreadEvent
+import com.nice.cxonechat.exceptions.CXOneException
+
+internal class ChatThreadEventHandlerThreading(
+ private val origin: ChatThreadEventHandler,
+ private val chat: ChatWithParameters,
+) : ChatThreadEventHandler {
+ override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
+ chat.entrails.threading.background {
+ try {
+ origin.trigger(event, listener, errorListener)
+ } catch (exception: CXOneException) {
+ errorListener?.onError(exception)
+ }
+ }
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerTokenGuard.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerTokenGuard.kt
index 3b47f86a..ce9bbd15 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerTokenGuard.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadEventHandlerTokenGuard.kt
@@ -1,6 +1,22 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadEventHandler
+import com.nice.cxonechat.ChatThreadEventHandler.OnEventErrorListener
import com.nice.cxonechat.ChatThreadEventHandler.OnEventSentListener
import com.nice.cxonechat.event.RefreshToken
import com.nice.cxonechat.event.thread.ChatThreadEvent
@@ -13,11 +29,11 @@ internal class ChatThreadEventHandlerTokenGuard(
private val chat: ChatWithParameters,
) : ChatThreadEventHandler by origin {
- override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?) {
+ override fun trigger(event: ChatThreadEvent, listener: OnEventSentListener?, errorListener: OnEventErrorListener?) {
val expiresAt = chat.storage.authTokenExpDate ?: Date(Long.MAX_VALUE)
if (expiresAt.expiresWithin(10.seconds)) {
chat.events().trigger(RefreshToken)
}
- origin.trigger(event, listener)
+ origin.trigger(event, listener, errorListener)
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentTyping.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentTyping.kt
index 3dc194eb..1a1cb0a9 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentTyping.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentTyping.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
@@ -21,7 +36,7 @@ internal class ChatThreadHandlerAgentTyping(
override fun get(listener: OnThreadUpdatedListener): Cancellable {
var isTyping = false
val cancellableStarted = chat.socketListener.addCallback(SenderTypingStarted) { event ->
- if (event.inThread(get())) {
+ if (event.inThread(get()) && event.agent != null) {
isTyping = true
listener.onUpdated(
updateThread(
@@ -32,7 +47,7 @@ internal class ChatThreadHandlerAgentTyping(
}
}
val cancellableEnded = chat.socketListener.addCallback(SenderTypingEnded) { event ->
- if (event.inThread(get())) {
+ if (event.inThread(get()) && event.agent != null) {
isTyping = false
listener.onUpdated(
updateThread(
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentUpdate.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentUpdate.kt
index 115ccc2e..b2ef8067 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentUpdate.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerAgentUpdate.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerImpl.kt
index 0e579828..73df9d0a 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerImpl.kt
@@ -21,7 +21,7 @@ import com.nice.cxonechat.ChatThreadEventHandler
import com.nice.cxonechat.ChatThreadHandler
import com.nice.cxonechat.ChatThreadHandler.OnThreadUpdatedListener
import com.nice.cxonechat.ChatThreadMessageHandler
-import com.nice.cxonechat.enums.EventType.ThreadArchived
+import com.nice.cxonechat.enums.EventType.CaseStatusChanged
import com.nice.cxonechat.enums.EventType.ThreadRecovered
import com.nice.cxonechat.enums.EventType.ThreadUpdated
import com.nice.cxonechat.event.thread.RecoverThreadEvent
@@ -30,11 +30,14 @@ import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.asCopyable
import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.updateWith
import com.nice.cxonechat.internal.model.ChatThreadMutable
import com.nice.cxonechat.internal.model.CustomFieldInternal.Companion.updateWith
+import com.nice.cxonechat.internal.model.network.EventCaseStatusChanged
import com.nice.cxonechat.internal.model.network.EventThreadRecovered
import com.nice.cxonechat.internal.model.network.EventThreadUpdated
import com.nice.cxonechat.internal.socket.EventCallback.Companion.addCallback
import com.nice.cxonechat.message.Message
import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.ChatThreadState.Pending
+import com.nice.cxonechat.thread.ChatThreadState.Ready
internal class ChatThreadHandlerImpl(
private val chat: ChatWithParameters,
@@ -45,7 +48,7 @@ internal class ChatThreadHandlerImpl(
override fun get(listener: OnThreadUpdatedListener): Cancellable {
val onRecovered = chat.socketListener.addCallback(ThreadRecovered) { event ->
- if(event.inThread(thread)) {
+ if (event.inThread(thread)) {
updateFromEvent(event)
listener.onUpdated(thread)
}
@@ -53,14 +56,16 @@ internal class ChatThreadHandlerImpl(
val onUpdated = chat.socketListener.addCallback(ThreadUpdated) {
listener.onUpdated(thread)
}
- val onArchived = chat.socketListener.addCallback(ThreadArchived) {
- refresh()
+ val onArchived = chat.socketListener.addCallback(CaseStatusChanged) { event ->
+ CaseStatusChangedHandlerActions.handleCaseClosed(thread, event, listener::onUpdated)
}
return Cancellable(onRecovered, onUpdated, onArchived)
}
override fun refresh() {
- events().trigger(RecoverThreadEvent)
+ if (thread.threadState != Pending) {
+ events().trigger(RecoverThreadEvent)
+ }
}
private fun updateFromEvent(event: EventThreadRecovered) {
@@ -77,7 +82,8 @@ internal class ChatThreadHandlerImpl(
fields = thread.fields.updateWith(
// drop any fields not in the configuration
event.thread.fields.filter { chat.configuration.allowsFieldId(it.id) }
- )
+ ),
+ threadState = Ready,
)
chat.fields = chat.fields.updateWith(
// drop any fields not in the configuration
@@ -86,9 +92,12 @@ internal class ChatThreadHandlerImpl(
}
override fun setName(name: String) {
- events().trigger(UpdateThreadEvent(name)) {
- thread += thread.asCopyable().copy(threadName = name)
- }
+ events().trigger(
+ event = UpdateThreadEvent(name),
+ listener = {
+ thread += thread.asCopyable().copy(threadName = name)
+ },
+ )
}
override fun messages(): ChatThreadMessageHandler {
@@ -104,6 +113,7 @@ internal class ChatThreadHandlerImpl(
handler = ChatThreadEventHandlerImpl(chat, thread)
handler = ChatThreadEventHandlerTokenGuard(handler, chat)
handler = ChatThreadEventHandlerArchival(handler, chat, thread)
+ handler = ChatThreadEventHandlerThreading(handler, chat)
return handler
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerLogging.kt
index 7258bd97..69457e63 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerLogging.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadHandler
@@ -5,8 +20,8 @@ import com.nice.cxonechat.ChatThreadHandler.OnThreadUpdatedListener
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
internal class ChatThreadHandlerLogging(
private val origin: ChatThreadHandler,
@@ -20,7 +35,7 @@ internal class ChatThreadHandlerLogging(
}
override fun get(listener: OnThreadUpdatedListener) = scope("get") {
- finest("Registered")
+ verbose("Registered")
origin.get {
duration {
listener.onUpdated(it)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMessageReadByAgent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMessageReadByAgent.kt
new file mode 100644
index 00000000..c6651078
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMessageReadByAgent.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.ChatThreadHandler
+import com.nice.cxonechat.ChatThreadHandler.OnThreadUpdatedListener
+import com.nice.cxonechat.enums.EventType.MessageReadChanged
+import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.asCopyable
+import com.nice.cxonechat.internal.model.ChatThreadMutable
+import com.nice.cxonechat.internal.model.network.EventMessageReadByAgent
+import com.nice.cxonechat.internal.socket.EventCallback.Companion.addCallback
+
+/**
+ * This class wraps origin [ChatThreadHandler] and adds effect to it's [get] function, which
+ * will update the mutable [thread] and also trigger [OnThreadUpdatedListener.onUpdated] callback
+ * with updated thread, when [EventMessageReadByAgent] is received.
+ *
+ * [EventMessageReadByAgent] will always cause an update of a message.
+ */
+internal class ChatThreadHandlerMessageReadByAgent(
+ private val origin: ChatThreadHandler,
+ private val chat: ChatWithParameters,
+ private val thread: ChatThreadMutable,
+) : ChatThreadHandler by origin {
+
+ override fun get(listener: OnThreadUpdatedListener): Cancellable {
+ val messageReadByAgent = chat.socketListener.addCallback(MessageReadChanged) { event ->
+ val message = event.message
+ if (message == null || !event.inThread(thread)) return@addCallback
+ thread += thread.asCopyable().copy(
+ messages = thread.messages
+ .toMutableList()
+ .apply {
+ this[indexOfFirst { it.id == event.messageId }] = message
+ }
+ )
+ listener.onUpdated(thread)
+ }
+ return Cancellable(
+ messageReadByAgent,
+ origin.get(listener)
+ )
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMetadata.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMetadata.kt
index 07fc5c11..6a544d1c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMetadata.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerMetadata.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
@@ -8,6 +23,7 @@ import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.asCopyable
import com.nice.cxonechat.internal.model.ChatThreadMutable
import com.nice.cxonechat.internal.model.network.EventThreadMetadataLoaded
import com.nice.cxonechat.internal.socket.EventCallback.Companion.addCallback
+import com.nice.cxonechat.thread.ChatThreadState.Loaded
internal class ChatThreadHandlerMetadata(
private val origin: ChatThreadHandler,
@@ -20,7 +36,8 @@ internal class ChatThreadHandlerMetadata(
if (!event.inThread(thread)) return@addCallback
thread += thread.asCopyable().copy(
messages = thread.messages.ifEmpty { listOfNotNull(event.message) },
- threadAgent = event.agent ?: thread.threadAgent
+ threadAgent = event.agent ?: thread.threadAgent,
+ threadState = Loaded,
)
listener.onUpdated(thread)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerWelcome.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerWelcome.kt
new file mode 100644
index 00000000..db056fa2
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadHandlerWelcome.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.Cancellable.Companion.asCancellable
+import com.nice.cxonechat.ChatThreadHandler
+import com.nice.cxonechat.ChatThreadHandler.OnThreadUpdatedListener
+import com.nice.cxonechat.ChatThreadMessageHandler
+import com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener
+import com.nice.cxonechat.event.thread.SendOutboundEvent
+import com.nice.cxonechat.internal.copy.ChatThreadCopyable.Companion.asCopyable
+import com.nice.cxonechat.internal.model.ChatThreadMutable
+import com.nice.cxonechat.internal.model.MessageDirectionModel.ToClient
+import com.nice.cxonechat.internal.model.MessageModel
+import com.nice.cxonechat.internal.model.MessageText
+import com.nice.cxonechat.internal.model.network.MessagePolyContent.Text
+import com.nice.cxonechat.internal.model.network.MessagePolyContent.Text.Payload
+import com.nice.cxonechat.internal.model.network.UserStatistics
+import com.nice.cxonechat.message.OutboundMessage
+import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.CustomField
+import java.util.Date
+import java.util.UUID
+import java.util.concurrent.FutureTask
+import java.util.concurrent.atomic.AtomicBoolean
+
+internal class ChatThreadHandlerWelcome(
+ private val origin: ChatThreadHandler,
+ private val chat: ChatWithParameters,
+ private val mutableThread: ChatThreadMutable,
+) : ChatThreadHandler by origin {
+
+ private val sendOutboundEvent = AtomicBoolean(mutableThread.messages.isEmpty())
+
+ private val prepareWelcomeMessageTask: FutureTask =
+ FutureTask(::addMessageAndPrepareEvent)
+
+ init {
+ if (sendOutboundEvent.get()) {
+ chat.entrails.threading.background(prepareWelcomeMessageTask)
+ } else {
+ prepareWelcomeMessageTask.cancel(true)
+ }
+ }
+
+ override fun get(): ChatThread {
+ runCatching { prepareWelcomeMessageTask.get() } // Await completion
+ return origin.get()
+ }
+
+ override fun get(listener: OnThreadUpdatedListener): Cancellable {
+ val notifyListenerWithWelcomeMessage = chat.entrails.threading.background(
+ FutureTask {
+ listener.onUpdated(get())
+ }
+ )
+ return Cancellable(
+ notifyListenerWithWelcomeMessage,
+ prepareWelcomeMessageTask.asCancellable(),
+ origin.get(listener)
+ )
+ }
+
+ override fun messages(): ChatThreadMessageHandler {
+ var handler = origin.messages()
+ if (sendOutboundEvent.get()) {
+ handler = WelcomeThreadMessageHandler(handler)
+ }
+ return handler
+ }
+
+ private inner class WelcomeThreadMessageHandler(
+ private val originHandler: ChatThreadMessageHandler,
+ ) : ChatThreadMessageHandler by originHandler {
+ override fun send(message: OutboundMessage, listener: OnMessageTransferListener?) {
+ chat.entrails.threading.background {
+ if (sendOutboundEvent.getAndSet(false)) {
+ val welcomeMessageEvent = prepareWelcomeMessageTask.get()
+ welcomeMessageEvent?.let(events()::trigger)
+ }
+ originHandler.send(message = message, listener = listener)
+ }
+ }
+ }
+
+ private fun addMessageAndPrepareEvent(): SendOutboundEvent? {
+ val storedMessage = chat.storage.welcomeMessage
+ if (storedMessage.isBlank()) {
+ sendOutboundEvent.set(false)
+ return null
+ }
+ val message = templateToFinalMessage(storedMessage)
+ val messageId = UUID.randomUUID()
+ val welcomeMessage = MessageText(
+ MessageModel(
+ idOnExternalPlatform = messageId,
+ threadIdOnExternalPlatform = mutableThread.id,
+ attachments = emptyList(),
+ createdAt = Date(),
+ direction = ToClient,
+ messageContent = Text(Payload(message)),
+ userStatistics = UserStatistics(null, null),
+ )
+ )
+ mutableThread += mutableThread.asCopyable().copy(
+ messages = mutableThread.messages.toMutableList().apply { add(0, welcomeMessage) }
+ )
+ val token = chat.storage.authToken
+ return SendOutboundEvent(message, token, messageId)
+ }
+
+ private fun templateToFinalMessage(storedMessage: String): String {
+ val connection = chat.connection
+ val parameters = mapOf(
+ "firstName" to connection.firstName,
+ "lastName" to connection.lastName,
+ )
+ val customerFieldMap = chat.fields.toMap()
+ val contactFieldMap = origin.get().fields.toMap()
+ return VariableMessageParser.parse(
+ storedMessage,
+ parameters,
+ customerFieldMap,
+ contactFieldMap
+ )
+ }
+
+ private companion object {
+ @JvmStatic
+ private fun customFieldAsPair(customField: CustomField): Pair = customField.id to customField.value
+
+ @JvmStatic
+ private fun List.toMap() = associate(::customFieldAsPair)
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerImpl.kt
index c4862949..8e58db35 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerImpl.kt
@@ -20,10 +20,15 @@ import com.nice.cxonechat.ChatThreadMessageHandler
import com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener
import com.nice.cxonechat.event.thread.LoadMoreMessagesEvent
import com.nice.cxonechat.event.thread.MessageEvent
+import com.nice.cxonechat.exceptions.InvalidParameterException
+import com.nice.cxonechat.exceptions.InvalidStateException
+import com.nice.cxonechat.exceptions.RuntimeChatException.AttachmentUploadError
import com.nice.cxonechat.internal.model.AttachmentModel
import com.nice.cxonechat.internal.model.AttachmentUploadModel
import com.nice.cxonechat.internal.model.CustomFieldModel
+import com.nice.cxonechat.message.ContentDescriptor
import com.nice.cxonechat.message.OutboundMessage
+import com.nice.cxonechat.utilities.isEmpty
internal class ChatThreadMessageHandlerImpl(
private val chat: ChatWithParameters,
@@ -35,18 +40,67 @@ internal class ChatThreadMessageHandlerImpl(
}
override fun send(message: OutboundMessage, listener: OnMessageTransferListener?) {
- val uploads = message.attachments.mapNotNull { attachment ->
- val body = AttachmentUploadModel(attachment)
- val response = chat.service.uploadFile(body, chat.connection.brandId.toString(), chat.connection.channelId).execute()
- val url = response.body()?.fileUrl ?: return@mapNotNull null
- AttachmentModel(url, attachment.friendlyName ?: "document", attachment.mimeType)
+ val uploads = message.attachments.mapNotNull(::uploadAttachment)
+
+ // Ignore messages with no text, successful attachments, or postback.
+ if (uploads.isEmpty() && message.message.isBlank() && message.postback?.isBlank() != false) {
+ throw InvalidParameterException("attempt to send empty message")
}
+
val fields = chat.fields.map(::CustomFieldModel)
val event = MessageEvent(message.message, uploads, fields, chat.storage.authToken, message.postback)
listener?.onProcessed(event.messageId)
- thread.events().trigger(event) {
- chat.fields = emptyList()
- listener?.onSent(event.messageId)
+ thread.events().trigger(
+ event = event,
+ listener = {
+ chat.fields = emptyList()
+ listener?.onSent(event.messageId)
+ },
+ )
+ }
+
+ private fun uploadAttachment(attachment: ContentDescriptor): AttachmentModel? {
+ val body = AttachmentUploadModel(attachment)
+ val attachmentName = attachment.fileName ?: "unknown"
+ val response = runCatching {
+ val connection = chat.connection
+ chat.service.uploadFile(
+ body = body,
+ brandId = connection.brandId.toString(),
+ channelId = connection.channelId
+ ).execute()
+ }.onFailure { throwable ->
+ chat.chatStateListener?.onChatRuntimeException(
+ AttachmentUploadError(attachmentName, throwable)
+ )
+ }.getOrNull()
+
+ return when {
+ response == null -> null
+ !response.isSuccessful -> {
+ val err = response.errorBody()?.string().orEmpty()
+ val errCode = response.code()
+ chat.chatStateListener?.onChatRuntimeException(
+ AttachmentUploadError(
+ attachmentName = attachmentName,
+ cause = InvalidStateException("Error code: $errCode, error message: $err")
+ )
+ )
+ null
+ }
+ response.body()?.fileUrl == null -> {
+ chat.chatStateListener?.onChatRuntimeException(
+ AttachmentUploadError(
+ attachmentName = attachmentName,
+ cause = InvalidStateException("Invalid response")
+ )
+ )
+ null
+ }
+ else -> {
+ val url = response.body()?.fileUrl ?: return null
+ AttachmentModel(url, attachment.friendlyName ?: "document", attachment.mimeType)
+ }
}
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerLogging.kt
index 51d80455..5eff084c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerLogging.kt
@@ -20,8 +20,8 @@ import com.nice.cxonechat.ChatThreadMessageHandler.OnMessageTransferListener
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
import com.nice.cxonechat.message.OutboundMessage
import java.util.UUID
@@ -40,7 +40,7 @@ internal class ChatThreadMessageHandlerLogging(
message: OutboundMessage,
listener: OnMessageTransferListener?,
) = scope("send(${message.hashCode()})") {
- finest("(message=${message.message},attachments=${message.attachments},postback=${message.postback})")
+ verbose("(message=${message.message},attachments=${message.attachments},postback=${message.postback})")
@Suppress("NAME_SHADOWING")
val listener = if (listener !is LoggingListener) LoggingListener(listener, this) else listener
origin.send(message, listener)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerProxy.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerProxy.kt
index 136e0990..41ea9666 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerProxy.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadMessageHandlerProxy.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadMessageHandler
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerConfigProxy.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerConfigProxy.kt
index 74fda9bc..eedc54db 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerConfigProxy.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerConfigProxy.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerImpl.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerImpl.kt
index 2c5c7669..f4085922 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerImpl.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerImpl.kt
@@ -1,16 +1,32 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
import com.nice.cxonechat.ChatThreadHandler
import com.nice.cxonechat.ChatThreadsHandler
-import com.nice.cxonechat.enums.EventType.ThreadArchived
+import com.nice.cxonechat.enums.EventType
import com.nice.cxonechat.enums.EventType.ThreadListFetched
import com.nice.cxonechat.event.FetchThreadEvent
import com.nice.cxonechat.internal.model.ChatThreadInternal
import com.nice.cxonechat.internal.model.ChatThreadMutable
+import com.nice.cxonechat.internal.model.ChatThreadMutable.Companion.asMutable
import com.nice.cxonechat.internal.model.CustomFieldInternal
+import com.nice.cxonechat.internal.model.network.EventCaseStatusChanged
import com.nice.cxonechat.internal.model.network.EventThreadListFetched
-import com.nice.cxonechat.internal.model.network.ReceivedThreadData
import com.nice.cxonechat.internal.socket.EventCallback.Companion.addCallback
import com.nice.cxonechat.prechat.PreChatSurvey
import com.nice.cxonechat.prechat.PreChatSurveyResponse
@@ -21,6 +37,7 @@ import com.nice.cxonechat.state.FieldDefinition
import com.nice.cxonechat.state.checkRequired
import com.nice.cxonechat.state.validate
import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.ChatThreadState.Pending
import java.util.UUID
internal class ChatThreadsHandlerImpl(
@@ -49,18 +66,26 @@ internal class ChatThreadsHandlerImpl(
val uuid = UUID.randomUUID()
val thread = ChatThreadInternal(
id = uuid,
- fields = combinedCustomFieldMap.map(::CustomFieldInternal)
+ fields = combinedCustomFieldMap.map(::CustomFieldInternal),
+ threadState = Pending,
)
- return createHandler(thread)
+ return createHandler(thread, true)
}
override fun threads(listener: ChatThreadsHandler.OnThreadsUpdatedListener): Cancellable {
+ var threads: List = emptyList()
val threadListFetched = chat.socketListener.addCallback(ThreadListFetched) { event ->
- listener.onThreadsUpdated(event.threads.map(ReceivedThreadData::toChatThread))
+ threads = event.threads.map { threadData -> threadData.toChatThread().asMutable() }
+ listener.onThreadsUpdated(threads)
}
- val threadArchived = chat.socketListener.addCallback(ThreadArchived) {
- refresh()
+ val threadArchived = chat.socketListener.addCallback(EventType.CaseStatusChanged) { event ->
+ threads.asSequence()
+ .filter(event::inThread)
+ .forEach { thread ->
+ CaseStatusChangedHandlerActions.handleCaseClosed(thread, event) { listener.onThreadsUpdated(threads) }
+ }
}
+
return Cancellable(
threadListFetched,
threadArchived
@@ -73,6 +98,7 @@ internal class ChatThreadsHandlerImpl(
private fun createHandler(
thread: ChatThread,
+ addWelcomeHandler: Boolean = false,
): ChatThreadHandler {
val mutableThread = thread as? ChatThreadMutable ?: ChatThreadMutable.from(thread)
var handler: ChatThreadHandler
@@ -81,6 +107,8 @@ internal class ChatThreadsHandlerImpl(
handler = ChatThreadHandlerMessages(handler, chat, mutableThread)
handler = ChatThreadHandlerAgentUpdate(handler, chat, mutableThread)
handler = ChatThreadHandlerAgentTyping(handler, chat)
+ handler = ChatThreadHandlerMessageReadByAgent(handler, chat, mutableThread)
+ if (addWelcomeHandler) handler = ChatThreadHandlerWelcome(handler, chat, mutableThread)
return handler
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerLogging.kt
index 60b7be09..7af2fc2d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerLogging.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerLogging.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.ChatThreadsHandler
@@ -5,8 +20,8 @@ import com.nice.cxonechat.ChatThreadsHandler.OnThreadsUpdatedListener
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
import com.nice.cxonechat.log.duration
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
import com.nice.cxonechat.prechat.PreChatSurvey
import com.nice.cxonechat.prechat.PreChatSurveyResponse
import com.nice.cxonechat.state.FieldDefinition
@@ -41,7 +56,7 @@ internal class ChatThreadsHandlerLogging(
}
override fun threads(listener: OnThreadsUpdatedListener) = scope("threads") {
- finest("Registered")
+ verbose("Registered")
origin.threads {
scope("onThreadsUpdated") {
duration {
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMemoizeHandlers.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMemoizeHandlers.kt
new file mode 100644
index 00000000..286e3fa5
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMemoizeHandlers.kt
@@ -0,0 +1,32 @@
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.ChatThreadHandler
+import com.nice.cxonechat.ChatThreadsHandler
+import com.nice.cxonechat.prechat.PreChatSurveyResponse
+import com.nice.cxonechat.state.FieldDefinition
+import com.nice.cxonechat.thread.ChatThread
+import java.util.Collections
+import java.util.UUID
+
+/**
+ * Implementation of [ChatThreadsHandler] which prevents creation of multiple instances of [ChatThreadHandler]
+ * for [ChatThread] with the same [ChatThread.id].
+ */
+internal class ChatThreadsHandlerMemoizeHandlers(
+ private val origin: ChatThreadsHandler,
+) : ChatThreadsHandler by origin {
+
+ private val threadHandlersMemoized: MutableMap by lazy { Collections.synchronizedMap(mutableMapOf()) }
+
+ override fun create(
+ customFields: Map,
+ preChatSurveyResponse: Sequence>,
+ ): ChatThreadHandler = origin.create(customFields, preChatSurveyResponse).also(::memoizeThreadHandler)
+
+ override fun thread(thread: ChatThread): ChatThreadHandler =
+ threadHandlersMemoized[thread.id] ?: origin.thread(thread).also(::memoizeThreadHandler)
+
+ private fun memoizeThreadHandler(threadHandler: ChatThreadHandler) {
+ threadHandlersMemoized[threadHandler.get().id] = threadHandler
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMessages.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMessages.kt
index b0d3b6d1..6a6c64ed 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMessages.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMessages.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMetadata.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMetadata.kt
new file mode 100644
index 00000000..c9d58e10
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerMetadata.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal
+
+import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.ChatMode.MULTI_THREAD
+import com.nice.cxonechat.ChatThreadEventHandlerActions.loadMetadata
+import com.nice.cxonechat.ChatThreadHandler
+import com.nice.cxonechat.ChatThreadsHandler
+import com.nice.cxonechat.ChatThreadsHandler.OnThreadsUpdatedListener
+import com.nice.cxonechat.enums.ErrorType.MetadataLoadFailed
+import com.nice.cxonechat.exceptions.RuntimeChatException.ServerCommunicationError
+import com.nice.cxonechat.internal.model.ChatThreadMutable
+import com.nice.cxonechat.internal.model.ChatThreadMutable.Companion.asMutable
+import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.ChatThreadState.Loaded
+import com.nice.cxonechat.thread.ChatThreadState.Ready
+import java.util.UUID
+
+internal class ChatThreadsHandlerMetadata(
+ private val origin: ChatThreadsHandler,
+ private val chat: ChatWithParameters,
+) : ChatThreadsHandler by origin {
+ private val metadataRequested = mutableSetOf()
+
+ override fun refresh() {
+ metadataRequested.clear()
+ origin.refresh()
+ }
+
+ override fun threads(listener: OnThreadsUpdatedListener) = origin.threads { threads ->
+ val threadIds = threads.map(ChatThread::id).toSet()
+ val mutableThreads = threads.map { it.asMutable() }
+ for (thread in mutableThreads) {
+ if (!metadataRequested.contains(thread.id)) {
+ val threadHandler = thread(thread)
+ registerForThreadUpdates(threadHandler, thread, listener, threads, threadIds)
+ requestMetadataForThread(threadHandler, thread)
+ }
+ }
+ listener.onThreadsUpdated(threads)
+ if (threads.isEmpty()) signalChatIsReady()
+ }.also {
+ refresh()
+ }
+
+ private fun registerForThreadUpdates(
+ threadHandler: ChatThreadHandler,
+ thread: ChatThreadMutable,
+ listener: OnThreadsUpdatedListener,
+ threads: List,
+ threadIds: Set,
+ ) {
+ var onMetadataLoaded: Cancellable? = null
+ onMetadataLoaded = threadHandler.get { updatedThread ->
+ if (updatedThread.threadState === Loaded || updatedThread.threadState === Ready) {
+ if (updatedThread.threadState === Loaded) {
+ thread.update(updatedThread)
+ listener.onThreadsUpdated(threads)
+ if (metadataRequested.containsAll(threadIds)) signalChatIsReady()
+ }
+ onMetadataLoaded?.cancel()
+ }
+ }
+ }
+
+ private fun requestMetadataForThread(threadHandler: ChatThreadHandler, thread: ChatThreadMutable) {
+ threadHandler.events().loadMetadata(listener = {
+ metadataRequested.add(thread.id)
+ }) {
+ chat.chatStateListener?.onChatRuntimeException(
+ ServerCommunicationError(
+ MetadataLoadFailed.value
+ )
+ )
+ }
+ }
+
+ private fun signalChatIsReady() {
+ if (chat.chatMode === MULTI_THREAD) {
+ chat.chatStateListener?.onReady()
+ }
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerReplayLastEmpty.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerReplayLastEmpty.kt
index 7ddd15f8..5423d3f9 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerReplayLastEmpty.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerReplayLastEmpty.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
@@ -9,7 +24,7 @@ import com.nice.cxonechat.state.FieldDefinition
import com.nice.cxonechat.thread.ChatThread
internal class ChatThreadsHandlerReplayLastEmpty(
- private val origin: ChatThreadsHandlerImpl,
+ private val origin: ChatThreadsHandler,
) : ChatThreadsHandler by origin {
private var latestThread: (() -> ChatThread)? = null
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerWelcome.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerWelcome.kt
deleted file mode 100644
index fc28cc90..00000000
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatThreadsHandlerWelcome.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.nice.cxonechat.internal
-
-import com.nice.cxonechat.ChatThreadHandler
-import com.nice.cxonechat.ChatThreadsHandler
-import com.nice.cxonechat.event.thread.SendOutboundEvent
-import com.nice.cxonechat.prechat.PreChatSurveyResponse
-import com.nice.cxonechat.state.FieldDefinition
-import com.nice.cxonechat.thread.CustomField
-
-internal class ChatThreadsHandlerWelcome(
- private val origin: ChatThreadsHandler,
- private val chat: ChatWithParameters,
-) : ChatThreadsHandler by origin {
-
- override fun create(
- customFields: Map,
- preChatSurveyResponse: Sequence>,
- ): ChatThreadHandler {
- return origin.create(customFields, preChatSurveyResponse)
- .also(::addWelcomeMessageToThread)
- }
-
- private fun addWelcomeMessageToThread(handler: ChatThreadHandler) {
- val storedMessage = chat.storage.welcomeMessage
- if (storedMessage.isBlank()) return
-
- val connection = chat.connection
- val parameters = mapOf(
- "firstName" to connection.firstName,
- "lastName" to connection.lastName,
- )
- val customerFieldMap = chat.fields.toMap()
- val contactFieldMap = handler.get().fields.toMap()
- val message = VariableMessageParser.parse(
- storedMessage,
- parameters,
- customerFieldMap,
- contactFieldMap
- )
- val token = chat.storage.authToken
- handler.events().trigger(SendOutboundEvent(message, token))
- }
-
- private companion object {
- private fun customFieldAsPair(customField: CustomField): Pair = customField.id to customField.value
- private fun List.toMap() = associate(::customFieldAsPair)
- }
-}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWelcomeMessageUpdate.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWelcomeMessageUpdate.kt
index d232f79d..9ec09743 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWelcomeMessageUpdate.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWelcomeMessageUpdate.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.enums.ActionType
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWithParameters.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWithParameters.kt
index f85f1ea5..bc667ef5 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWithParameters.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ChatWithParameters.kt
@@ -16,6 +16,7 @@
package com.nice.cxonechat.internal
import com.nice.cxonechat.Chat
+import com.nice.cxonechat.ChatStateListener
import com.nice.cxonechat.event.PageViewEvent
import com.nice.cxonechat.internal.socket.ProxyWebSocketListener
import com.nice.cxonechat.state.Connection
@@ -25,7 +26,7 @@ import okhttp3.WebSocket
internal interface ChatWithParameters : Chat {
val entrails: ChatEntrails
- val socket: WebSocket
+ val socket: WebSocket?
val socketListener: ProxyWebSocketListener
var connection: Connection
override var fields: List
@@ -33,6 +34,8 @@ internal interface ChatWithParameters : Chat {
/** Last page view event received, if any. */
var lastPageViewed: PageViewEvent?
+ val chatStateListener: ChatStateListener?
+
val storage get() = entrails.storage
val service get() = entrails.service
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/RemoteServiceBuilder.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/RemoteServiceBuilder.kt
index c5a06d3f..6443fd57 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/RemoteServiceBuilder.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/RemoteServiceBuilder.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.api.RemoteService
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/StoreVisitorCallback.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/StoreVisitorCallback.kt
index 044fe9da..1c7cfdbf 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/StoreVisitorCallback.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/StoreVisitorCallback.kt
@@ -17,8 +17,8 @@ package com.nice.cxonechat.internal
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
-import com.nice.cxonechat.log.finest
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
import com.nice.cxonechat.log.warning
import retrofit2.Call
import retrofit2.Callback
@@ -31,7 +31,7 @@ internal class StoreVisitorCallback(
override fun onResponse(call: Call, response: Response) = scope("onResponse") {
if (response.isSuccessful) {
- logger.finest("StoreVisitor created")
+ logger.verbose("StoreVisitor created")
} else {
logger.warning("StoreVisitor creation failed: ${response.errorBody()?.string()}")
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/Threading.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/Threading.kt
index e93ec76e..d627939b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/Threading.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/Threading.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ThreadingExecutor.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ThreadingExecutor.kt
index d2b84c47..3dbc5fbf 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ThreadingExecutor.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/ThreadingExecutor.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
import com.nice.cxonechat.Cancellable
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/VariableMessageParser.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/VariableMessageParser.kt
index 26c8ea44..3d9048a2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/VariableMessageParser.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/VariableMessageParser.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal
internal object VariableMessageParser {
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/AgentCopyable.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/AgentCopyable.kt
index 183805a3..6c484963 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/AgentCopyable.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/AgentCopyable.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.copy
import com.nice.cxonechat.internal.model.AgentInternal
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ChatThreadCopyable.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ChatThreadCopyable.kt
index 1eb4ad07..9abebe09 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ChatThreadCopyable.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ChatThreadCopyable.kt
@@ -20,6 +20,7 @@ import com.nice.cxonechat.internal.model.ChatThreadMutable
import com.nice.cxonechat.message.Message
import com.nice.cxonechat.thread.Agent
import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.ChatThreadState
import com.nice.cxonechat.thread.CustomField
import java.util.UUID
@@ -36,6 +37,7 @@ internal class ChatThreadCopyable(
canAddMoreMessages: Boolean = model.canAddMoreMessages,
scrollToken: String = model.scrollToken,
fields: List = model.fields,
+ threadState: ChatThreadState = model.threadState,
) = ChatThreadInternal(
id = id,
threadName = threadName,
@@ -43,7 +45,8 @@ internal class ChatThreadCopyable(
threadAgent = threadAgent,
canAddMoreMessages = canAddMoreMessages,
scrollToken = scrollToken,
- fields = fields
+ fields = fields,
+ threadState = threadState,
)
companion object {
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ConnectionCopyable.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ConnectionCopyable.kt
index 0beb116d..08a83935 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ConnectionCopyable.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/copy/ConnectionCopyable.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.copy
import com.nice.cxonechat.internal.model.ConnectionInternal
@@ -15,7 +30,7 @@ internal class ConnectionCopyable(
channelId: String = connection.channelId,
firstName: String = connection.firstName,
lastName: String = connection.lastName,
- customerId: UUID? = connection.customerId,
+ customerId: String? = connection.customerId,
environment: Environment = connection.environment,
visitorId: UUID = connection.visitorId,
) = ConnectionInternal(
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ActionInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ActionInternal.kt
index 8fc6af2b..25c22604 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ActionInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ActionInternal.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.PolyAction
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AgentInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AgentInternal.kt
index c81933a3..29015310 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AgentInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AgentInternal.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.thread.Agent
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentModel.kt
index 670d6774..996c5248 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentUploadModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentUploadModel.kt
index 9dbc048d..5cad603b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentUploadModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/AttachmentUploadModel.kt
@@ -1,23 +1,55 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
+import android.annotation.SuppressLint
import android.util.Base64
import com.google.gson.annotations.SerializedName
import com.nice.cxonechat.message.ContentDescriptor
import com.nice.cxonechat.message.ContentDescriptor.DataSource
+import com.nice.cxonechat.util.applyDefaultExtension
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStream
-internal data class AttachmentUploadModel(
+@Suppress("UseDataClass")
+internal class AttachmentUploadModel {
@SerializedName("content")
- val content: String? = null,
+ val content: String
@SerializedName("mimeType")
- val mimeType: String? = null,
+ val mimeType: String
@SerializedName("fileName")
- val fileName: String? = null,
-) {
+ val fileName: String
+
+ /**
+ * Default constructor from direct properties.
+ *
+ * @param content base-64 encoded content to send
+ * @param mimeType mime type of the attachment
+ * @param fileName "friendly" name of the attachment. If the name has no extension,
+ * then a default extension will be applied based on [mimeType].
+ */
+ constructor(content: String, mimeType: String, fileName: String) {
+ this.content = content
+ this.mimeType = mimeType
+ this.fileName = fileName.applyDefaultExtension(mimeType)
+ }
+
/**
* Convenience constructor that gets all necessary fields from the passed
* [ContentDescriptor].
@@ -29,9 +61,29 @@ internal data class AttachmentUploadModel(
constructor(upload: ContentDescriptor): this(
content = upload.content.read().base64,
mimeType = upload.mimeType,
- fileName = upload.friendlyName
+ fileName = upload.friendlyName ?: upload.fileName
)
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as AttachmentUploadModel
+
+ if (content != other.content) return false
+ if (mimeType != other.mimeType) return false
+ return fileName == other.fileName
+ }
+
+ override fun hashCode(): Int {
+ var result = content.hashCode()
+ result = 31 * result + mimeType.hashCode()
+ result = 31 * result + fileName.hashCode()
+ return result
+ }
+
+ override fun toString() = "AttachmentUploadModel(content='$content', mimeType='$mimeType', fileName='$fileName')"
+
companion object {
/**
* Encode the receiving [ByteArray] as a base-64 encoded string.
@@ -49,6 +101,9 @@ internal data class AttachmentUploadModel(
* @return data from [DataSource] as a base-64 encoded string
* @throws IOException if the data source can't be read
*/
+ @SuppressLint(
+ "Recycle" // FP - opened InputStream is closed via the `use` function.
+ )
@Throws(IOException::class)
private fun DataSource.read() = when (this) {
is DataSource.Uri ->
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Brand.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Brand.kt
index 184459e9..09fc2ce6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Brand.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Brand.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelConfiguration.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelConfiguration.kt
index c2acd016..29051fed 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelConfiguration.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelConfiguration.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelIdentifier.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelIdentifier.kt
index dbadf055..9e598fb8 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelIdentifier.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChannelIdentifier.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadInternal.kt
index a344eb9d..5aa6434a 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadInternal.kt
@@ -1,8 +1,24 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.message.Message
import com.nice.cxonechat.thread.Agent
import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.ChatThreadState
import com.nice.cxonechat.thread.CustomField
import java.util.UUID
@@ -14,6 +30,7 @@ internal data class ChatThreadInternal(
override val canAddMoreMessages: Boolean = true,
override val scrollToken: String = "",
override val fields: List = emptyList(),
+ override val threadState: ChatThreadState,
) : ChatThread() {
override fun toString() = buildString {
@@ -31,6 +48,8 @@ internal data class ChatThreadInternal(
append(scrollToken)
append("', fields=")
append(fields)
+ append("', state=")
+ append(threadState)
append(")")
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadMutable.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadMutable.kt
index 12c1edb2..59d3a2b5 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadMutable.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ChatThreadMutable.kt
@@ -1,8 +1,24 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.message.Message
import com.nice.cxonechat.thread.Agent
import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.ChatThreadState
import com.nice.cxonechat.thread.CustomField
import java.util.UUID
@@ -26,6 +42,8 @@ internal class ChatThreadMutable private constructor(
get() = thread.scrollToken
override val fields: List
get() = thread.fields
+ override val threadState: ChatThreadState
+ get() = thread.threadState
fun update(thread: ChatThread) {
this.thread = thread
@@ -52,5 +70,7 @@ internal class ChatThreadMutable private constructor(
is ChatThreadMutable -> thread
else -> ChatThreadMutable(thread)
}
+
+ fun ChatThread.asMutable() = from(this)
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionExt.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionExt.kt
index 012d835f..4376acc2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionExt.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionExt.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.exceptions.MissingCustomerId
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionInternal.kt
index 2db8e720..c8ea6133 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ConnectionInternal.kt
@@ -24,7 +24,7 @@ internal data class ConnectionInternal(
override val channelId: String,
override val firstName: String,
override val lastName: String,
- override val customerId: UUID?,
+ override val customerId: String?,
override val environment: Environment,
override val visitorId: UUID,
) : Connection {
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Contact.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Contact.kt
index 6bb4f525..c8edd83f 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Contact.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Contact.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ContentDescriptorInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ContentDescriptorInternal.kt
index f00fa1ae..fa1572f0 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ContentDescriptorInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ContentDescriptorInternal.kt
@@ -20,8 +20,8 @@ import com.nice.cxonechat.message.ContentDescriptor.DataSource
internal data class ContentDescriptorInternal(
override val content: DataSource,
- override val mimeType: String?,
- override val fileName: String?,
+ override val mimeType: String,
+ override val fileName: String,
override val friendlyName: String?,
) : ContentDescriptor {
override fun toString(): String =
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldModel.kt
index cf2ecdff..62609fe6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldPolyType.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldPolyType.kt
index 39f430b5..6f397c5b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldPolyType.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomFieldPolyType.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomerIdentityModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomerIdentityModel.kt
index 36c7f4cd..24159aae 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomerIdentityModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/CustomerIdentityModel.kt
@@ -17,11 +17,10 @@ package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
import com.nice.cxonechat.message.MessageAuthor
-import java.util.UUID
internal data class CustomerIdentityModel(
@SerializedName("idOnExternalPlatform")
- val idOnExternalPlatform: UUID,
+ val idOnExternalPlatform: String,
@SerializedName("firstName")
val firstName: String? = null,
@@ -34,7 +33,7 @@ internal data class CustomerIdentityModel(
) {
fun toMessageAuthor(): MessageAuthor = MessageAuthorInternal(
- id = idOnExternalPlatform.toString(),
+ id = idOnExternalPlatform,
firstName = firstName.orEmpty(),
lastName = lastName.orEmpty(),
imageUrl = imageUrl,
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ErrorModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ErrorModel.kt
new file mode 100644
index 00000000..b2e1df1c
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/ErrorModel.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal.model
+
+import com.google.gson.annotations.SerializedName
+import com.nice.cxonechat.enums.ErrorType
+
+/**
+ * Model for error event pushed from server.
+ *
+ * @property error Details about the error.
+ */
+internal data class ErrorModel(
+ @SerializedName("error")
+ val error: Error,
+) {
+ /**
+ * Error details.
+ *
+ * @property errorCode One of predefined [ErrorType]s.
+ * @property transactionId Id of transaction which has triggered the error, usable for tracking down the cause in
+ * server logs.
+ */
+ internal data class Error(
+ @SerializedName("errorCode")
+ val errorCode: ErrorType,
+ @SerializedName("transactionId")
+ val transactionId: String,
+ )
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MediaInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MediaInternal.kt
index f2f901e8..939ceb70 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MediaInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MediaInternal.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MediaModel
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageDirectionModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageDirectionModel.kt
index 0ce86e27..3b2c9d77 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageDirectionModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageDirectionModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageListPicker.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageListPicker.kt
index 59635e26..ed3fad24 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageListPicker.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageListPicker.kt
@@ -1,6 +1,20 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
-import com.nice.cxonechat.internal.model.MessageModel.Companion.author
import com.nice.cxonechat.internal.model.network.MessagePolyContent
import com.nice.cxonechat.message.Action
import com.nice.cxonechat.message.Attachment
@@ -28,7 +42,7 @@ internal data class MessageListPicker(
get() = model.direction.toMessageDirection()
override val metadata: MessageMetadata
get() = model.userStatistics.toMessageMetadata()
- override val author: MessageAuthor
+ override val author: MessageAuthor?
get() = model.author
override val attachments: Iterable
get() = model.attachments.map(AttachmentModel::toAttachment)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageMetadataInternal.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageMetadataInternal.kt
index 11f11a55..e8d5d295 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageMetadataInternal.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageMetadataInternal.kt
@@ -16,15 +16,27 @@
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.message.MessageMetadata
+import com.nice.cxonechat.message.MessageStatus
+import com.nice.cxonechat.message.MessageStatus.READ
+import com.nice.cxonechat.message.MessageStatus.SEEN
+import com.nice.cxonechat.message.MessageStatus.SENT
import java.util.Date
internal data class MessageMetadataInternal(
+ override val seenAt: Date?,
override val readAt: Date?,
) : MessageMetadata {
- override fun toString() = buildString {
- append("MessageMetadata(readAt=")
- append(readAt)
- append(")")
+ @Transient
+ override val status: MessageStatus = when {
+ readAt != null -> READ
+ seenAt != null -> SEEN
+ else -> SENT
}
+
+ override fun toString(): String = "MessageMetadata(" +
+ "seenAt=$seenAt, " +
+ "readAt=$readAt, " +
+ "status=$status" +
+ ")"
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageModel.kt
index b9c95ecf..e031992e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
@@ -11,6 +26,7 @@ import com.nice.cxonechat.internal.model.network.MessagePolyContent.QuickReplies
import com.nice.cxonechat.internal.model.network.MessagePolyContent.RichLink
import com.nice.cxonechat.internal.model.network.MessagePolyContent.Text
import com.nice.cxonechat.internal.model.network.UserStatistics
+import com.nice.cxonechat.message.MessageAuthor
import java.util.Date
import java.util.UUID
@@ -42,6 +58,11 @@ internal data class MessageModel(
@SerializedName("authorEndUserIdentity")
val authorEndUserIdentity: CustomerIdentityModel? = null,
) {
+ val author: MessageAuthor?
+ get() = when (direction) {
+ ToAgent -> authorEndUserIdentity?.toMessageAuthor()
+ ToClient -> authorUser?.toMessageAuthor()
+ }
fun toMessage() = when (messageContent) {
is Plugin -> MessagePlugin(this)
@@ -51,13 +72,4 @@ internal data class MessageModel(
is RichLink -> MessageRichLink(this)
Noop -> null
}
-
- companion object {
-
- val MessageModel.author
- get() = when (direction) {
- ToAgent -> authorUser?.toMessageAuthor() ?: MessageAuthorDefaults.User
- ToClient -> authorEndUserIdentity?.toMessageAuthor() ?: MessageAuthorDefaults.Agent
- }
- }
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessagePlugin.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessagePlugin.kt
index 3bfd7f9c..8f56bfe6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessagePlugin.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessagePlugin.kt
@@ -15,7 +15,6 @@
package com.nice.cxonechat.internal.model
-import com.nice.cxonechat.internal.model.MessageModel.Companion.author
import com.nice.cxonechat.internal.model.network.MessagePolyContent
import com.nice.cxonechat.message.Attachment
import com.nice.cxonechat.message.Message.Plugin
@@ -43,7 +42,7 @@ internal data class MessagePlugin(
get() = model.direction.toMessageDirection()
override val metadata: MessageMetadata
get() = model.userStatistics.toMessageMetadata()
- override val author: MessageAuthor
+ override val author: MessageAuthor?
get() = model.author
override val attachments: Iterable
get() = model.attachments.map(AttachmentModel::toAttachment)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageQuickReplies.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageQuickReplies.kt
index 90fed0bd..52c4cf1e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageQuickReplies.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageQuickReplies.kt
@@ -1,6 +1,20 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
-import com.nice.cxonechat.internal.model.MessageModel.Companion.author
import com.nice.cxonechat.internal.model.network.MessagePolyContent
import com.nice.cxonechat.message.Action
import com.nice.cxonechat.message.Attachment
@@ -28,7 +42,7 @@ internal data class MessageQuickReplies(
get() = model.direction.toMessageDirection()
override val metadata: MessageMetadata
get() = model.userStatistics.toMessageMetadata()
- override val author: MessageAuthor
+ override val author: MessageAuthor?
get() = model.author
override val attachments: Iterable
get() = model.attachments.map(AttachmentModel::toAttachment)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageRichLink.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageRichLink.kt
index 92d018d1..073c1fcc 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageRichLink.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageRichLink.kt
@@ -1,6 +1,20 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
-import com.nice.cxonechat.internal.model.MessageModel.Companion.author
import com.nice.cxonechat.internal.model.network.MessagePolyContent
import com.nice.cxonechat.message.Attachment
import com.nice.cxonechat.message.Media
@@ -28,7 +42,7 @@ internal data class MessageRichLink(
get() = model.direction.toMessageDirection()
override val metadata: MessageMetadata
get() = model.userStatistics.toMessageMetadata()
- override val author: MessageAuthor
+ override val author: MessageAuthor?
get() = model.author
override val attachments: Iterable
get() = model.attachments.map(AttachmentModel::toAttachment)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageText.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageText.kt
index f350fd92..8fb5e7ce 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageText.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/MessageText.kt
@@ -15,7 +15,6 @@
package com.nice.cxonechat.internal.model
-import com.nice.cxonechat.internal.model.MessageModel.Companion.author
import com.nice.cxonechat.internal.model.network.MessagePolyContent
import com.nice.cxonechat.message.Attachment
import com.nice.cxonechat.message.Message.Text
@@ -42,7 +41,7 @@ internal data class MessageText(
get() = model.direction.toMessageDirection()
override val metadata: MessageMetadata
get() = model.userStatistics.toMessageMetadata()
- override val author: MessageAuthor
+ override val author: MessageAuthor?
get() = model.author
override val attachments: Iterable
get() = model.attachments.map(AttachmentModel::toAttachment)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/NodeModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/NodeModel.kt
index 8745e6a2..9ae4b009 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/NodeModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/NodeModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementButton.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementButton.kt
index cc11c36c..030d5833 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementButton.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementButton.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCountdown.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCountdown.kt
index b015300c..72fa93d3 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCountdown.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCountdown.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCustom.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCustom.kt
index 905198f8..6a2ad9b5 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCustom.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementCustom.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementFile.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementFile.kt
index 3b4df280..562f8f1b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementFile.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementFile.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementGallery.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementGallery.kt
index 19e9f289..1e7e7293 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementGallery.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementGallery.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.message.PluginElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementSubtitle.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementSubtitle.kt
index d9853265..7a2316e1 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementSubtitle.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementSubtitle.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementText.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementText.kt
index 3cb227b4..b62c2e77 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementText.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementText.kt
@@ -1,7 +1,24 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
import com.nice.cxonechat.message.PluginElement.Text
+import com.nice.cxonechat.message.TextFormat
+import com.nice.cxonechat.message.TextFormat.Plain
internal data class PluginElementText(
private val element: MessagePolyElement.Text,
@@ -10,19 +27,27 @@ internal data class PluginElementText(
override val text: String
get() = element.text
+ override val format = element.mimeType?.let(TextFormat::from) ?: Plain
+
+ @Deprecated(
+ "isMarkdown has been deprecated, please replace with format.",
+ ReplaceWith("format.isMarkdown")
+ )
override val isMarkdown: Boolean
- get() = element.mimeType.equals("text/markdown", ignoreCase = true)
+ get() = format.isMarkdown
+ @Deprecated(
+ "isHtml has been deprecated, please replace with format.",
+ ReplaceWith("format.isHtml")
+ )
override val isHtml: Boolean
- get() = element.mimeType.equals("text/html", ignoreCase = true)
+ get() = format.isHtml
override fun toString() = buildString {
append("PluginElement.Text(text='")
append(text)
- append("', isMarkdown=")
- append(isMarkdown)
- append(", isHtml=")
- append(isHtml)
+ append("', format=")
+ append(format)
append(")")
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementTitle.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementTitle.kt
index 04b93aec..bdec4829 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementTitle.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PluginElementTitle.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.nice.cxonechat.internal.model.network.MessagePolyElement
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactCustomFieldDefinitionModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactCustomFieldDefinitionModel.kt
index a65b339c..26b8248e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactCustomFieldDefinitionModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactCustomFieldDefinitionModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactFormModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactFormModel.kt
index a6bcdf9b..1bbf2fe8 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactFormModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/PreContactFormModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/SelectorModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/SelectorModel.kt
index 6eb9b091..b4620a4b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/SelectorModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/SelectorModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Thread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Thread.kt
index 3c24c939..653afe5b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Thread.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/Thread.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessPayload.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessPayload.kt
new file mode 100644
index 00000000..9a3ef4d4
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessPayload.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal.model.network
+
+import com.google.gson.annotations.SerializedName
+
+internal data class AccessPayload(
+ @SerializedName("accessToken")
+ val accessToken: AccessTokenPayload?,
+) {
+ constructor(token: String?) : this(token?.let(::AccessTokenPayload))
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessToken.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessToken.kt
index f8ea83cc..c847e76f 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessToken.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessToken.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessTokenPayload.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessTokenPayload.kt
index 53a4e306..fdcb9e01 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessTokenPayload.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/AccessTokenPayload.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionArchiveThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionArchiveThread.kt
index f728da22..f44c9fab 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionArchiveThread.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionArchiveThread.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionAuthorizeCustomer.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionAuthorizeCustomer.kt
index 1ba1d503..3a10a602 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionAuthorizeCustomer.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionAuthorizeCustomer.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionCustomerTyping.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionCustomerTyping.kt
index c7857b3d..68383fbf 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionCustomerTyping.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionCustomerTyping.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionExecuteTrigger.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionExecuteTrigger.kt
index c621a145..cdf62bb9 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionExecuteTrigger.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionExecuteTrigger.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionFetchThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionFetchThread.kt
index a7d5a358..80da0b68 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionFetchThread.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionFetchThread.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadMoreMessages.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadMoreMessages.kt
index 5827bac1..872c1a1f 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadMoreMessages.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadMoreMessages.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadThreadMetadata.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadThreadMetadata.kt
index aa7bdede..77df56a2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadThreadMetadata.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionLoadThreadMetadata.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessage.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessage.kt
index 1bb5c3d7..947f578f 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessage.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessage.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessageSeenByCustomer.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessageSeenByCustomer.kt
index 14b3a948..ca948a28 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessageSeenByCustomer.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionMessageSeenByCustomer.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionOutboundMessage.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionOutboundMessage.kt
index d31f47a1..9d5811d8 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionOutboundMessage.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionOutboundMessage.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
@@ -9,9 +24,10 @@ import com.nice.cxonechat.internal.model.CustomFieldModel
import com.nice.cxonechat.internal.model.Thread
import com.nice.cxonechat.state.Connection
import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.thread.CustomField
import java.util.UUID
-internal data class ActionOutboundMessage constructor(
+internal data class ActionOutboundMessage(
@SerializedName("action")
val action: EventAction = ChatWindowEvent,
@SerializedName("eventId")
@@ -73,12 +89,12 @@ internal data class ActionOutboundMessage constructor(
thread = Thread(thread),
messageContent = MessageContent(message),
id = id,
- customer = fields.takeUnless { it.isEmpty() }?.let(::CustomFieldsData),
- customerContact = thread.fields.takeUnless { it.isEmpty() }
+ customer = fields.takeUnless(List::isEmpty)?.let(::CustomFieldsData),
+ customerContact = thread.fields.takeUnless(List::isEmpty)
?.map(::CustomFieldModel)
?.let(::CustomFieldsData),
attachments = attachments.toList(),
- accessToken = token?.takeUnless { it.isBlank() }?.let(::AccessTokenPayload)
+ accessToken = token?.takeUnless(String::isBlank)?.let(::AccessTokenPayload)
)
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionReconnectCustomer.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionReconnectCustomer.kt
index 41da355d..bbda990c 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionReconnectCustomer.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionReconnectCustomer.kt
@@ -1,9 +1,23 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
import com.nice.cxonechat.enums.EventAction
import com.nice.cxonechat.enums.EventType.ReconnectCustomer
-import com.nice.cxonechat.internal.model.network.ActionRefreshToken.Data
import com.nice.cxonechat.state.Connection
import java.util.UUID
@@ -13,18 +27,18 @@ internal data class ActionReconnectCustomer(
@SerializedName("eventId")
val eventId: UUID = UUID.randomUUID(),
@SerializedName("payload")
- val payload: LegacyPayload,
+ val payload: LegacyPayload,
) {
constructor(
connection: Connection,
visitor: UUID,
- token: String,
+ token: String?,
) : this(
payload = LegacyPayload(
eventType = ReconnectCustomer,
connection = connection,
- data = Data(token),
+ data = AccessPayload(token),
visitor = visitor
)
)
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRecoverThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRecoverThread.kt
index 5d1d04f6..5b642c99 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRecoverThread.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRecoverThread.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRefreshToken.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRefreshToken.kt
index 089e1a21..9cf54de5 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRefreshToken.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionRefreshToken.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
@@ -13,7 +28,7 @@ internal data class ActionRefreshToken(
@SerializedName("eventId")
val eventId: UUID = UUID.randomUUID(),
@SerializedName("payload")
- val payload: LegacyPayload,
+ val payload: LegacyPayload,
) {
constructor(
@@ -23,15 +38,7 @@ internal data class ActionRefreshToken(
payload = LegacyPayload(
eventType = RefreshToken,
connection = connection,
- data = Data(token)
+ data = AccessPayload(token)
)
)
-
- data class Data(
- @SerializedName("accessToken")
- val accessToken: AccessTokenPayload,
- ) {
-
- constructor(token: String) : this(AccessTokenPayload(token))
- }
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetContactCustomFields.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetContactCustomFields.kt
index 1423816c..61fa5cce 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetContactCustomFields.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetContactCustomFields.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetCustomerCustomFields.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetCustomerCustomFields.kt
index 1c3e6726..0035582a 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetCustomerCustomFields.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionSetCustomerCustomFields.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionStoreVisitorEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionStoreVisitorEvent.kt
index ee860ed9..dc990de7 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionStoreVisitorEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionStoreVisitorEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionUpdateThread.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionUpdateThread.kt
index c38b96f3..deea8a81 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionUpdateThread.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ActionUpdateThread.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Conversion.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Conversion.kt
index bbfdf3af..6127a0ae 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Conversion.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Conversion.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomFieldsData.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomFieldsData.kt
index edf8b584..9b7938b3 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomFieldsData.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomFieldsData.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomVariable.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomVariable.kt
index 0dbb1679..b8eb255d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomVariable.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/CustomVariable.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/DeviceFingerprint.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/DeviceFingerprint.kt
index 68ccb8b5..45a56af3 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/DeviceFingerprint.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/DeviceFingerprint.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventAgentTyping.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventAgentTyping.kt
index f23f54e6..d106f9c2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventAgentTyping.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventAgentTyping.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
@@ -11,6 +26,10 @@ internal data class EventAgentTyping(
val data: Data,
) {
+ /**
+ * Information about agent which has triggered the event.
+ * Agent value is null if the event is triggered by the customer.
+ */
val agent get() = data.user?.toAgent()
fun inThread(thread: ChatThread) =
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCaseStatusChanged.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCaseStatusChanged.kt
new file mode 100644
index 00000000..89a74299
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCaseStatusChanged.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal.model.network
+
+import com.google.gson.annotations.SerializedName
+import com.nice.cxonechat.thread.ChatThread
+import com.nice.cxonechat.util.DateTime
+import java.util.UUID
+
+internal data class EventCaseStatusChanged(
+ @SerializedName("eventId")
+ val eventId: UUID = UUID.randomUUID(),
+ @SerializedName("createdAt")
+ val createdAt: DateTime,
+ @SerializedName("data")
+ val data: Data,
+) {
+
+ val status
+ get() = data.case.status
+
+ fun inThread(thread: ChatThread) =
+ data.case.threadIdOnExternalPlatform == thread.id.toString()
+
+ internal data class Data(
+ @SerializedName("case")
+ val case: Case,
+ )
+
+ internal data class Case(
+ @SerializedName("threadIdOnExternalPlatform")
+ val threadIdOnExternalPlatform: String,
+ @SerializedName("status")
+ val status: CaseStatus,
+ @SerializedName("statusUpdatedAt")
+ val statusUpdatedAt: DateTime,
+ )
+
+ internal enum class CaseStatus {
+ @SerializedName("new")
+ NEW,
+
+ @SerializedName("open")
+ OPEN,
+
+ @SerializedName("pending")
+ PENDING,
+
+ @SerializedName("escalated")
+ ESCALATED,
+
+ @SerializedName("resolved")
+ RESOLVED,
+
+ /**
+ * This state is terminal.
+ */
+ @SerializedName("closed")
+ CLOSED,
+
+ @SerializedName("trashed")
+ TRASHED
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventContactInboxAssigneeChanged.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventContactInboxAssigneeChanged.kt
index c64edcce..941fd5c0 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventContactInboxAssigneeChanged.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventContactInboxAssigneeChanged.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCustomerAuthorized.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCustomerAuthorized.kt
index 185fea8a..0b5847ae 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCustomerAuthorized.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventCustomerAuthorized.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageCreated.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageCreated.kt
index 9fefd6a2..815c8791 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageCreated.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageCreated.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageReadByAgent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageReadByAgent.kt
index 523eaed0..e92c93d6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageReadByAgent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMessageReadByAgent.kt
@@ -1,7 +1,23 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
import com.nice.cxonechat.internal.model.MessageModel
+import com.nice.cxonechat.thread.ChatThread
/**
* Event received when an agent has read a message.
@@ -16,6 +32,16 @@ internal data class EventMessageReadByAgent(
val messageId get() = data.message.idOnExternalPlatform
val message get() = data.message.toMessage()
+ /**
+ * Returns `true` iff [threadId] matches the one of supplied [thread] and the [thread.messages] contain element
+ * with matching id.
+ */
+ fun inThread(thread: ChatThread): Boolean =
+ thread.id == threadId &&
+ thread.messages.any { threadMessage ->
+ threadMessage.id == messageId
+ }
+
data class Data(
@SerializedName("message")
val message: MessageModel,
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMoreMessagesLoaded.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMoreMessagesLoaded.kt
index 0e708f85..cca14af6 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMoreMessagesLoaded.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventMoreMessagesLoaded.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventProactiveAction.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventProactiveAction.kt
index 468dbc7d..69d9086f 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventProactiveAction.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventProactiveAction.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadListFetched.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadListFetched.kt
index ce5b5c99..f3fbf182 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadListFetched.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadListFetched.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadMetadataLoaded.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadMetadataLoaded.kt
index 6ed00969..e5fce17d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadMetadataLoaded.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventThreadMetadataLoaded.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventTokenRefreshed.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventTokenRefreshed.kt
index 0154d392..5d0b31a3 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventTokenRefreshed.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/EventTokenRefreshed.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Identifier.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Identifier.kt
index ecc01a4d..7aaeb308 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Identifier.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Identifier.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Journey.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Journey.kt
index 2918be33..725822b3 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Journey.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Journey.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/LegacyPayload.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/LegacyPayload.kt
index ac095765..a1763ae2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/LegacyPayload.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/LegacyPayload.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/MediaModel.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/MediaModel.kt
index 6cf8ca82..eed445fd 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/MediaModel.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/MediaModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PageViewData.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PageViewData.kt
index c11f9c59..b761eaeb 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PageViewData.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PageViewData.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Payload.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Payload.kt
index 8dc17783..ec145821 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Payload.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Payload.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PolyAction.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PolyAction.kt
index 49b2661d..ad814cc2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PolyAction.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/PolyAction.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Postback.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Postback.kt
index 855a3986..946e9d94 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Postback.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Postback.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ProactiveActionInfo.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ProactiveActionInfo.kt
index 4755a89f..f89dfdb4 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ProactiveActionInfo.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ProactiveActionInfo.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ReceivedThreadData.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ReceivedThreadData.kt
index f9897e40..ff560a85 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ReceivedThreadData.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ReceivedThreadData.kt
@@ -1,8 +1,24 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
import com.nice.cxonechat.internal.model.ChatThreadInternal
import com.nice.cxonechat.internal.model.Thread
+import com.nice.cxonechat.thread.ChatThreadState.Received
import java.util.Date
import java.util.UUID
@@ -29,6 +45,7 @@ internal data class ReceivedThreadData(
id = idOnExternalPlatform,
messages = mutableListOf(),
canAddMoreMessages = canAddMoreMessages,
- threadName = threadName
+ threadName = threadName,
+ threadState = Received,
)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Referrer.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Referrer.kt
index 37c0bbdd..ffe9491a 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Referrer.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/Referrer.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ThreadEventData.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ThreadEventData.kt
index a0b53c80..250d5e48 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ThreadEventData.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/ThreadEventData.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UTM.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UTM.kt
index 2f4d545a..a1ce9135 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UTM.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UTM.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UserStatistics.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UserStatistics.kt
index 4ee78e41..19d4ab4e 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UserStatistics.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/UserStatistics.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
@@ -14,6 +29,7 @@ internal data class UserStatistics(
) {
fun toMessageMetadata(): MessageMetadata = MessageMetadataInternal(
+ seenAt = seenAt,
readAt = readAt
)
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/VisitorEvent.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/VisitorEvent.kt
index d56a91bf..ffdf2729 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/VisitorEvent.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/VisitorEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/WrappedText.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/WrappedText.kt
index 056d380b..41bbf06b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/WrappedText.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/model/network/WrappedText.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.model.network
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/Default.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/Default.kt
index f2f2ec2d..298eb640 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/Default.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/Default.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.serializer
import com.google.gson.Gson
@@ -13,7 +28,6 @@ import com.nice.cxonechat.internal.model.network.MessagePolyContent
import com.nice.cxonechat.internal.model.network.MessagePolyElement
import com.nice.cxonechat.internal.model.network.PolyAction
import com.nice.cxonechat.util.DateTime
-import com.nice.cxonechat.util.RuntimeTypeAdapterFactory
import com.nice.cxonechat.util.timestampToDate
import com.nice.cxonechat.util.toTimestamp
import java.io.IOException
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/util/RuntimeTypeAdapterFactory.java b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/RuntimeTypeAdapterFactory.java
similarity index 99%
rename from chat-sdk-core/src/main/java/com/nice/cxonechat/util/RuntimeTypeAdapterFactory.java
rename to chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/RuntimeTypeAdapterFactory.java
index 7ec3ae6c..52f766b7 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/util/RuntimeTypeAdapterFactory.java
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/serializer/RuntimeTypeAdapterFactory.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.nice.cxonechat.util;
+package com.nice.cxonechat.internal.serializer;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@@ -143,7 +143,7 @@
* Shape shape = gson.fromJson(json, Shape.class);
* }
*/
-public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory {
+final class RuntimeTypeAdapterFactory implements TypeAdapterFactory {
private final Class> baseType;
private final String typeFieldName;
private final Map> labelToSubtype = new LinkedHashMap<>();
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ErrorCallback.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ErrorCallback.kt
new file mode 100644
index 00000000..629ee878
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ErrorCallback.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal.socket
+
+import com.nice.cxonechat.Cancellable
+import com.nice.cxonechat.enums.ErrorType
+import com.nice.cxonechat.internal.model.ErrorModel
+import com.nice.cxonechat.internal.serializer.Default.serializer
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+
+/**
+ * Simple [WebSocketListener] which attempts to deserialize [ErrorModel] from incoming messages and if the
+ * [ErrorModel.Error.errorCode] matches the supplied [errorType], the element will be passed back as [onError] callback.
+ *
+ * @param errorType The [ErrorType] which will be used for callback.
+ */
+internal abstract class ErrorCallback(
+ private val errorType: ErrorType,
+) : WebSocketListener() {
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ val errorMessage: ErrorModel? = serializer.runCatching { fromJson(text, ErrorModel::class.java) }.getOrNull()
+ if (errorMessage?.error?.errorCode == errorType) {
+ onError(webSocket)
+ }
+ }
+
+ /**
+ * Callback which is invoked when websocket receives message with [ErrorModel] which have matching
+ * [ErrorModel.Error.errorCode] to the supplied [errorType].
+ *
+ * @param webSocket [WebSocket] instance received in the [WebSocketListener.onMessage] callback.
+ */
+ abstract fun onError(webSocket: WebSocket)
+
+ internal companion object {
+
+ /**
+ * Create and register [ErrorCallback] for supplied [errorType].
+ *
+ * @receiver [ProxyWebSocketListener] which will be used for registration of the [ErrorCallback] listener.
+ * @return A [Cancellable] instance which will cancel the [ErrorCallback] registration.
+ */
+ internal inline fun ProxyWebSocketListener.addErrorCallback(
+ errorType: ErrorType,
+ crossinline callback: WebSocket.() -> Unit,
+ ): Cancellable {
+ val listener = object : ErrorCallback(errorType) {
+ override fun onError(webSocket: WebSocket) = callback(webSocket)
+ }
+ addListener(listener)
+ return Cancellable { removeListener(listener) }
+ }
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventBlueprint.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventBlueprint.kt
index b364f9fa..6eee8a55 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventBlueprint.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventBlueprint.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import com.google.gson.annotations.SerializedName
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventCallback.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventCallback.kt
index c408925c..8a6c9824 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventCallback.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventCallback.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import com.nice.cxonechat.Cancellable
@@ -12,8 +27,10 @@ internal abstract class EventCallback(
) : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
- val blueprint: EventBlueprint? = serializer.fromJson(text, EventBlueprint::class.java)
- if (blueprint?.anyType == type) {
+ val blueprint: EventBlueprint? = serializer.runCatching {
+ fromJson(text, EventBlueprint::class.java)
+ }.getOrNull()
+ if (blueprint?.anyType === type) {
val event: Event? = serializer.fromJson(text, eventType)
if (event != null) {
onEvent(webSocket, event)
@@ -23,15 +40,13 @@ internal abstract class EventCallback(
abstract fun onEvent(websocket: WebSocket, event: Event)
- companion object {
+ internal companion object {
inline operator fun invoke(
type: EventType,
crossinline callback: WebSocket.(Event) -> Unit,
) = object : EventCallback(type, Event::class.java) {
- override fun onEvent(websocket: WebSocket, event: Event) {
- callback(websocket, event)
- }
+ override fun onEvent(websocket: WebSocket, event: Event) = callback(websocket, event)
}
inline fun ProxyWebSocketListener.addCallback(
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventLogger.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventLogger.kt
index c03e16f4..265b7b84 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventLogger.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/EventLogger.kt
@@ -1,10 +1,25 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import com.nice.cxonechat.log.Logger
import com.nice.cxonechat.log.LoggerScope
-import com.nice.cxonechat.log.finer
-import com.nice.cxonechat.log.finest
+import com.nice.cxonechat.log.debug
import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
@@ -14,17 +29,17 @@ internal class EventLogger(
) : WebSocketListener(), LoggerScope by LoggerScope(logger) {
init {
- finest("Registered dispatch listener")
+ verbose("Registered dispatch listener")
}
override fun onMessage(
webSocket: WebSocket,
text: String,
) = scope("onMessage") {
- finest(text)
+ verbose(text)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) = scope("onFailure") {
- finer("Response: $response", t)
+ debug("Response: $response", t)
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ProxyWebSocketListener.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ProxyWebSocketListener.kt
index ed0af332..42c75a73 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ProxyWebSocketListener.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/ProxyWebSocketListener.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import okhttp3.Response
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactory.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactory.kt
index 8e71fd80..81cc0e95 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactory.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactory.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import androidx.annotation.WorkerThread
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactoryDefault.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactoryDefault.kt
index 69920db7..60f1ff13 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactoryDefault.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/SocketFactoryDefault.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import com.nice.cxonechat.SocketFactoryConfiguration
@@ -25,6 +40,7 @@ internal class SocketFactoryDefault(
append("&channelId=${config.channelId}")
append("&applicationType=native")
append("&os=Android")
+ @Suppress("DEPRECATION")
append("&clientVersion=${config.version}")
}
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/StateReportingSocketFactory.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/StateReportingSocketFactory.kt
index 3f737164..830fb7ab 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/StateReportingSocketFactory.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/StateReportingSocketFactory.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
import com.nice.cxonechat.ChatStateListener
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebSocketSpec.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebSocketSpec.kt
index 6950dab6..3ba77520 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebSocketSpec.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebSocketSpec.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.internal.socket
/**
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebsocketLogging.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebsocketLogging.kt
new file mode 100644
index 00000000..45c3bf66
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/internal/socket/WebsocketLogging.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.internal.socket
+
+import com.nice.cxonechat.log.Logger
+import com.nice.cxonechat.log.LoggerScope
+import com.nice.cxonechat.log.scope
+import com.nice.cxonechat.log.verbose
+import okhttp3.WebSocket
+
+/**
+ * [LoggerScope] for [WebSocket], which logs text of messages sent via [send].
+ * Also logs calls to [close].
+ *
+ * @param socket The wrapped [WebSocket].
+ * @param logger Base for the [LoggerScope] used by this implementation.
+ */
+internal class WebsocketLogging(
+ private val socket: WebSocket,
+ logger: Logger,
+) : WebSocket by socket, LoggerScope by LoggerScope(logger) {
+ override fun send(text: String): Boolean = scope("send") {
+ verbose(text)
+ socket.send(text)
+ }
+
+ override fun close(code: Int, reason: String?): Boolean = scope("close") {
+ socket.close(code, reason)
+ }
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/Level.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/log/Level.kt
deleted file mode 100644
index 919646e0..00000000
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/Level.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.nice.cxonechat.log
-
-/**
- * Logging level.
- */
-sealed class Level {
-
- /** Integer representation of a given level. */
- abstract val intValue: Int
-
- /** Compares itself to [other] level for convenience. */
- operator fun compareTo(other: Level): Int = intValue.compareTo(other.intValue)
-
- /** Severe level corresponds to integer value of 1000. */
- object Severe : Level() {
- override val intValue: Int
- get() = 1000
- }
-
- /** Warning level corresponds to integer value of 900. */
- object Warning : Level() {
- override val intValue: Int
- get() = 900
- }
-
- /** Info level corresponds to integer value of 800. */
- object Info : Level() {
- override val intValue: Int
- get() = 800
- }
-
- /** Config level corresponds to integer value of 700. */
- object Config : Level() {
- override val intValue: Int
- get() = 700
- }
-
- /** Fine level corresponds to integer value of 500. */
- object Fine : Level() {
- override val intValue: Int
- get() = 500
- }
-
- /** Finer level corresponds to integer value of 400. */
- object Finer : Level() {
- override val intValue: Int
- get() = 400
- }
-
- /** Finest level corresponds to integer value of 300. */
- object Finest : Level() {
- override val intValue: Int
- get() = 300
- }
-
- /**
- * All level corresponds to integer value of [Int.MIN_VALUE].
- * Note that this option may not be supported by all Logger
- * implementations.
- * */
- object All : Level() {
- override val intValue: Int
- get() = Int.MIN_VALUE
- }
-
- /**
- * Custom level allows you to specify your own values and
- * store them statically.
- * */
- class Custom(
- override val intValue: Int,
- ) : Level()
-}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerExt.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerExt.kt
deleted file mode 100644
index 39e1e0fe..00000000
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerExt.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.nice.cxonechat.log
-
-import kotlin.time.ExperimentalTime
-import kotlin.time.measureTimedValue
-
-internal fun Logger.finest(message: String, throwable: Throwable? = null) {
- log(Level.Finest, message, throwable)
-}
-
-internal fun Logger.finer(message: String, throwable: Throwable? = null) {
- log(Level.Finer, message, throwable)
-}
-
-internal fun Logger.fine(message: String, throwable: Throwable? = null) {
- log(Level.Fine, message, throwable)
-}
-
-internal fun Logger.info(message: String, throwable: Throwable? = null) {
- log(Level.Info, message, throwable)
-}
-
-internal fun Logger.warning(message: String, throwable: Throwable? = null) {
- log(Level.Warning, message, throwable)
-}
-
-internal fun Logger.severe(message: String, throwable: Throwable? = null) {
- log(Level.Severe, message, throwable)
-}
-
-@OptIn(ExperimentalTime::class)
-internal inline fun Logger.duration(body: () -> T): T {
- finest("Started")
- val (value, duration) = measureTimedValue(body)
- finest("Finished" took duration)
- return value
-}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerNoop.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerNoop.kt
deleted file mode 100644
index 3befc98a..00000000
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerNoop.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.nice.cxonechat.log
-
-internal object LoggerNoop : Logger {
-
- override fun log(level: Level, message: String, throwable: Throwable?) {
- /* no-op */
- }
-}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerScope.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerScope.kt
deleted file mode 100644
index 50f03c50..00000000
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/log/LoggerScope.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.nice.cxonechat.log
-
-import kotlin.time.Duration
-import kotlin.time.DurationUnit.MILLISECONDS
-
-internal interface LoggerScope : Logger {
-
- val scope: String
- val identity: Logger
-
- companion object {
-
- operator fun invoke(name: String, identity: Logger): LoggerScope = NamedScope(scope = name, identity = identity)
-
- inline operator fun invoke(identity: Logger) =
- LoggerScope(T::class.java.simpleName, identity)
- }
-}
-
-private class NamedScope(
- override val scope: String,
- override val identity: Logger,
-) : LoggerScope {
-
- override fun log(level: Level, message: String, throwable: Throwable?) {
- identity.log(level, "[$scope] $message", throwable)
- }
-}
-
-internal infix fun String.took(duration: Duration) =
- "$this took ${duration.toDouble(MILLISECONDS)}ms"
-
-internal inline fun LoggerScope.scope(name: String, body: LoggerScope.() -> T): T =
- body(LoggerScope("$scope/$name", identity))
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Action.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Action.kt
index 49939be4..e52190f2 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Action.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Action.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.message
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/ContentDescriptor.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/ContentDescriptor.kt
index fcd0ad95..fa43442d 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/ContentDescriptor.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/ContentDescriptor.kt
@@ -38,16 +38,14 @@ interface ContentDescriptor {
*
* @property bytes actual content
*/
- class Bytes internal constructor(val bytes: ByteArray): DataSource() {
+ internal class Bytes(val bytes: ByteArray) : DataSource() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Bytes
- if (!bytes.contentEquals(other.bytes)) return false
-
- return true
+ return bytes.contentEquals(other.bytes)
}
override fun hashCode(): Int = bytes.contentHashCode()
@@ -61,9 +59,9 @@ interface ContentDescriptor {
* @property uri original uri of content
* @property context Android context to be used to open the [uri]
*/
- class Uri internal constructor(
+ internal class Uri(
val uri: android.net.Uri,
- val context: Context
+ val context: Context,
): DataSource() {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -71,9 +69,7 @@ interface ContentDescriptor {
other as Uri
- if (uri != other.uri) return false
-
- return true
+ return uri == other.uri
}
override fun hashCode(): Int = uri.hashCode()
@@ -92,14 +88,15 @@ interface ContentDescriptor {
* It's required to properly deserialize the file after upload.
*
* Visit [IANA](https://www.iana.org/) for valid mime types
- * */
- val mimeType: String?
+ */
+ val mimeType: String
/**
* Name of provided in [content].
* Should contain the file name extension corresponding to the [mimeType].
- * */
- val fileName: String?
+ * Note: Either [mimeType] *must* be specified or [fileName] must include a valid extension.
+ */
+ val fileName: String
/**
* Friendly name provided in [content].
@@ -124,9 +121,9 @@ interface ContentDescriptor {
operator fun invoke(
content: android.net.Uri,
context: Context,
- mimeType: String?,
- fileName: String?,
- friendlyName: String?
+ mimeType: String,
+ fileName: String,
+ friendlyName: String? = null
): ContentDescriptor = ContentDescriptorInternal(
content = DataSource.Uri(content, context),
mimeType = mimeType,
@@ -146,8 +143,8 @@ interface ContentDescriptor {
@JvmName("create")
operator fun invoke(
content: ByteArray,
- mimeType: String?,
- fileName: String?,
+ mimeType: String,
+ fileName: String,
friendlyName: String?
): ContentDescriptor = ContentDescriptorInternal(
content = DataSource.Bytes(content),
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Media.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Media.kt
index 6f966335..6c6426b1 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Media.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Media.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.message
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Message.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Message.kt
index 37366566..dd84084a 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Message.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/Message.kt
@@ -38,27 +38,27 @@ sealed class Message {
/**
* The id that was assigned to this message.
* If another message has matching id, it's the same message with possibly different content.
- * */
+ */
abstract val id: UUID
/**
* The thread id that this message belongs to. Messages should never be
* mismatched between threads as this can lead to inconsistencies and
* undefined behavior.
- * */
+ */
abstract val threadId: UUID
/**
* The timestamp of when the message was created on the server. Similarly
* to [id] this field shouldn't change for the lifetime of the message.
- * */
+ */
abstract val createdAt: Date
/**
* The direction in which the message is sent.
*
* @see MessageDirection
- * */
+ */
abstract val direction: MessageDirection
/**
@@ -66,15 +66,18 @@ sealed class Message {
* contain anything from message status to custom properties.
*
* @see MessageMetadata
- * */
+ */
abstract val metadata: MessageMetadata
/**
* Author associated with this message.
*
+ * *Note:* Under some circumstances the author name may be unknown and [author] will be null.
+ * The UI can provide a suitable localized fallback based on [direction].
+ *
* @see MessageAuthor
- * */
- abstract val author: MessageAuthor
+ */
+ abstract val author: MessageAuthor?
/**
* Attachments provided with the message. This field can be empty.
@@ -84,7 +87,7 @@ sealed class Message {
* Never make any assumption on the implemented type of the [Iterable].
*
* @see ChatThreadMessageHandler.send
- * */
+ */
abstract val attachments: Iterable
/**
@@ -97,7 +100,7 @@ sealed class Message {
/**
* Simple message representing only text content. This type of content
* is usually generated through User or Agent replying to each other.
- * */
+ */
@Public
abstract class Text : Message() {
@@ -109,7 +112,7 @@ sealed class Message {
* characters out of scope for your current device (typically emojis
* or unsupported characters from some languages). Use support
* libraries to display them, if applicable.
- * */
+ */
abstract val text: String
}
@@ -120,14 +123,14 @@ sealed class Message {
* required by your own specification. Note that new elements can be added
* to the backend services for which you need to update the SDK. New
* elements, previously undefined are ignored by the SDK until implemented.
- * */
+ */
@Public
abstract class Plugin : Message() {
/**
* Additional information provided alongside with the message. Refer to
* information given by a representative to correctly use this parameter.
- * */
+ */
abstract val postback: String?
/**
@@ -136,7 +139,7 @@ sealed class Message {
* this version. Kindly update the SDK in order to gain support.
*
* @see PluginElement
- * */
+ */
abstract val element: PluginElement?
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageDirection.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageDirection.kt
index 53d14236..4e0bb56b 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageDirection.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageDirection.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.message
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageMetadata.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageMetadata.kt
index 85c148bf..d6804927 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageMetadata.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageMetadata.kt
@@ -23,9 +23,19 @@ import java.util.Date
* */
@Public
interface MessageMetadata {
+ /**
+ * The date at which the message was seen (delivered) on backend.
+ * Default to null if the message is freshly sent by the SDK, always non-null
+ * if the message is delivered.
+ */
+ val seenAt: Date?
+
/**
* The date at which the message was read.
* Defaults to null if the message is freshly sent or delivered.
* */
val readAt: Date?
+
+ /** Inferred status of message. */
+ val status: MessageStatus
}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageStatus.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageStatus.kt
new file mode 100644
index 00000000..ae4252b1
--- /dev/null
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/MessageStatus.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
+package com.nice.cxonechat.message
+
+import com.nice.cxonechat.Public
+
+/**
+ * Enumeration of possible message states, including those not reported by the SDK.
+ */
+@Public
+enum class MessageStatus {
+ /**
+ * Status which can be used by UI implementation, for message passed to SDK, but not yet confirmed
+ * as [SENT].
+ */
+ SENDING,
+
+ /** Default state of message when it has been processed by the SDK and sent to backend. */
+ SENT,
+
+ /** Status which can be used by UI implementation. */
+ FAILED_TO_DELIVER,
+
+ /** Status reported when the message is reported as delivered/seen on backend. */
+ SEEN,
+
+ /** Status reported when the message is reported as read. */
+ READ,
+}
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/OutboundMessage.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/OutboundMessage.kt
index fb209c53..aa40edac 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/OutboundMessage.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/OutboundMessage.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.message
import com.nice.cxonechat.Public
diff --git a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/PluginElement.kt b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/PluginElement.kt
index 6f76b18e..cf13df10 100644
--- a/chat-sdk-core/src/main/java/com/nice/cxonechat/message/PluginElement.kt
+++ b/chat-sdk-core/src/main/java/com/nice/cxonechat/message/PluginElement.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2021-2023. NICE Ltd. All rights reserved.
+ *
+ * Licensed under the NICE License;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://github.com/nice-devone/nice-cxone-mobile-sdk-android/blob/main/LICENSE
+ *
+ * TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE CXONE MOBILE SDK IS PROVIDED ON
+ * AN “AS IS” BASIS. NICE HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
+ * OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+ */
+
package com.nice.cxonechat.message
import com.nice.cxonechat.Public
@@ -25,7 +40,7 @@ import java.util.Date
* can extract properties defined by your company or representative.
*
* @see Message.Plugin
- * */
+ */
@Public
sealed class PluginElement {
@@ -34,7 +49,7 @@ sealed class PluginElement {
* These elements are highly variable and there's no guarantee that all
* of the elements will be present at any given time. Though at least one
* element should be present at any given time.
- * */
+ */
@Public
abstract class Menu : PluginElement() {
/**
@@ -45,7 +60,7 @@ sealed class PluginElement {
* then iterable returns no elements.
*
* @see File
- * */
+ */
abstract val files: Iterable
/**
@@ -56,7 +71,7 @@ sealed class PluginElement {
* then iterable returns no elements.
*
* @see Title
- * */
+ */
abstract val titles: Iterable
/**
@@ -68,7 +83,7 @@ sealed class PluginElement {
* then iterable returns no elements.
*
* @see Subtitle
- * */
+ */
abstract val subtitles: Iterable
/**
@@ -79,7 +94,7 @@ sealed class PluginElement {
* then iterable returns no elements.
*
* @see Text
- * */
+ */
abstract val texts: Iterable
/**
@@ -91,7 +106,7 @@ sealed class PluginElement {
* then iterable returns no elements.
*
* @see Button
- * */
+ */
abstract val buttons: Iterable