diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..fd45b12
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches/build_file_checksums.ser
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
new file mode 100755
index 0000000..f8dbc1f
--- /dev/null
+++ b/.idea/assetWizardSettings.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100755
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100755
index 0000000..7ac24c7
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100755
index 0000000..703e5d4
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100755
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100755
index 0000000..288b36b
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..6870378
--- /dev/null
+++ b/README.md
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+CometChat Android Demo app (built using **CometChat Pro**) is a fully functional messaging app capable of **one-on-one** (private) and **group** messaging. The app enables users to send **text** and **multimedia messages like audio, video, images, documents.**
+
+[](#) [](#)
+
+## Table of Contents
+
+1. [Screenshots ](#screenshots)
+
+2. [Installation ](#installtion)
+
+3. [Run the Sample App ](#run-the-sample-app)
+
+4. [Customizing the UI](#customizing-the-ui)
+
+5. [Integrating this sample into your own app](#integrating-this-sample-into-your-own-app)
+
+5. [Contribute](#contribute)
+
+
+
+## ScreenShots
+
+
+
+## Installtion
+
+ Simply Clone the project from android-kotlin-chat-app repository and open in Android Studio.
+ Build the Demo App and it will be ready to Run
+
+
+
+
+## Run the Sample App
+
+
+
+ To Run to sample App you have to do the following changes by Adding **ApiKey** and **AppId**
+
+ - Open the Project in Android Mode in Android Studio
+
+ - Go to Under java --> com\inscripts\cometchatpulse--> StringContract
+
+ - Under class `StringContract.kt` go to `class` named `AppDetails`
+
+ - modify *APP_ID* and *API_KEY* with your own **ApiKey** and **AppId**
+
+ `val APP_ID: String = "XXXXXXXXX"`
+
+ `val API_KEY: String = "XXXXXXXXX"`
+
+## Note
+
+ You can Obtain your *APP_ID* and *API_KEY* from [CometChat-Pulse Dashboard](https://app.cometchat.com/)
+
+ For more information read [CometChat-Pro Android SDK](https://prodocs.cometchat.com/docs/android-quick-start) Documentation
+
+
+
+
+ 
+
+ ## Customizing the UI
+
+ We have provided three themes with our sample app namely **PersianBlue, MountainMeadow, AzureRadiance**. To apply the themes:
+
+ - Go to `Application` class `CometChatPro`
+
+ - Create constructor of class `Appearance` and pass any of these three values
+
+ 1.PERSIAN_BLUE
+
+ 2.MOUNTAIN_MEADOW
+
+ 3.AZURE_RADIANCE
+
+ example `Appearance(Appearance.AppTheme.PERSIAN_BLUE)`
+
+ To make your custom appearance go to `Appearance` class under package named Utils i.e
+
+ Go to Under java --> com\inscripts\cometchatpulse--> Utils--> Appearance
+
+
+
+
+
+
+## Integrating this sample into your own app
+ Copy sample app in your project
+
+ remove login and add your own authentication method
+
+ launch `MainActivity` and start using the app
+
+## Contribute
+
+
+ Feel free to make Pull Request.
+
diff --git a/ScreenShot/Screenshot_20190121-135306_CometChat Pro.jpg b/ScreenShot/Screenshot_20190121-135306_CometChat Pro.jpg
new file mode 100755
index 0000000..57c3145
Binary files /dev/null and b/ScreenShot/Screenshot_20190121-135306_CometChat Pro.jpg differ
diff --git a/ScreenShot/Screenshot_20190121-135314_CometChat Pro.jpg b/ScreenShot/Screenshot_20190121-135314_CometChat Pro.jpg
new file mode 100755
index 0000000..7ca7bf3
Binary files /dev/null and b/ScreenShot/Screenshot_20190121-135314_CometChat Pro.jpg differ
diff --git a/ScreenShot/Screenshot_20190121-135330_CometChat Pro.jpg b/ScreenShot/Screenshot_20190121-135330_CometChat Pro.jpg
new file mode 100755
index 0000000..fe20001
Binary files /dev/null and b/ScreenShot/Screenshot_20190121-135330_CometChat Pro.jpg differ
diff --git a/ScreenShot/Screenshot_20190121-142043_CometChat Pro.jpg b/ScreenShot/Screenshot_20190121-142043_CometChat Pro.jpg
new file mode 100755
index 0000000..ab11da4
Binary files /dev/null and b/ScreenShot/Screenshot_20190121-142043_CometChat Pro.jpg differ
diff --git a/ScreenShot/gib.gif b/ScreenShot/gib.gif
new file mode 100755
index 0000000..c5bb3a8
Binary files /dev/null and b/ScreenShot/gib.gif differ
diff --git a/ScreenShot/guide.png b/ScreenShot/guide.png
new file mode 100755
index 0000000..46fd214
Binary files /dev/null and b/ScreenShot/guide.png differ
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100755
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100755
index 0000000..6df34ed
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,99 @@
+apply plugin: 'com.android.application'
+
+apply plugin: 'kotlin-android'
+
+apply plugin: 'kotlin-android-extensions'
+
+apply plugin: 'kotlin-kapt'
+
+
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.inscripts.cometchatpulse"
+ minSdkVersion 21
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ ndk {
+ abiFilters "armeabi-v7a", "x86"
+ }
+
+// packagingOptions {
+// exclude "lib/arm64-v8a/libgnustl_shared.so"
+// }
+
+ }
+ dataBinding {
+ enabled = true
+ }
+
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.google.android.gms:play-services-maps:16.0.0'
+ compile 'com.google.android.gms:play-services-places:16.0.0'
+// compile 'com.google.android.gms:play-services:12.0.1'
+ compile 'com.google.android.gms:play-services-location:16.0.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+
+ implementation 'com.android.support:design:28.0.0'
+ implementation 'com.android.support:support-v4:28.0.0'
+ implementation 'com.android.support:recyclerview-v7:28.0.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.android.support:cardview-v7:28.0.0'
+ implementation 'com.android.support:support-emoji-appcompat:28.0.0'
+ implementation 'com.android.support:support-annotations:28.0.0'
+
+ implementation 'com.github.bumptech.glide:glide:4.8.0'
+
+ annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
+
+ // ViewModel and LiveData
+ implementation "android.arch.lifecycle:extensions:1.1.1"
+
+
+ kapt "android.arch.lifecycle:compiler:1.1.1"
+
+
+ //cometchat sdk
+ implementation 'com.cometchat:pro-android-chat-sdk:1.2.0'
+
+
+ implementation 'com.google.firebase:firebase-core:16.+'
+
+ implementation 'com.google.firebase:firebase-messaging:17.3.4'
+
+ implementation 'com.facebook.shimmer:shimmer:0.4.0'
+
+
+ api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0"
+ api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0"
+
+
+}
+apply plugin: 'com.google.gms.google-services'
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100755
index 0000000..e51d617
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,55 @@
+{
+ "project_info": {
+ "project_number": "122431658736",
+ "firebase_url": "https://pro-demo-229414.firebaseio.com",
+ "project_id": "pro-demo-229414",
+ "storage_bucket": "pro-demo-229414.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:122431658736:android:9701feb58d0de92f",
+ "android_client_info": {
+ "package_name": "com.inscripts.cometchatpulse"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "122431658736-850hjj22tfu85s0kskhvgbaej5ajoi0k.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.inscripts.cometchatpulse",
+ "certificate_hash": "b7ac951dadc69f508d5964100060ac97e6dfd595"
+ }
+ },
+ {
+ "client_id": "122431658736-ab8npvt0hi9kb3fphce4v3546j5eq8m5.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyBZQBGyUgawKhekPGvys_KQzKBDpcJE3BE"
+ }
+ ],
+ "services": {
+ "analytics_service": {
+ "status": 1
+ },
+ "appinvite_service": {
+ "status": 2,
+ "other_platform_oauth_client": [
+ {
+ "client_id": "122431658736-ab8npvt0hi9kb3fphce4v3546j5eq8m5.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ },
+ "ads_service": {
+ "status": 2
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100755
index 0000000..308344d
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,24 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+
+# ServiceLoader support
+-keepnames class kotlinx.** { *; }
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/inscripts/cometchatpulse/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/inscripts/cometchatpulse/ExampleInstrumentedTest.kt
new file mode 100755
index 0000000..7fb69e6
--- /dev/null
+++ b/app/src/androidTest/java/com/inscripts/cometchatpulse/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.inscripts.cometchatpulse
+
+import android.support.test.InstrumentationRegistry
+import android.support.test.runner.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getTargetContext()
+ assertEquals("com.inscripts.cometchatpulse", appContext.packageName)
+ }
+}
diff --git a/app/src/debug/res/values/google_maps_api.xml b/app/src/debug/res/values/google_maps_api.xml
new file mode 100755
index 0000000..4b23a1f
--- /dev/null
+++ b/app/src/debug/res/values/google_maps_api.xml
@@ -0,0 +1,24 @@
+
+
+ AIzaSyCFV_G9O00VZ61EFqun4y_l3XJq9KUcAXQ
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100755
index 0000000..5fd0fe9
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/assets/Avenir_Next.ttf b/app/src/main/assets/Avenir_Next.ttf
new file mode 100755
index 0000000..a059a49
Binary files /dev/null and b/app/src/main/assets/Avenir_Next.ttf differ
diff --git a/app/src/main/assets/GoogleSans-Bold.ttf b/app/src/main/assets/GoogleSans-Bold.ttf
new file mode 100755
index 0000000..8049766
Binary files /dev/null and b/app/src/main/assets/GoogleSans-Bold.ttf differ
diff --git a/app/src/main/assets/GoogleSans-Medium.ttf b/app/src/main/assets/GoogleSans-Medium.ttf
new file mode 100755
index 0000000..1543660
Binary files /dev/null and b/app/src/main/assets/GoogleSans-Medium.ttf differ
diff --git a/app/src/main/assets/GoogleSans-Regular.ttf b/app/src/main/assets/GoogleSans-Regular.ttf
new file mode 100755
index 0000000..ab605f9
Binary files /dev/null and b/app/src/main/assets/GoogleSans-Regular.ttf differ
diff --git a/app/src/main/assets/HelveticaNeueBold.ttf b/app/src/main/assets/HelveticaNeueBold.ttf
new file mode 100755
index 0000000..a918901
Binary files /dev/null and b/app/src/main/assets/HelveticaNeueBold.ttf differ
diff --git a/app/src/main/assets/HelveticaNeueItalic.ttf b/app/src/main/assets/HelveticaNeueItalic.ttf
new file mode 100755
index 0000000..6830ffc
Binary files /dev/null and b/app/src/main/assets/HelveticaNeueItalic.ttf differ
diff --git a/app/src/main/assets/HelveticaNeueMedium.ttf b/app/src/main/assets/HelveticaNeueMedium.ttf
new file mode 100755
index 0000000..9a1e4cf
Binary files /dev/null and b/app/src/main/assets/HelveticaNeueMedium.ttf differ
diff --git a/app/src/main/assets/OpenSans-Regular.ttf b/app/src/main/assets/OpenSans-Regular.ttf
new file mode 100755
index 0000000..db43334
Binary files /dev/null and b/app/src/main/assets/OpenSans-Regular.ttf differ
diff --git a/app/src/main/assets/Product Sans Bold.ttf b/app/src/main/assets/Product Sans Bold.ttf
new file mode 100755
index 0000000..d847195
Binary files /dev/null and b/app/src/main/assets/Product Sans Bold.ttf differ
diff --git a/app/src/main/assets/Product Sans Italic.ttf b/app/src/main/assets/Product Sans Italic.ttf
new file mode 100755
index 0000000..5fc56d4
Binary files /dev/null and b/app/src/main/assets/Product Sans Italic.ttf differ
diff --git a/app/src/main/assets/Product Sans Regular.ttf b/app/src/main/assets/Product Sans Regular.ttf
new file mode 100755
index 0000000..c0442ee
Binary files /dev/null and b/app/src/main/assets/Product Sans Regular.ttf differ
diff --git a/app/src/main/assets/Roboto-Medium.ttf b/app/src/main/assets/Roboto-Medium.ttf
new file mode 100755
index 0000000..6a95133
Binary files /dev/null and b/app/src/main/assets/Roboto-Medium.ttf differ
diff --git a/app/src/main/assets/Roboto-Regular.ttf b/app/src/main/assets/Roboto-Regular.ttf
new file mode 100755
index 0000000..ddee473
Binary files /dev/null and b/app/src/main/assets/Roboto-Regular.ttf differ
diff --git a/app/src/main/assets/RobotoCondensed-Regular.ttf b/app/src/main/assets/RobotoCondensed-Regular.ttf
new file mode 100755
index 0000000..f0d3a81
Binary files /dev/null and b/app/src/main/assets/RobotoCondensed-Regular.ttf differ
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/CallActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/CallActivity.kt
new file mode 100755
index 0000000..2a4d9a6
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/CallActivity.kt
@@ -0,0 +1,163 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.app.Activity
+import android.arch.lifecycle.ViewModelProviders
+import android.content.pm.PackageManager
+import android.databinding.DataBindingUtil
+import android.media.RingtoneManager
+import android.net.Uri
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.view.View
+import android.widget.RelativeLayout
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.inscripts.cometchatpulse.Repository.MessageRepository
+import com.inscripts.cometchatpulse.Helpers.CCPermissionHelper
+import com.inscripts.cometchatpulse.Helpers.CometChatAudioHelper
+import com.inscripts.cometchatpulse.Helpers.OutgoingAudioHelper
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.OnetoOneViewModel
+import com.inscripts.cometchatpulse.databinding.ActivityCallBinding
+import java.lang.NullPointerException
+
+class CallActivity : AppCompatActivity(), View.OnClickListener {
+
+ private lateinit var name: String
+
+ private lateinit var id: String
+
+ lateinit var binding: ActivityCallBinding
+
+ private var imageUrl: String? = null
+
+ private var cometChatAudioHelper: CometChatAudioHelper? = null
+
+ private lateinit var sessionID: String
+
+ private lateinit var onetoOneViewModel: OnetoOneViewModel
+
+ private lateinit var notification: Uri
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_call)
+
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_call)
+ CommonUtil.setStatusBarColor(this)
+ cometChatAudioHelper = CometChatAudioHelper(this)
+ cometChatAudioHelper?.initAudio()
+ notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
+ onetoOneViewModel = ViewModelProviders.of(this).get(OnetoOneViewModel::class.java)
+
+ try {
+
+
+ if (intent?.action?.equals(CometChatConstants.CALL_TYPE_VIDEO)!!) {
+ if (!CCPermissionHelper.hasPermissions(this, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+ CCPermissionHelper.requestPermissions(this, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VIDEO_CALL)
+ }
+
+ } else if (intent?.action.equals(CometChatConstants.CALL_TYPE_AUDIO)) {
+ if (!CCPermissionHelper.hasPermissions(this, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ CCPermissionHelper.requestPermissions(this, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VOICE_CALL)
+ }
+ }
+ } catch (e: NullPointerException) {
+ e.printStackTrace()
+ }
+
+ if (intent.hasExtra(StringContract.IntentString.RECIVER_TYPE)) {
+
+ if (intent.getStringExtra(StringContract.IntentString.RECIVER_TYPE).equals(CometChatConstants.RECEIVER_TYPE_GROUP)) {
+
+ name = intent.getStringExtra(StringContract.IntentString.GROUP_NAME)
+ id = intent.getStringExtra(StringContract.IntentString.GROUP_ID)
+ imageUrl = intent?.getStringExtra(StringContract.IntentString.GROUP_ICON)
+ } else {
+ name = intent.getStringExtra(StringContract.IntentString.USER_NAME)
+ id = intent.getStringExtra(StringContract.IntentString.USER_ID)
+ imageUrl = intent?.getStringExtra(StringContract.IntentString.USER_AVATAR)
+ }
+ }
+
+ if (intent?.type.equals(StringContract.IntentString.INCOMING)) {
+ binding.tvCallText.setText("Incoming call...")
+ cometChatAudioHelper?.startIncomingAudio(notification, true)
+ } else if (intent?.type.equals(StringContract.IntentString.OUTGOING)) {
+ cometChatAudioHelper?.startOutgoingAudio(OutgoingAudioHelper.Type.IN_COMMUNICATION)
+ val rl = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
+ RelativeLayout.LayoutParams.WRAP_CONTENT)
+
+ rl.addRule(RelativeLayout.CENTER_HORIZONTAL)
+ rl.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
+ rl.bottomMargin = 56
+
+ binding.hangUp.layoutParams = rl
+ binding.acceptCall.visibility = View.GONE
+ binding.tvCallText.setText("Ringing...")
+ }
+
+ binding.name = name
+ binding.image = imageUrl
+
+ binding.acceptCall.setOnClickListener(this)
+ binding.hangUp.setOnClickListener(this)
+
+ sessionID = intent.getStringExtra(StringContract.IntentString.SESSION_ID)
+
+
+ }
+
+ override fun onStart() {
+ super.onStart()
+ onetoOneViewModel.addCallListener(this@CallActivity, StringContract.ListenerName.CALL_EVENT_LISTENER, binding.mainCallView)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ onetoOneViewModel.removeCallListener(StringContract.ListenerName.CALL_EVENT_LISTENER)
+ cometChatAudioHelper?.stop(false)
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+
+ when (requestCode) {
+
+ StringContract.RequestCode.VOICE_CALL -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED) {
+
+ } else {
+ Toast.makeText(this, "Voice call will behave inappropriately ", Toast.LENGTH_SHORT).show()
+ }
+ StringContract.RequestCode.VIDEO_CALL -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+ } else {
+ Toast.makeText(this, "Video call will behave inappropriately ", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ override fun onClick(p0: View?) {
+
+ when (p0?.id) {
+
+ R.id.acceptCall -> {
+ cometChatAudioHelper?.stop(false)
+ onetoOneViewModel.acceptCall(sessionID, binding.mainCallView, this@CallActivity)
+ }
+
+ R.id.hangUp -> {
+ cometChatAudioHelper?.stop(true)
+ onetoOneViewModel.rejectCall(sessionID, CometChatConstants.CALL_STATUS_REJECTED, this@CallActivity)
+ }
+
+ }
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/CreateGroupActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/CreateGroupActivity.kt
new file mode 100755
index 0000000..3ab6c7a
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/CreateGroupActivity.kt
@@ -0,0 +1,206 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.arch.lifecycle.ViewModelProviders
+import android.databinding.DataBindingUtil
+import android.graphics.PorterDuff
+import android.graphics.Typeface
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.widget.AdapterView
+import android.widget.ArrayAdapter
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.models.Group
+import com.inscripts.cometchatpulse.Extensions.setTitleTypeface
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupChatViewModel
+import com.inscripts.cometchatpulse.ViewModel.GroupViewModel
+import com.inscripts.cometchatpulse.databinding.ActivityCreateGroupBinding
+
+
+class CreateGroupActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
+
+
+ private lateinit var binding: ActivityCreateGroupBinding
+
+ private var groupType: String? = null
+
+ private var guid: String? = null
+
+ private var groupDescription:String?=null
+
+ private var groupName: String? = null
+
+ private var groupPassword: String? = null
+
+ private lateinit var groupViewModel:GroupViewModel
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_create_group)
+
+ setSupportActionBar(binding.createGroupToolbar)
+ supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+
+ supportActionBar?.title="Create Group"
+
+ CommonUtil.setStatusBarColor(this)
+
+ binding.createGroupToolbar.setTitleTypeface(StringContract.Font.title)
+
+
+ CommonUtil.setStatusBarColor(this)
+
+ if (StringContract.AppDetails.theme==Appearance.AppTheme.AZURE_RADIANCE){
+ binding.createGroupToolbar.setTitleTextColor(StringContract.Color.black)
+ }
+ else {
+ binding.createGroupToolbar.setTitleTextColor(StringContract.Color.white)
+ }
+
+ binding.createGroupToolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+ binding.createGroupToolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint,PorterDuff.Mode.SRC_ATOP)
+
+ binding.spinner.onItemSelectedListener = this
+
+
+ groupViewModel=ViewModelProviders.of(this).get(GroupViewModel::class.java)
+
+ val adapter = ArrayAdapter.createFromResource(this,
+ R.array.group_type, android.R.layout.simple_spinner_item)
+
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
+ binding.spinner.setAdapter(adapter)
+ binding.editTextGuid.addTextChangedListener(guidWatcher)
+ binding.editTextPassword.addTextChangedListener(passwordWatcher)
+
+ //typeface
+ binding.tvName.typeface=StringContract.Font.status
+ binding.tvGuid.typeface=StringContract.Font.status
+ binding.tvDescription.typeface=StringContract.Font.status
+ binding.tvType.typeface=StringContract.Font.status
+
+ binding.editTextDescription.typeface=StringContract.Font.name
+ binding.editTextPassword.typeface=StringContract.Font.name
+ binding.editTextName.typeface=StringContract.Font.name
+ binding.editTextGuid.typeface=StringContract.Font.name
+
+
+ }
+
+ val guidWatcher:TextWatcher=object :TextWatcher{
+ override fun afterTextChanged(p0: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
+
+ }
+
+ override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
+ binding.editTextGuid.setError(null)
+ }
+
+ }
+
+ val passwordWatcher:TextWatcher=object :TextWatcher{
+ override fun afterTextChanged(p0: Editable?) {
+
+ }
+
+ override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
+
+ }
+
+ override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
+ binding.editTextPassword.setError(null)
+ }
+
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+
+ menuInflater.inflate(R.menu.create_menu, menu)
+
+ return super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ if (item?.itemId == R.id.menu_create_group) {
+ guid = binding.editTextGuid.text?.toString()?.trim()
+ groupPassword = binding.editTextPassword.text?.toString()?.trim()
+ groupDescription=binding.editTextDescription.text?.toString()?.trim()
+ groupName = binding.editTextName.text?.toString()?.trim()
+
+ if (guid.isNullOrEmpty()) {
+ binding.editTextGuid.setError("GUID can't be empty")
+
+ }
+ else if (groupType?.equals(CometChatConstants.GROUP_TYPE_PASSWORD, ignoreCase = true)!!
+ && groupPassword.isNullOrEmpty()) {
+ binding.editTextPassword.setError("Password is mandatory")
+
+ }
+ else if (groupType?.equals("Select Group Type",ignoreCase = true)!!)
+ {
+ Toast.makeText(this,"Please select group type",Toast.LENGTH_SHORT).show()
+ }
+
+ else if (guid != null && groupType != null && groupName != null) {
+
+ if (groupType.equals(CometChatConstants.GROUP_TYPE_PASSWORD, ignoreCase = true)) {
+
+ if (groupPassword != null) {
+ val group = Group(guid, groupName, groupType.toString().toLowerCase(),
+ groupPassword, null, groupDescription)
+
+ groupViewModel.createGroup(this,group)
+
+ } /*else {
+ chatroomPasswordField.setText("");
+ chatroomPasswordField.setError(chatroomLang.get26());
+ }*/
+ } else {
+ val group = Group(guid, groupName, groupType.toString().toLowerCase(), null,
+ null, groupDescription)
+ groupViewModel.createGroup(this,group)
+
+
+ }
+
+
+ }
+
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ fun showToast(message: String) {
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+
+ override fun onNothingSelected(p0: AdapterView<*>?) {
+ }
+
+ override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
+
+ groupType = p0?.getSelectedItem() as String
+
+ if (groupType.equals(CometChatConstants.GROUP_TYPE_PASSWORD, ignoreCase = true)) {
+ binding.llPasswordContainer.setVisibility(View.VISIBLE)
+ } else {
+ binding.llPasswordContainer.setVisibility(View.GONE)
+ }
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/GroupDetailActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/GroupDetailActivity.kt
new file mode 100755
index 0000000..c400eea
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/GroupDetailActivity.kt
@@ -0,0 +1,185 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.arch.lifecycle.ViewModelProviders
+import android.databinding.DataBindingUtil
+import android.graphics.PorterDuff
+import android.support.v7.app.AppCompatActivity
+import android.os.Bundle
+import android.support.v4.content.ContextCompat
+import android.support.v7.widget.LinearLayoutManager
+import android.view.Menu
+import android.view.MenuItem
+import com.cometchat.pro.core.CometChat
+import com.inscripts.cometchatpulse.Adapter.GroupOptionAdapter
+import com.inscripts.cometchatpulse.Extensions.setTitleTypeface
+import com.inscripts.cometchatpulse.Fragment.BanMemberFragment
+import com.inscripts.cometchatpulse.Fragment.MemberFragment
+import com.inscripts.cometchatpulse.Helpers.OnOptionClickListener
+import com.inscripts.cometchatpulse.Pojo.GroupOption
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupViewModel
+import com.inscripts.cometchatpulse.databinding.ActivityGroupDetailBinding
+
+class GroupDetailActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivityGroupDetailBinding
+
+ private lateinit var groupId: String
+
+ private lateinit var ownerUid: String
+
+ private lateinit var layoutManager: LinearLayoutManager
+
+ private lateinit var groupOptionAdapter: GroupOptionAdapter
+
+ private var groupOptionList: MutableList = mutableListOf()
+
+ private lateinit var groupViewModel: GroupViewModel
+
+ private var groupOwner:String?=null
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_group_detail)
+
+ CommonUtil.setStatusBarColor(this)
+
+ groupOwner = intent?.getStringExtra(StringContract.IntentString.GROUP_OWNER)
+
+ binding.groupName = intent?.getStringExtra(StringContract.IntentString.GROUP_NAME)
+
+ binding.groupIcon = intent?.getStringExtra(StringContract.IntentString.GROUP_ICON)
+
+ binding.description = intent?.getStringExtra(StringContract.IntentString.GROUP_DESCRIPTION)
+
+ ownerUid = CometChat.getLoggedInUser().uid
+
+ groupId = intent?.getStringExtra(StringContract.IntentString.GROUP_ID).toString()
+
+ binding.tvDescription.typeface=StringContract.Font.name
+ binding.tvName.typeface=StringContract.Font.name
+
+
+
+ groupViewModel = ViewModelProviders.of(this).get(GroupViewModel::class.java)
+
+ layoutManager = LinearLayoutManager(this)
+ binding.rvGroupOptions.layoutManager = layoutManager
+ groupOptionAdapter = GroupOptionAdapter(this, GroupOptionItemList(), ownerUid, groupId,object :OnOptionClickListener(){
+
+ override fun OnOptionClick( position:Int){
+
+ when (position) {
+
+ 0 -> {
+ val memberListFragment = MemberFragment().apply {
+ arguments = Bundle().apply {
+ putString(StringContract.IntentString.GROUP_ID, groupId)
+ putString(StringContract.IntentString.USER_ID, ownerUid)
+ }
+ }
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.group_frame, memberListFragment).addToBackStack(null).commit()
+ }
+
+ 1 -> {
+ val banMemberListFragment = BanMemberFragment().apply {
+ arguments = Bundle().apply {
+ putString(StringContract.IntentString.GROUP_ID, groupId)
+ putString(StringContract.IntentString.USER_ID, ownerUid)
+ }
+ }
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.group_frame, banMemberListFragment).addToBackStack(null).commit()
+ }
+ 2 -> {
+ showDialog("Are you sure want to leave ? "+intent?.getStringExtra(StringContract.IntentString.GROUP_NAME),
+ "Leave Group",position)
+ }
+
+ 3 -> {
+ showDialog("Are you sure want to delete ? "+intent?.getStringExtra(StringContract.IntentString.GROUP_NAME),
+ "Delete Group",position)
+ }
+
+ }
+ }
+
+ })
+ binding.rvGroupOptions.adapter = groupOptionAdapter
+
+
+ setSupportActionBar(binding.toolbar)
+ supportActionBar!!.title="Group Details"
+ supportActionBar!!.elevation = 10f
+ supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+
+
+ binding.toolbar.setTitleTypeface(StringContract.Font.title)
+ binding.toolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ binding.tv30.setBackgroundColor(StringContract.Color.primaryDarkColor)
+ binding.toolbar.setTitleTextColor(StringContract.Color.black)
+
+ } else {
+ binding.tv30.setBackgroundColor(StringContract.Color.primaryColor)
+ binding.toolbar.setTitleTextColor(StringContract.Color.white)
+ }
+
+ }
+
+
+ private fun GroupOptionItemList(): MutableList {
+
+ groupOptionList.add(GroupOption("View Members", ContextCompat.getDrawable(this, R.drawable.ic_person_black_24dp)))
+ groupOptionList.add(GroupOption("Unban Members", ContextCompat.getDrawable(this, R.drawable.ic_supervisor_account_black_24dp)))
+ groupOptionList.add(GroupOption("Leave Group", ContextCompat.getDrawable(this, R.drawable.ic_exit_to_app_black_24dp)))
+ if (ownerUid.equals(groupOwner)) {
+ groupOptionList.add(GroupOption("Delete Group", ContextCompat.getDrawable(this, R.drawable.ic_delete_black_24dp)))
+ }
+ return groupOptionList
+ }
+
+
+ fun showDialog(message: String, title: String, position: Int) {
+ val builder = android.support.v7.app.AlertDialog.Builder(this)
+ builder.setTitle(CommonUtil.setTitle(title, this))
+
+ .setMessage(message)
+ .setCancelable(true)
+ .setNegativeButton(CommonUtil.setTitle("Cancel", this)) {
+ dialogInterface, i -> dialogInterface.dismiss() }
+ .setPositiveButton(CommonUtil.setTitle("Yes", this)) {
+ dialogInterface, i -> when(position){
+
+ 2->{
+ groupViewModel.leaveGroup(groupId, this@GroupDetailActivity)
+ }
+
+ 3->{
+ groupViewModel.deleteGroup(groupId,this@GroupDetailActivity)
+ }
+ }
+ }.show()
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ return super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+
+ if (item.itemId == android.R.id.home) {
+ onBackPressed()
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/ImageViewActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/ImageViewActivity.kt
new file mode 100755
index 0000000..fc1c360
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/ImageViewActivity.kt
@@ -0,0 +1,29 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.databinding.DataBindingUtil
+import android.support.v7.app.AppCompatActivity
+import android.os.Bundle
+
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.databinding.ActivityImageViewBinding
+
+class ImageViewActivity : AppCompatActivity() {
+
+ private lateinit var binding:ActivityImageViewBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ CommonUtil.setStatusBarColor(this)
+ binding=DataBindingUtil.setContentView(this,R.layout.activity_image_view)
+
+ binding.context=this
+
+ binding.type=intent?.getStringExtra(StringContract.IntentString.FILE_TYPE)
+
+ binding.url=intent?.getStringExtra(StringContract.IntentString.URL)
+
+ CommonUtil.setStatusBarColor(this)
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/LocationActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/LocationActivity.kt
new file mode 100755
index 0000000..499a603
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/LocationActivity.kt
@@ -0,0 +1,292 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.content.pm.PackageManager
+import android.location.Location
+import android.location.LocationListener
+import android.location.LocationManager
+import android.os.Bundle
+import android.support.v4.app.ActivityCompat
+import android.support.v4.content.ContextCompat
+import android.support.v7.app.AppCompatActivity
+import android.util.Log
+import android.view.View
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.models.TextMessage
+import com.google.android.gms.common.api.Status
+import com.google.android.gms.location.FusedLocationProviderClient
+import com.google.android.gms.location.LocationRequest
+import com.google.android.gms.location.LocationServices
+import com.google.android.gms.location.places.GeoDataClient
+import com.google.android.gms.location.places.Place
+import com.google.android.gms.location.places.PlaceDetectionClient
+import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment
+import com.google.android.gms.location.places.ui.PlaceSelectionListener
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.SupportMapFragment
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.Marker
+import com.google.android.gms.maps.model.MarkerOptions
+import com.google.android.gms.maps.model.PolygonOptions
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.Repository.MessageRepository
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import kotlinx.android.synthetic.main.activity_location.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import org.json.JSONObject
+
+
+class LocationActivity : AppCompatActivity(), OnMapReadyCallback, PlaceSelectionListener, View.OnClickListener {
+
+ private var mMap: GoogleMap? = null
+
+ private val DEFAULT_ZOOM: Float = 20f
+
+ private var mDefaultLocation: LatLng = LatLng(-33.8523341, 151.2106085)
+
+ private var markerLatLng: LatLng? = null
+
+ private var mLastKnownLocation: Location? = null
+
+ private lateinit var mFusedLocationProviderClient: FusedLocationProviderClient
+
+ private lateinit var autocompleteFragment: PlaceAutocompleteFragment
+
+ private lateinit var receiverId: String
+
+ private var receiverType: String? = null
+
+ private var marker: Marker? = null
+
+ private lateinit var mLocationRequest:LocationRequest
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_location)
+ CommonUtil.setStatusBarColor(this)
+ // Obtain the SupportMapFragment and get notified when the map is ready to be used.
+ val mapFragment = supportFragmentManager.findFragmentById(com.inscripts.cometchatpulse.R.id.map) as SupportMapFragment
+ mapFragment.getMapAsync(this)
+
+ // Construct a FusedLocationProviderClient.
+ mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this@LocationActivity)
+
+
+ receiverId = intent.getStringExtra(StringContract.IntentString.ID)
+ receiverType = intent?.getStringExtra(StringContract.IntentString.RECIVER_TYPE)
+
+ autocompleteFragment = fragmentManager.findFragmentById(R.id.place_autocomplete_fragment) as PlaceAutocompleteFragment
+
+ autocompleteFragment.setOnPlaceSelectedListener(this)
+
+ ivLocation.setOnClickListener(this)
+
+ }
+
+
+ override fun onPlaceSelected(p0: Place?) {
+ mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(p0?.latLng, DEFAULT_ZOOM))
+
+ try {
+ marker = mMap?.addMarker(p0?.latLng?.let { MarkerOptions().position(it).title(p0.name.toString()) })!!
+ markerLatLng = p0?.latLng
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ }
+
+ override fun onError(p0: Status?) {
+
+ }
+
+ override fun onClick(p0: View?) {
+
+ when (p0?.id) {
+
+ R.id.ivLocation -> {
+
+ try {
+
+ val messageRepository: MessageRepository = MessageRepository()
+
+ val jObject = JSONObject()
+
+ jObject.put("lat", markerLatLng?.latitude)
+ jObject.put("logt", markerLatLng?.longitude)
+
+ val textMessage = TextMessage(receiverId, "custom_location",CometChatConstants.MESSAGE_TYPE_TEXT, receiverType)
+
+ textMessage.metadata = jObject
+
+ messageRepository.sendTextMessage(textMessage, this@LocationActivity)
+
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ }
+ }
+
+
+ override fun onDestroy() {
+ super.onDestroy()
+ }
+
+
+ override fun onStop() {
+ super.onStop()
+ }
+
+ /**
+ * Manipulates the map once available.
+ * This callback is triggered when the map is ready to be used.
+ * This is where we can add markers or lines, add listeners or move the camera. In this case,
+ * we just add a marker near Sydney, Australia.
+ * If Google Play services is not installed on the device, the user will be prompted to install
+ * it inside the SupportMapFragment. This method will only be triggered once the user has
+ * installed Google Play services and returned to the app.
+ */
+ override fun onMapReady(googleMap: GoogleMap) {
+ mMap = googleMap
+
+ // Add a marker in Sydney and move the camera
+
+// val sydney = LatLng(19.046865, 72.906995)
+// mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Inscripts"))
+// mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
+ getLocationPermission()
+ updateLocationUI()
+ getDeviceLocation()
+
+
+
+ mMap?.setOnMapClickListener(object : GoogleMap.OnMapClickListener {
+
+ override fun onMapClick(p0: LatLng?) {
+
+ try {
+ marker?.remove()
+ markerLatLng = p0
+ marker = mMap?.addMarker(p0?.let { MarkerOptions().position(it) })
+ mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(p0, DEFAULT_ZOOM))
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ })
+
+ mMap?.setOnMyLocationButtonClickListener(object :GoogleMap.OnMyLocationButtonClickListener{
+ override fun onMyLocationButtonClick(): Boolean {
+
+ return false
+ }
+
+ })
+
+ }
+
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+
+ when (requestCode) {
+
+ StringContract.RequestCode.LOCATION -> {
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ } else {
+
+ Toast.makeText(this, "Location permission denied, can't fetch location", Toast.LENGTH_SHORT).show()
+ }
+
+
+ }
+ }
+
+ updateLocationUI()
+ }
+
+
+ private fun getDeviceLocation() {
+
+ try {
+ if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ val locationResult = mFusedLocationProviderClient.lastLocation
+ locationResult.addOnCompleteListener(this) { p0 ->
+ if (p0.isSuccessful) {
+ try {
+ mLastKnownLocation = p0.result
+ mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(mLastKnownLocation?.latitude!!, mLastKnownLocation?.longitude!!), DEFAULT_ZOOM))
+ marker = mMap?.addMarker(MarkerOptions().position(LatLng(mLastKnownLocation?.latitude!!, mLastKnownLocation?.longitude!!)))!!
+ markerLatLng= mLastKnownLocation?.latitude?.let { LatLng(it, mLastKnownLocation?.longitude!!) }
+ } catch (e: Exception) {
+
+ }
+ } else {
+ Log.d("MAP", "Current location is null. Using defaults.")
+ Log.e("MAp", "Exception: %s", p0.exception)
+ mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM))
+ }
+ }
+
+ } else {
+ ActivityCompat.requestPermissions(this,
+ arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), StringContract.RequestCode.LOCATION)
+
+ }
+ } catch (e: Exception) {
+
+ }
+
+ }
+
+ private fun getLocationPermission() {
+ if (ContextCompat.checkSelfPermission(this.applicationContext,
+ android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ getDeviceLocation()
+
+ } else {
+ ActivityCompat.requestPermissions(this,
+ arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), StringContract.RequestCode.LOCATION)
+ }
+ }
+
+ private fun updateLocationUI() {
+
+ if (mMap == null) {
+ return
+ }
+
+ try {
+
+ if (ContextCompat.checkSelfPermission(this.applicationContext,
+ android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ mMap?.isMyLocationEnabled = true
+ mMap?.uiSettings?.isMyLocationButtonEnabled = true
+
+ } else {
+ getLocationPermission()
+ mMap?.isMyLocationEnabled=false
+
+ }
+
+
+ } catch (e: SecurityException) {
+ Log.e("Exception: %s", e.message)
+ }
+
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/LoginActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/LoginActivity.kt
new file mode 100755
index 0000000..23db88d
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/LoginActivity.kt
@@ -0,0 +1,127 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.content.Context
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.databinding.DataBindingUtil
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffColorFilter
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.ShapeDrawable
+import android.graphics.drawable.StateListDrawable
+import android.os.Bundle
+import android.support.v4.content.ContextCompat
+import android.support.v7.app.AppCompatActivity
+import android.text.Html
+import android.text.SpannableString
+import android.text.TextUtils
+import android.util.Log
+import android.view.View
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.exceptions.CometChatException
+import com.cometchat.pro.models.User
+import com.google.firebase.messaging.FirebaseMessaging
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.databinding.ActivityLoginBinding
+
+
+public class LoginActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivityLoginBinding
+ private lateinit var context: Context
+ private val TAG="LoginActivity"
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ context = this
+ CommonUtil.setStatusBarColor(this)
+ if (CometChat.getLoggedInUser() != null) {
+ startActivity()
+ }
+
+ else {
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_login)
+ binding.login = this
+
+ if (StringContract.AppDetails.theme==Appearance.AppTheme.PERSIAN_BLUE||
+ StringContract.AppDetails.theme==Appearance.AppTheme.MOUNTAIN_MEADOW) {
+ binding.btLogin.setTextColor(StringContract.Color.white)
+ binding.rlBack.setBackgroundColor(StringContract.Color.primaryColor)
+ binding.progressHorizontal.progressTintList= ColorStateList.valueOf(StringContract.Color.primaryColor)
+ }
+ else{
+ binding.progressHorizontal.progressTintList= ColorStateList.valueOf(StringContract.Color.iconTint)
+ binding.btLogin.setTextColor(StringContract.Color.black)
+ binding.rlBack.setBackgroundColor(StringContract.Color.primaryDarkColor)
+ }
+
+ binding.editTextUid.typeface=StringContract.Font.name
+ binding.btLogin.typeface=StringContract.Font.status
+ val drawableUid=(binding.btLogin.background)
+
+ drawableUid.setColorFilter(StringContract.Color.primaryColor,PorterDuff.Mode.SRC_ATOP)
+ for (drawable:Drawable? in binding.editTextUid.compoundDrawables) {
+ if (drawable != null) {
+ drawable.setColorFilter(PorterDuffColorFilter(ContextCompat.getColor(binding.editTextUid.getContext(), StringContract.Color.primaryColor), PorterDuff.Mode.SRC_ATOP))
+ }
+ }
+
+ }
+
+ CommonUtil.setStatusBarColor(this)
+
+ }
+
+ fun onLoginClick(uid:String){
+
+ Log.d("Login", uid)
+ binding.progressHorizontal.visibility=View.VISIBLE
+ kotlin.run {
+ Toast.makeText(this@LoginActivity,"Please Wait",Toast.LENGTH_SHORT).show()
+ CometChat.login(uid.trim(), StringContract.AppDetails.API_KEY, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: User?) {
+ startActivity()
+
+ FirebaseMessaging.getInstance().subscribeToTopic("user_${p0?.uid}")
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(context, p0?.message, Toast.LENGTH_SHORT).show()
+ binding.progressHorizontal.visibility=View.GONE
+ Log.d(TAG,"onError:Login "+p0?.message)
+
+
+ }
+
+ })
+
+// CometChat.login("superhero11_3b34bb32bfc7f3a930c829b75d6ffeb579efbd0e",object :CometChat.CallbackListener(){
+// override fun onSuccess(p0: User?) {
+// Log.d(TAG,"onSuccess: "+p0.toString())
+// binding.progressHorizontal.visibility=View.GONE
+// startActivity()
+// }
+//
+// override fun onError(p0: CometChatException?) {
+// Log.d(TAG,"onError: "+p0?.message)
+// binding.progressHorizontal.visibility=View.GONE
+// }
+//
+// })
+ }
+
+
+ }
+
+ fun startActivity() {
+ startActivity(Intent(this, MainActivity::class.java))
+ finish()
+ }
+}
+
+
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/MainActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/MainActivity.kt
new file mode 100755
index 0000000..4cc378c
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/MainActivity.kt
@@ -0,0 +1,436 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.app.AlertDialog
+import android.app.ProgressDialog
+import android.arch.lifecycle.ViewModelProviders
+import android.content.Context
+import android.content.DialogInterface
+import android.content.Intent
+import android.content.res.ColorStateList
+import android.graphics.PorterDuff
+import android.graphics.Typeface
+import android.os.Bundle
+import android.support.design.widget.BottomNavigationView
+import android.support.v4.app.Fragment
+import android.support.v4.content.ContextCompat
+import android.support.v7.app.AppCompatActivity
+import android.util.Log
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
+import android.widget.EditText
+import android.widget.TextView
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.exceptions.CometChatException
+import com.cometchat.pro.helpers.Logger
+import com.cometchat.pro.models.Group
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Fragment.ContactListFragment
+import com.inscripts.cometchatpulse.Fragment.GroupFragment
+import com.inscripts.cometchatpulse.Fragment.GroupListFragment
+import com.inscripts.cometchatpulse.Fragment.OneToOneFragment
+import com.inscripts.cometchatpulse.Helpers.ChildClickListener
+import com.inscripts.cometchatpulse.Helpers.CustomAlertDialogHelper
+import com.inscripts.cometchatpulse.Helpers.OnAlertDialogButtonClickListener
+import com.inscripts.cometchatpulse.Helpers.OnBackArrowClickListener
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.Repository.GroupRepository
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupChatViewModel
+import com.inscripts.cometchatpulse.ViewModel.GroupViewModel
+import com.inscripts.cometchatpulse.ViewModel.OnetoOneViewModel
+import kotlinx.android.synthetic.main.activity_main.*
+
+
+class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener,
+ ChildClickListener, OnBackArrowClickListener, OnAlertDialogButtonClickListener, GroupRepository.onGroupJoin {
+
+ private var twoPane: Boolean = false
+
+ private var position: Int = 0
+
+ private lateinit var progressDialog: ProgressDialog
+
+ private lateinit var groupViewModel: GroupViewModel
+
+ private lateinit var group: Group
+
+ var resId: Int = 0
+
+ private lateinit var groupChatViewModel: GroupChatViewModel
+
+ private lateinit var oneToOneChatViewModel: OnetoOneViewModel
+
+ private val TAG="MainActivity"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ navigation.setOnNavigationItemSelectedListener(this)
+
+ frame_container_detail
+ loadFragment(ContactListFragment())
+
+ groupViewModel = ViewModelProviders.of(this).get(GroupViewModel::class.java)
+ groupChatViewModel = ViewModelProviders.of(this).get(GroupChatViewModel::class.java)
+ oneToOneChatViewModel = ViewModelProviders.of(this).get(OnetoOneViewModel::class.java)
+
+
+ setSupportActionBar(toolbar)
+ supportActionBar?.title = ""
+ toolbar.title = ""
+
+ toolbar.setBackgroundColor(StringContract.Color.primaryColor)
+ navigation.itemTextColor = getColorStateList()
+
+ navigation.itemIconTintList = getColorStateList()
+
+ overrideFont(this,navigation)
+
+
+ if (main_frame != null) {
+ main_frame.setBackgroundColor(StringContract.Color.primaryColor)
+ }
+ toolbar.overflowIcon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ toolbar_title?.setTypeface(StringContract.Font.title)
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ toolbar_title.setTextColor(StringContract.Color.black)
+ } else {
+ toolbar_title.setTextColor(StringContract.Color.white)
+ }
+ toolbar_title?.setText("Contact")
+
+ if (frame_container_detail != null) {
+
+ twoPane = true
+ }
+ CommonUtil.setStatusBarColor(this)
+
+ for (i in 0..navigation.menu.size()) {
+
+ }
+
+
+ }
+
+ private fun overrideFont(context: Context, v: View) {
+ val typeface = StringContract.Font.status
+ try {
+ if (v is ViewGroup) {
+ for (i in 0..v.childCount) {
+ overrideFont(context, v.getChildAt(i))
+ }
+
+ } else if (v is TextView) {
+ v.typeface = typeface
+ }
+ } catch (e: Exception) {
+
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+
+ menuInflater.inflate(R.menu.main_menu, menu)
+
+ val menuDrawable = ContextCompat.getDrawable(this, R.drawable.ic_more)
+ menuDrawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ menu?.getItem(0)?.setIcon(menuDrawable)
+
+ val menuItem = menu?.findItem(R.id.create_group)?.icon
+
+ menuItem?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+
+ return super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ when (item?.itemId) {
+
+ R.id.create_group -> {
+ startActivity(Intent(this, CreateGroupActivity::class.java))
+ }
+
+ R.id.logout_menu -> {
+
+ CometChat.logout(object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: String?) {
+ startActivity(Intent(this@MainActivity, LoginActivity::class.java))
+ finish()
+ }
+
+ override fun onError(p0: CometChatException?) {
+ }
+
+ })
+
+ }
+
+ R.id.view_menu -> {
+ val user = CometChat.getLoggedInUser()
+ val profilViewIntent = Intent(this, UserProfileViewActivity::class.java)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_NAME, user.name)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_ID, user.uid)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_STATUS, user.status)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_AVATAR, user.avatar)
+ startActivity(profilViewIntent)
+ }
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ private fun getColorStateList(): ColorStateList {
+
+ val states = arrayOf(
+ intArrayOf(-android.R.attr.state_selected), intArrayOf(android.R.attr.state_selected)
+ )
+ var colors = intArrayOf()
+
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ colors = intArrayOf(StringContract.Color.inactiveColor, StringContract.Color.iconTint)
+ } else {
+ colors = intArrayOf(StringContract.Color.inactiveColor, StringContract.Color.primaryColor)
+ }
+
+
+ return ColorStateList(states, colors)
+ }
+
+
+ override fun onBackPressed() {
+ super.onBackPressed()
+ hideKeyboard()
+
+ }
+
+ fun hideKeyboard() {
+ val inputManager =getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+
+ // check if no view has focus:
+ val currentFocusedView = currentFocus
+ if (currentFocusedView != null) {
+ inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ }
+ }
+
+
+ override fun OnChildClick(t: Any) {
+
+
+ if (twoPane) {
+ resId = R.id.frame_container_detail
+ } else {
+ resId = R.id.main_frame
+ }
+ if (t is User) {
+ val oneToOneFragment = OneToOneFragment().apply {
+ arguments = Bundle().apply {
+ putString(StringContract.IntentString.USER_ID, t.uid)
+ putString(StringContract.IntentString.USER_NAME, t.name)
+ putString(StringContract.IntentString.USER_AVATAR, t.avatar)
+ putString(StringContract.IntentString.USER_STATUS, t.status)
+ putLong(StringContract.IntentString.LAST_ACTIVE, t.lastActiveAt)
+
+ }
+ }
+ supportFragmentManager.beginTransaction()
+ .replace(resId, oneToOneFragment).addToBackStack(null).commit()
+ } else if (t is Group) {
+ group = t
+ initJoinGroup(group, resId)
+ }
+
+ }
+
+ fun startGroupChatFragment(t: Group, resId: Int) {
+ val groupChat = GroupFragment().apply {
+ arguments = Bundle().apply {
+ putString(StringContract.IntentString.GROUP_ID, t.guid)
+ putString(StringContract.IntentString.GROUP_NAME, t.name)
+ putString(StringContract.IntentString.GROUP_ICON, t.icon)
+ putString(StringContract.IntentString.GROUP_OWNER, t.owner)
+ putString(StringContract.IntentString.GROUP_DESCRIPTION, t.description)
+ }
+ }
+ supportFragmentManager.beginTransaction()
+ .replace(resId, groupChat).addToBackStack(null).commit()
+
+ }
+
+ private lateinit var groupPassword: String
+
+ override fun onButtonClick(alertDialog: AlertDialog?, v: View?, which: Int, popupId: Int) {
+
+ val groupPasswordInput = v?.findViewById(R.id.edittextDialogueInput) as EditText
+ if (which == DialogInterface.BUTTON_NEGATIVE) { // Cancel
+
+ alertDialog?.dismiss()
+ } else if (which == DialogInterface.BUTTON_POSITIVE) { // Join
+ try {
+ progressDialog = ProgressDialog.show(this, "", getString(R.string.joining))
+ progressDialog.setProgressStyle(StringContract.Color.primaryColor)
+ progressDialog.setCancelable(false)
+ groupPassword = groupPasswordInput.text.toString()
+ if (groupPassword.length == 0) {
+ groupPasswordInput.setText("")
+ groupPasswordInput.error = getString(R.string.incorrect_password)
+
+ } else {
+ try {
+ alertDialog?.dismiss()
+ group.setPassword(groupPassword)
+
+ groupViewModel.joinGroup(group, progressDialog, resId, this@MainActivity)
+
+ } catch (e: Exception) {
+ Logger.error("Error at SHA1:UnsupportedEncodingException FOR PASSWORD " + e.localizedMessage)
+ e.printStackTrace()
+ }
+
+ }
+ } catch (e: Exception) {
+ Logger.error("chatroomFragment.java onButtonClick() : Exception=" + e.localizedMessage)
+ e.printStackTrace()
+ }
+
+ }
+ }
+
+
+ private fun initJoinGroup(group: Group, resId: Int) {
+
+ if (CommonUtil.isConnected(this@MainActivity)) {
+
+ if (group.groupType.equals(CometChatConstants.GROUP_TYPE_PUBLIC, ignoreCase = true) ||
+ group.groupType.equals(CometChatConstants.GROUP_TYPE_PRIVATE, ignoreCase = true)) {
+
+ if (group.isJoined) {
+ startGroupChatFragment(group, resId)
+ } else {
+ progressDialog = ProgressDialog.show(this, "", getString(R.string.joining))
+ progressDialog.setCancelable(false)
+ groupViewModel.joinGroup(group, progressDialog, resId, this@MainActivity)
+ }
+
+ } else {
+ if (group.isJoined) {
+ startGroupChatFragment(group, resId)
+ } else {
+ val dialogview = this.getLayoutInflater().inflate(R.layout.cc_custom_dialog, null)
+ val tvTitle = dialogview.findViewById(R.id.textViewDialogueTitle) as TextView
+ tvTitle.text = ""
+ CustomAlertDialogHelper(this, getString(R.string.group_password), dialogview, getString(R.string.enter),
+ "", getString(R.string.cancel), this, 1, false)
+ }
+ }
+ } else {
+ if (progressDialog.isShowing()) {
+ progressDialog.dismiss()
+ }
+ Toast.makeText(this, getString(R.string.warning), Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ }
+
+ override fun onBackClick() {
+
+ if (twoPane) {
+
+ if (list_container.visibility == View.VISIBLE) {
+ list_container.visibility = View.GONE
+ } else if (list_container.visibility == View.GONE) {
+ list_container.visibility = View.VISIBLE
+ }
+ }
+ }
+
+
+ override fun onSaveInstanceState(outState: Bundle?) {
+ super.onSaveInstanceState(outState)
+
+ outState?.putInt(StringContract.IntentString.POSITION, position)
+ }
+
+ override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
+ super.onRestoreInstanceState(savedInstanceState)
+
+ try {
+ supportActionBar?.title = ""
+ navigation.selectedItemId = savedInstanceState?.getInt(StringContract.IntentString.POSITION)!!
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ fun loadFragment(fragment: Fragment?): Boolean {
+
+ if (fragment != null) {
+ supportFragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit()
+ return true
+ } else {
+ return false
+ }
+
+ }
+
+
+
+ override fun onResume() {
+ super.onResume()
+ Log.d(TAG,"onResume: ")
+ groupChatViewModel.addGroupEventListener(StringContract.ListenerName.GROUP_EVENT_LISTENER)
+ oneToOneChatViewModel.addCallListener(this, TAG, null)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ Log.d(TAG,"onPause: ")
+ groupChatViewModel.removeGroupEventListener(StringContract.ListenerName.GROUP_EVENT_LISTENER)
+ oneToOneChatViewModel.removeCallListener(TAG)
+ }
+
+ override fun onJoined(group: Group, resId: Int) {
+ startGroupChatFragment(group, resId)
+ }
+
+
+ override fun onNavigationItemSelected(p0: MenuItem): Boolean {
+
+ var fragment: Fragment? = null
+
+ when (p0.itemId) {
+
+ R.id.menu_contacts -> {
+ fragment = ContactListFragment()
+ toolbar_title?.setText("Contacts")
+ position = R.id.menu_contacts
+
+ }
+
+ R.id.menu_group -> {
+
+ fragment = GroupListFragment()
+ toolbar_title?.setText("Groups")
+ position = R.id.menu_group
+
+ }
+
+ }
+ return loadFragment(fragment)
+ }
+
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Activities/UserProfileViewActivity.kt b/app/src/main/java/com/inscripts/cometchatpulse/Activities/UserProfileViewActivity.kt
new file mode 100755
index 0000000..d247b6f
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Activities/UserProfileViewActivity.kt
@@ -0,0 +1,155 @@
+package com.inscripts.cometchatpulse.Activities
+
+import android.arch.lifecycle.ViewModelProviders
+import android.content.pm.PackageManager
+import android.databinding.DataBindingUtil
+import android.graphics.PorterDuff
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.view.MenuItem
+import android.view.View
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.CometChat
+import com.inscripts.cometchatpulse.Helpers.CCPermissionHelper
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.OnetoOneViewModel
+import com.inscripts.cometchatpulse.databinding.ActivityUserProfileViewBinding
+import android.support.v4.content.ContextCompat
+import android.graphics.PorterDuffColorFilter
+import android.graphics.drawable.Drawable
+import com.inscripts.cometchatpulse.Extensions.setTitleTypeface
+import com.inscripts.cometchatpulse.Utils.Appearance
+
+
+class UserProfileViewActivity : AppCompatActivity(), View.OnClickListener {
+
+ private lateinit var binding: ActivityUserProfileViewBinding
+
+ private var uid: String? = null
+
+ private lateinit var oneToOneViewModel: OnetoOneViewModel
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ CommonUtil.setStatusBarColor(this)
+ binding = DataBindingUtil.setContentView(this, R.layout.activity_user_profile_view)
+
+ binding.url = intent?.getStringExtra(StringContract.IntentString.USER_AVATAR)
+
+ binding.status = intent?.getStringExtra(StringContract.IntentString.USER_STATUS)
+
+ binding.name = intent?.getStringExtra(StringContract.IntentString.USER_NAME)
+
+ uid = intent?.getStringExtra(StringContract.IntentString.USER_ID)
+
+ oneToOneViewModel = ViewModelProviders.of(this).get(OnetoOneViewModel::class.java)
+
+ setSupportActionBar(binding.toolbar)
+
+ supportActionBar?.title=intent?.getStringExtra(StringContract.IntentString.USER_NAME)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding.toolbar.setTitleTypeface(StringContract.Font.title)
+
+ binding.toolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint,PorterDuff.Mode.SRC_ATOP)
+
+ binding.tv30.setTextColor(StringContract.Color.primaryColor)
+
+ binding.toolbar.setTitle(intent?.getStringExtra(StringContract.IntentString.USER_NAME))
+
+ binding.toolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+ binding.toolbar.setTitleTextColor(StringContract.Color.white)
+
+ if (StringContract.AppDetails.theme== Appearance.AppTheme.AZURE_RADIANCE) {
+ binding.toolbar.setTitleTextColor(StringContract.Color.black)
+ binding.ivVideo.drawable.setColorFilter(StringContract.Color.iconTint,PorterDuff.Mode.SRC_ATOP)
+ binding.ivVoice.drawable.setColorFilter(StringContract.Color.iconTint,PorterDuff.Mode.SRC_ATOP)
+
+ }
+ else{
+ binding.ivVideo.drawable.setColorFilter(StringContract.Color.primaryColor,PorterDuff.Mode.SRC_ATOP)
+ binding.ivVoice.drawable.setColorFilter(StringContract.Color.primaryColor,PorterDuff.Mode.SRC_ATOP)
+ binding.toolbar.setTitleTextColor(StringContract.Color.white)
+ }
+
+ binding.videoCall.setOnClickListener(this)
+ binding.voiceCall.setOnClickListener(this)
+
+
+ if (CometChat.getLoggedInUser().uid.equals(intent?.getStringExtra(StringContract.IntentString.USER_ID))) {
+
+ binding.voiceCall.visibility = View.GONE
+ binding.videoCall.visibility = View.GONE
+ binding.cardViewCallContainer.visibility = View.GONE
+ binding.status="online"
+
+ }
+ CommonUtil.setStatusBarColor(this)
+
+ }
+
+ override fun onClick(p0: View?) {
+
+ when (p0?.id) {
+
+ R.id.voice_call -> {
+ if (CCPermissionHelper.hasPermissions(this, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ uid?.let { oneToOneViewModel.initCall(this, it, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_AUDIO) }
+ } else {
+ CCPermissionHelper.requestPermissions(this, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VOICE_CALL)
+ }
+
+ }
+
+ R.id.video_call -> {
+ if (CCPermissionHelper.hasPermissions(this, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ uid?.let { oneToOneViewModel.initCall(this, it, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_VIDEO) }
+ } else {
+ CCPermissionHelper.requestPermissions(this, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VIDEO_CALL)
+ }
+
+
+ }
+ }
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+
+ when (requestCode) {
+
+ StringContract.RequestCode.VOICE_CALL -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED) {
+
+ uid?.let { oneToOneViewModel.initCall(this, it, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_AUDIO) }
+
+ } else {
+ Toast.makeText(this, "Voice call will behave inappropriately ", Toast.LENGTH_SHORT).show()
+ }
+ StringContract.RequestCode.VIDEO_CALL -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ uid?.let { oneToOneViewModel.initCall(this, it, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_VIDEO) }
+ } else {
+
+ Toast.makeText(this, "Video call will behave inappropriately ", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ if (item?.itemId == android.R.id.home) {
+ onBackPressed()
+ }
+ return super.onOptionsItemSelected(item)
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/ContactListAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/ContactListAdapter.kt
new file mode 100755
index 0000000..1cc7a2b
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/ContactListAdapter.kt
@@ -0,0 +1,56 @@
+package com.inscripts.cometchatpulse.Adapter
+
+import android.content.Context
+import android.databinding.DataBindingUtil
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Helpers.ChildClickListener
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.ViewHolder.ContactViewHolder
+import com.inscripts.cometchatpulse.databinding.ContactItemBinding
+import com.inscripts.cometchatpulse.ViewModel.UserViewModel
+
+
+class ContactListAdapter(val context: Context?) : RecyclerView.Adapter() {
+
+ private var userList: MutableMap = mutableMapOf()
+
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): ContactViewHolder {
+
+ val layoutInflater:LayoutInflater = LayoutInflater.from(context)
+
+ val binding:ContactItemBinding= DataBindingUtil.inflate(layoutInflater,R.layout.contact_item,p0,false)
+
+ return ContactViewHolder(binding)
+ }
+
+ override fun getItemCount(): Int {
+ return userList.size
+ }
+
+ override fun onBindViewHolder(contactViewHolder: ContactViewHolder, p1: Int) {
+
+ val user=userList.values.toMutableList().get(p1)
+
+ contactViewHolder.binding.user=user
+ contactViewHolder.binding.childClick=context as ChildClickListener
+ contactViewHolder.binding.textviewUserName.typeface=StringContract.Font.name
+ contactViewHolder.binding.textviewUserStatus.typeface=StringContract.Font.status
+ contactViewHolder.binding.executePendingBindings()
+ contactViewHolder.binding.root.setTag(R.string.user,user)
+ contactViewHolder.binding.executePendingBindings()
+
+ }
+
+ internal fun setUser(users: MutableMap) {
+ this.userList = users
+ notifyDataSetChanged()
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupChatAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupChatAdapter.kt
new file mode 100755
index 0000000..92ebd98
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupChatAdapter.kt
@@ -0,0 +1,1348 @@
+package com.inscripts.cometchatpulse.Adapter
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.databinding.DataBindingUtil
+import android.graphics.Bitmap
+import android.graphics.PorterDuff
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.net.Uri
+import android.os.AsyncTask
+import android.os.Handler
+import android.support.v4.util.LongSparseArray
+import android.support.v7.widget.RecyclerView
+import android.text.TextUtils
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.SeekBar
+import android.widget.TextView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.RequestOptions
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.Call
+import com.cometchat.pro.models.*
+import com.inscripts.cometchatpulse.Activities.ImageViewActivity
+import com.inscripts.cometchatpulse.AsyncTask.DownloadFile
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.CustomView.StickyHeaderAdapter
+import com.inscripts.cometchatpulse.Helpers.CCPermissionHelper
+import com.inscripts.cometchatpulse.Helpers.OnClickEvent
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.DateUtil
+import com.inscripts.cometchatpulse.Utils.FileUtil
+import com.inscripts.cometchatpulse.ViewHolder.*
+import com.inscripts.cometchatpulse.databinding.*
+import java.io.File
+import java.io.IOException
+import java.util.*
+
+class GroupChatAdapter(val context: Context, val guid: String, val ownerId: String, val listener: OnClickEvent ) :
+ RecyclerView.Adapter(), StickyHeaderAdapter {
+
+
+ private var messagesList: MutableList = mutableListOf()
+
+ lateinit var viewHolder: RecyclerView.ViewHolder
+
+ private var currentPlayingSong: String? = null
+ private var timerRunnable: Runnable? = null
+ private val seekHandler = Handler()
+ private var onClickEvent: OnClickEvent
+ private var currentlyPlayingId = 0L
+
+ private var downloadFile: DownloadFile? = null
+
+ var player: MediaPlayer? = null
+
+ init {
+
+ if (player == null) {
+ player = MediaPlayer()
+ }
+ onClickEvent = listener
+ audioDurations = LongSparseArray()
+ videoThumbnails = LongSparseArray()
+
+ }
+
+ companion object {
+ private lateinit var audioDurations: LongSparseArray
+ private lateinit var videoThumbnails: LongSparseArray
+ }
+
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
+ val layoutInflater: LayoutInflater = LayoutInflater.from(context)
+
+ when (p1) {
+
+ StringContract.ViewType.RIGHT_TEXT_MESSAGE -> {
+ val binding: RightTextBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_text, p0, false)
+ return RightTextMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_MESSAGE -> {
+ val binding: LeftTextBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_text, p0, false)
+ return LeftTextMessageHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_IMAGE_MESSAGE -> {
+ val binding: CcImageVideoLayoutRightBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_right, p0, false)
+ return RightImageVideoMessageHolder(binding)
+ }
+ StringContract.ViewType.LEFT_IMAGE_MESSAGE -> {
+ val binding: CcImageVideoLayoutLeftBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_left, p0, false)
+ return LeftImageVideoMessageHolder(binding)
+ }
+ StringContract.ViewType.RIGHT_VIDEO_MESSAGE -> {
+
+ val binding: CcImageVideoLayoutRightBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_right, p0, false)
+ return RightImageVideoMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_VIDEO_MESSAGE -> {
+ val binding: CcImageVideoLayoutLeftBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_left, p0, false)
+ return LeftImageVideoMessageHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_AUDIO_MESSAGE -> {
+ val binding: RightAudioBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_audio, p0, false)
+ return RightAudioMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_AUDIO_MESSAGE -> {
+ val binding: LeftAudioBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_audio, p0, false)
+ return LeftAudioMessageHolder(binding)
+ }
+ StringContract.ViewType.CALL_MESSAGE -> {
+ val binding: ListHeaderBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_header, p0, false)
+ return TextHeaderHolder(binding)
+ }
+ StringContract.ViewType.ACTION_MESSAGE -> {
+ val binding: ListHeaderBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_header, p0, false)
+ return TextHeaderHolder(binding)
+ }
+ StringContract.ViewType.RIGHT_FILE_MESSAGE -> {
+ val binding: RightFileBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_file, p0, false)
+ return RightFileViewHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_FILE_MESSAGE -> {
+ val binding: LeftFileBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_file, p0, false)
+ return LeftFileViewHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_LOCATION_MESSAGE -> {
+ val binding: RightLocationBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_location, p0, false)
+ return RightLocationViewHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_LOCATION_MESSAGE -> {
+ val binding: LeftLocationBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_location, p0, false)
+ return LeftLocationViewHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_TEXT_REPLY_MESSAGE -> {
+
+ val binding: RightReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_reply, p0, false)
+ return RightReplyMessageHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_MEDIA_REPLY_MESSAGE -> {
+
+ val binding: RightReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_reply, p0, false)
+ return RightReplyMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_REPLY_MESSAGE -> {
+
+ val binding: LeftReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_reply, p0, false)
+ return LeftReplyMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_MEDIA_REPLY_MESSAGE -> {
+
+ val binding: LeftReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_reply, p0, false)
+ return LeftReplyMessageHolder(binding)
+ }
+
+
+ else -> {
+ Log.d(" onCreateViewHolder ", " Unknown View Type ")
+ val binding: RightTextBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_text, p0, false)
+ return RightTextMessageHolder(binding)
+ }
+ }
+ }
+
+
+ override fun getHeaderId(var1: Int): Long {
+
+ return java.lang.Long.parseLong(DateUtil.getDateId(messagesList.get(var1).getSentAt() * 1000))
+ }
+
+ override fun onCreateHeaderViewHolder(var1: ViewGroup): TextHeaderHolder {
+ val layoutInflater: LayoutInflater = LayoutInflater.from(context)
+ val binding: ListHeaderBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_header, var1, false)
+ return TextHeaderHolder(binding)
+ }
+
+ override fun onBindHeaderViewHolder(var1: TextHeaderHolder, var2: Int, var3: Long) {
+ val date = Date(messagesList.get(var2).getSentAt() * 1000)
+
+ val formattedDate = DateUtil.getCustomizeDate(date.getTime())
+
+ var1.binding.txtMessageDate.setBackground(context.resources.getDrawable(R.drawable.cc_rounded_date_button))
+
+ var1.binding.txtMessageDate.setText(formattedDate)
+ }
+
+
+ fun setLongClick(view: View, baseMessage: BaseMessage) {
+ var message: Any? = null
+ if (baseMessage is TextMessage)
+ message = baseMessage
+
+ if (baseMessage is MediaMessage)
+ message = baseMessage
+
+ view.setOnLongClickListener {
+ message?.let { it1 -> onClickEvent.onClickRl(view, it1) }
+ true
+ }
+ }
+
+
+ override fun getItemCount(): Int {
+ return messagesList.size
+ }
+
+ override fun onBindViewHolder(p0: RecyclerView.ViewHolder, p1: Int) {
+ val baseMessage = messagesList.get(p1)
+ val timeStampLong = messagesList.get(p1).sentAt
+ var message: String? = null
+ var mediaFile: String? = null
+
+ var filePath: String? = null
+ if (baseMessage is MediaMessage) {
+ try {
+ if (baseMessage.metadata?.has("path")!!)
+ filePath = baseMessage.metadata.getString("path")
+ } catch (e: Exception) {
+
+ }
+
+ }
+
+ if (baseMessage is Call) {
+ val user = baseMessage.callInitiator as User
+
+ if (user.uid.equals(ownerId, ignoreCase = true)) {
+ message = "You initiated call "
+ } else {
+ message = user.name + " initiated call "
+ }
+ }
+
+ if (baseMessage is MediaMessage) {
+ mediaFile = baseMessage.url
+
+ }
+
+ when (p0.itemViewType) {
+
+ StringContract.ViewType.RIGHT_TEXT_MESSAGE -> {
+ val rightTextMessageHolder = p0 as RightTextMessageHolder
+ rightTextMessageHolder.binding.message = (baseMessage as TextMessage)
+ rightTextMessageHolder.binding.tvMessage.typeface = StringContract.Font.message
+ rightTextMessageHolder.binding.timestamp.typeface = StringContract.Font.status
+ rightTextMessageHolder.binding.tvMessage.background.setColorFilter(StringContract.Color.rightMessageColor, PorterDuff.Mode.SRC_ATOP)
+ setLongClick(rightTextMessageHolder.binding.root,baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_MESSAGE -> {
+ val leftTextMessageHolder = p0 as LeftTextMessageHolder
+ leftTextMessageHolder.binding.message = (baseMessage as TextMessage)
+ leftTextMessageHolder.binding.tvMessage.typeface = StringContract.Font.message
+ leftTextMessageHolder.binding.senderName.typeface = StringContract.Font.status
+ leftTextMessageHolder.binding.timestamp.typeface = StringContract.Font.status
+ leftTextMessageHolder.binding.tvMessage.background.setColorFilter(StringContract.Color.leftMessageColor, PorterDuff.Mode.SRC_ATOP)
+ setLongClick(leftTextMessageHolder.binding.root,baseMessage)
+
+ }
+
+ StringContract.ViewType.LEFT_IMAGE_MESSAGE -> {
+ val leftImageVideoMessageHolder = p0 as LeftImageVideoMessageHolder
+ leftImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ leftImageVideoMessageHolder.binding.senderName.typeface = StringContract.Font.status
+ leftImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+
+ leftImageVideoMessageHolder.binding.imageMessage.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(leftImageVideoMessageHolder.binding.imageMessage,baseMessage)
+
+ }
+
+ StringContract.ViewType.RIGHT_IMAGE_MESSAGE -> {
+ val rightImageVideoMessageHolder = p0 as RightImageVideoMessageHolder
+ rightImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ rightImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+
+ rightImageVideoMessageHolder.binding.imageMessage.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(rightImageVideoMessageHolder.binding.imageMessage,baseMessage)
+ }
+
+ StringContract.ViewType.RIGHT_FILE_MESSAGE -> {
+ try {
+
+ val rightFileViewHolder = p0 as RightFileViewHolder
+ rightFileViewHolder.binding.message = baseMessage as MediaMessage
+ rightFileViewHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.rightMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+ val t = mediaFile?.substring(mediaFile.lastIndexOf("/"))?.split("_".toRegex())?.dropLastWhile({ it.isEmpty() })?.toTypedArray()
+ rightFileViewHolder.binding.fileName.setText(t?.get(2))
+ rightFileViewHolder.binding.fileType.setText(mediaFile?.substring(mediaFile.lastIndexOf(".") + 1))
+ rightFileViewHolder.binding.fileName.typeface = StringContract.Font.name
+ rightFileViewHolder.binding.fileType.typeface = StringContract.Font.name
+ rightFileViewHolder.binding.timeStamp.typeface = StringContract.Font.status
+ val finalMediaFile = mediaFile
+ setLongClick(rightFileViewHolder.binding.root,baseMessage)
+ rightFileViewHolder.binding.fileName.setOnClickListener(View.OnClickListener { context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(finalMediaFile))) })
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+
+ StringContract.ViewType.RIGHT_LOCATION_MESSAGE -> {
+ val rightLocationViewHolder = p0 as RightLocationViewHolder
+ rightLocationViewHolder.binding.message = baseMessage as TextMessage
+ rightLocationViewHolder.binding.timestamp.typeface = StringContract.Font.status
+ rightLocationViewHolder.bindView(p1, messagesList)
+
+ }
+
+ StringContract.ViewType.LEFT_LOCATION_MESSAGE -> {
+ val leftLocationViewHolder = p0 as LeftLocationViewHolder
+ leftLocationViewHolder.binding.message = baseMessage as TextMessage
+ leftLocationViewHolder.binding.timestamp.typeface = StringContract.Font.status
+ leftLocationViewHolder.bindView(p1, messagesList)
+ }
+
+ StringContract.ViewType.RIGHT_TEXT_REPLY_MESSAGE -> {
+
+ val rightReplyMessageHolder = p0 as RightReplyMessageHolder
+ rightReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightReplyMessageHolder.binding.message = baseMessage
+ rightReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.rightMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is TextMessage) {
+
+ rightReplyMessageHolder.binding.txtNewmsg.visibility = View.VISIBLE
+ rightReplyMessageHolder.binding.txtNewmsg.text = baseMessage.text
+ rightReplyMessageHolder.binding.txtNewmsg.typeface = StringContract.Font.message
+ rightReplyMessageHolder.binding.tvNameReply.typeface = StringContract.Font.name
+ rightReplyMessageHolder.binding.ivNewMessage.visibility = View.GONE
+
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ rightReplyMessageHolder.binding.tvNameReply.text = "You"
+
+ } else {
+ rightReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ when {
+ baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT) -> {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text =
+ baseMessage.metadata?.getString("text")
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO) -> {
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.VISIBLE
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(rightReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO) -> {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE) -> {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ }
+
+ }
+
+ setLongClick(rightReplyMessageHolder.binding.root, baseMessage)
+
+ }
+
+ StringContract.ViewType.RIGHT_MEDIA_REPLY_MESSAGE -> {
+
+ val rightReplyMessageHolder = p0 as RightReplyMessageHolder
+ rightReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightReplyMessageHolder.binding.message = baseMessage
+ rightReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.rightMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is MediaMessage) {
+
+
+ if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_IMAGE)
+ || baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+
+ rightReplyMessageHolder.binding.imageContainer.visibility = View.VISIBLE
+
+ if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+ rightReplyMessageHolder.binding.ivVideoPlay.visibility = View.VISIBLE
+ rightReplyMessageHolder.binding.ivVideoPlay.setOnClickListener {
+ startIntent(baseMessage)
+ }
+ }
+ rightReplyMessageHolder.binding.tvReplyTextMessage.visibility = View.VISIBLE
+ Glide.with(context).load(baseMessage.url)
+ .into(rightReplyMessageHolder.binding.ivNewMessage)
+
+ } else if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ rightReplyMessageHolder.binding.fileContainer.visibility = View.VISIBLE
+
+ rightReplyMessageHolder.binding.fileName.text = FileUtil.getFileName(baseMessage.url)
+ rightReplyMessageHolder.binding.fileType.text = FileUtil.getFileExtension(baseMessage.url)
+
+ rightReplyMessageHolder.binding.fileName.setOnClickListener {
+
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(baseMessage.url)))
+ }
+ } else if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ rightReplyMessageHolder.binding.audioContainer.visibility = View.VISIBLE
+ rightReplyMessageHolder.binding.audioSeekBar.progress = 0
+ rightReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightReplyMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+
+ try {
+
+ if (GroupChatAdapter.audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(filePath)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ GroupChatAdapter.audioDurations.put(timeStampLong, duration)
+ rightReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = GroupChatAdapter.audioDurations.get(timeStampLong)
+ rightReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ rightReplyMessageHolder.binding.playButton.setOnClickListener {
+
+ if (!TextUtils.isEmpty(filePath)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying()!!) {
+ player?.pause()
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow_black)
+ } else {
+
+ player?.getCurrentPosition()?.let { player?.seekTo(it) }
+ player?.getCurrentPosition()?.let { rightReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ rightReplyMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { rightReplyMessageHolder.binding.audioSeekBar.setMax(it) }
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.getCurrentPosition()
+ pos?.let { rightReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ rightReplyMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+ player?.let {
+ playAudio(filePath, timeStampLong, it, rightReplyMessageHolder.binding.playButton,
+ rightReplyMessageHolder.binding.audioLength, rightReplyMessageHolder.binding.audioSeekBar)
+ }
+ }
+
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ }
+ }
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ rightReplyMessageHolder.binding.tvNameReply.text = "You"
+ } else {
+ rightReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ if (baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT)) {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text =
+ baseMessage.metadata?.getString("text")
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.VISIBLE
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(rightReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ }
+ }
+
+ setLongClick(rightReplyMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_REPLY_MESSAGE -> {
+
+ val leftReplyMessageHolder = p0 as LeftReplyMessageHolder
+ leftReplyMessageHolder.binding.message = baseMessage
+ leftReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.leftMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is TextMessage) {
+
+ leftReplyMessageHolder.binding.txtNewmsg.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.txtNewmsg.text = baseMessage.text
+ leftReplyMessageHolder.binding.txtNewmsg.typeface = StringContract.Font.message
+ leftReplyMessageHolder.binding.ivNewMessage.visibility = View.GONE
+ leftReplyMessageHolder.binding.tvNameReply.visibility=View.VISIBLE
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ leftReplyMessageHolder.binding.tvNameReply.text = "You"
+ } else {
+ leftReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ if (baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = baseMessage.metadata?.getString("text")
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.VISIBLE
+
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(leftReplyMessageHolder.binding.ivReplyImage)
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.visibility=View.VISIBLE
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+
+ }
+
+ setLongClick(leftReplyMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_MEDIA_REPLY_MESSAGE -> {
+
+ val leftReplyMessageHolder = p0 as LeftReplyMessageHolder
+ leftReplyMessageHolder.binding.message = baseMessage
+ leftReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.leftMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is MediaMessage) {
+
+ when {
+ baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_IMAGE)
+ || baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO) -> {
+
+ leftReplyMessageHolder.binding.imageContainer.visibility = View.VISIBLE
+
+ if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+ leftReplyMessageHolder.binding.ivVideoPlay.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.ivVideoPlay.setOnClickListener {
+ startIntent(baseMessage)
+ }
+
+ }
+ Glide.with(context).load(baseMessage.url)
+ .into(leftReplyMessageHolder.binding.ivNewMessage)
+
+ }
+ baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_FILE) -> {
+
+ leftReplyMessageHolder.binding.fileContainer.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.fileName.text = FileUtil.getFileName(baseMessage.url)
+ leftReplyMessageHolder.binding.fileType.text = FileUtil.getFileExtension(baseMessage.url)
+ leftReplyMessageHolder.binding.fileName.setOnClickListener {
+
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(baseMessage.url)))
+ }
+ }
+ baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_AUDIO) -> {
+
+ leftReplyMessageHolder.binding.audioContainer.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.audioSeekBar.progress = 0
+ leftReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ leftReplyMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+
+ try {
+
+ if (GroupChatAdapter.audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(baseMessage.url)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ GroupChatAdapter.audioDurations.put(timeStampLong, duration)
+ leftReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = GroupChatAdapter.audioDurations.get(timeStampLong)
+ leftReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ leftReplyMessageHolder.binding.playButton.setOnClickListener {
+
+ if (!TextUtils.isEmpty(baseMessage.url)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying()!!) {
+ player?.pause()
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow)
+ } else {
+
+ player?.getCurrentPosition()?.let { player?.seekTo(it) }
+ player?.getCurrentPosition()?.let { leftReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ leftReplyMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { leftReplyMessageHolder.binding.audioSeekBar.setMax(it) }
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.getCurrentPosition()
+ pos?.let { leftReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ leftReplyMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler.removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ player?.let {
+ playAudio(baseMessage.url, timeStampLong, it, leftReplyMessageHolder.binding.playButton,
+ leftReplyMessageHolder.binding.audioLength,
+ leftReplyMessageHolder.binding.audioSeekBar)
+ }
+ }
+
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ }
+ }
+ }
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ leftReplyMessageHolder.binding.tvNameReply.text = "You"
+ } else {
+ leftReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ if (baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text =
+ baseMessage.metadata?.getString("text")
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.visibility=View.VISIBLE
+
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(leftReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO)){
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text="Video"
+ }
+ else{
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text="Photo"
+ }
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ }
+
+ setLongClick(leftReplyMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_FILE_MESSAGE -> {
+ try {
+
+ val leftFileViewHolder = p0 as LeftFileViewHolder
+ leftFileViewHolder.binding.message = baseMessage as MediaMessage
+ leftFileViewHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.leftMessageColor, PorterDuff.Mode.SRC_ATOP)
+ val t = mediaFile?.substring(mediaFile.lastIndexOf("/"))?.split("_".toRegex())?.dropLastWhile({ it.isEmpty() })?.toTypedArray()
+ leftFileViewHolder.binding.fileName.setText(t?.get(2))
+ leftFileViewHolder.binding.fileType.setText(mediaFile?.substring(mediaFile.lastIndexOf(".") + 1))
+ val finalMediaFile = mediaFile
+ leftFileViewHolder.binding.fileName.typeface = StringContract.Font.name
+ leftFileViewHolder.binding.fileType.typeface = StringContract.Font.name
+ leftFileViewHolder.binding.timeStamp.typeface = StringContract.Font.status
+ leftFileViewHolder.binding.senderName.typeface = StringContract.Font.status
+ setLongClick(leftFileViewHolder.binding.root,baseMessage)
+ leftFileViewHolder.binding.fileName.setOnClickListener({ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(finalMediaFile))) })
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ StringContract.ViewType.LEFT_VIDEO_MESSAGE -> {
+ val leftImageVideoMessageHolder = p0 as LeftImageVideoMessageHolder
+ leftImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ leftImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ leftImageVideoMessageHolder.binding.senderName.typeface = StringContract.Font.status
+
+ val requestOptions = RequestOptions()
+ .fitCenter()
+ .placeholder(R.drawable.ic_broken_image)
+ Glide.with(context)
+ .load(baseMessage.url)
+ .apply(requestOptions)
+ .into(leftImageVideoMessageHolder.binding.imageMessage)
+
+ leftImageVideoMessageHolder.binding.btnPlayVideo.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(leftImageVideoMessageHolder.binding.root,baseMessage)
+ }
+
+ StringContract.ViewType.RIGHT_VIDEO_MESSAGE -> {
+ val rightImageVideoMessageHolder = p0 as RightImageVideoMessageHolder
+ rightImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ rightImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+
+ val requestOptions = RequestOptions()
+ .fitCenter()
+ .placeholder(R.drawable.ic_broken_image)
+ Glide.with(context)
+ .load(baseMessage.url)
+ .apply(requestOptions)
+ .into(rightImageVideoMessageHolder.binding.imageMessage)
+
+
+ rightImageVideoMessageHolder.binding.btnPlayVideo.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(rightImageVideoMessageHolder.binding.root,baseMessage)
+ }
+
+
+ StringContract.ViewType.RIGHT_AUDIO_MESSAGE -> {
+ val rightAudioMessageHolder = p0 as RightAudioMessageHolder
+ rightAudioMessageHolder.binding.message = (baseMessage as MediaMessage)
+ rightAudioMessageHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.rightMessageColor, PorterDuff.Mode.SRC_ATOP)
+ rightAudioMessageHolder.binding.audioSeekBar.progress = 0
+ rightAudioMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightAudioMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+ setLongClick(rightAudioMessageHolder.binding.root, baseMessage)
+
+ try {
+
+ if (GroupChatAdapter.audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(filePath)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ GroupChatAdapter.audioDurations.put(timeStampLong, duration)
+ rightAudioMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = GroupChatAdapter.audioDurations.get(timeStampLong)
+ rightAudioMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ rightAudioMessageHolder.binding.playButton.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(v: View?) {
+
+ if (!TextUtils.isEmpty(filePath)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying()!!) {
+ player?.pause()
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow)
+ } else {
+
+ player?.currentPosition?.let { player?.seekTo(it) }
+ player?.currentPosition?.let { rightAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ rightAudioMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { rightAudioMessageHolder.binding.audioSeekBar.setMax(it) }
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.getCurrentPosition()
+ pos?.let { rightAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ rightAudioMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ player?.let {
+ playAudio(filePath, timeStampLong, it, rightAudioMessageHolder.binding.playButton,
+ rightAudioMessageHolder.binding.audioLength, rightAudioMessageHolder.binding.audioSeekBar)
+ }
+ }
+
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ })
+
+ filePath?.let { Log.d("metaData", it) }
+
+ }
+
+ StringContract.ViewType.LEFT_AUDIO_MESSAGE -> {
+
+ val leftAudioMessageHolder = p0 as LeftAudioMessageHolder
+ leftAudioMessageHolder.binding.message = (baseMessage as MediaMessage)
+ leftAudioMessageHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.leftMessageColor, PorterDuff.Mode.SRC_ATOP)
+ leftAudioMessageHolder.binding.audioSeekBar.progress = 0
+ leftAudioMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+ leftAudioMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ setLongClick(leftAudioMessageHolder.itemView, baseMessage)
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+
+ val audioPath: String = FileUtil.getPath(context, CometChatConstants.MESSAGE_TYPE_AUDIO) +
+ FileUtil.getFileName(baseMessage.url)
+
+ val audioFile = File(audioPath)
+
+ if (audioFile.exists()) {
+
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+ leftAudioMessageHolder.binding.download.visibility = View.GONE
+ leftAudioMessageHolder.binding.playButton.visibility = View.VISIBLE
+
+ } else {
+
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+ leftAudioMessageHolder.binding.download.visibility = View.VISIBLE
+ leftAudioMessageHolder.binding.playButton.visibility = View.GONE
+
+ }
+
+ leftAudioMessageHolder.binding.download.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(v: View?) {
+
+ if (downloadFile?.status == AsyncTask.Status.RUNNING) {
+
+ downloadFile?.cancel(true)
+ leftAudioMessageHolder.binding.download.setImageResource(R.drawable.ic_file_download)
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+ leftAudioMessageHolder.binding.playButton.visibility = View.GONE
+ } else {
+
+ if (CCPermissionHelper.hasPermissions(CometChatPro.applicationContext(), CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
+ if (FileUtil.checkDirExistence(context, CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ downloadFile = DownloadFile(CometChatConstants.MESSAGE_TYPE_AUDIO, baseMessage.url,
+ leftAudioMessageHolder.binding)
+
+ downloadFile?.execute()
+
+ }
+ } else {
+ CCPermissionHelper.requestPermissions(context as Activity,
+ arrayOf(CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE), StringContract.RequestCode.FILE_WRITE)
+ }
+ }
+ }
+ })
+
+ leftAudioMessageHolder.binding.playButton.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(v: View?) {
+
+ if (!TextUtils.isEmpty(baseMessage.url)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying!!) {
+ player?.pause()
+
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow_black)
+ } else {
+ // player.setDataSource(message);
+ // player.prepare();
+ player?.currentPosition?.let { player?.seekTo(it) }
+ player?.currentPosition?.let { leftAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ leftAudioMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { leftAudioMessageHolder.binding.audioSeekBar.setMax(it) }
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.currentPosition
+ pos?.let { leftAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ leftAudioMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+ player?.let {
+ playAudio(if (audioFile.exists()) audioPath else baseMessage.url, timeStampLong, it, leftAudioMessageHolder.binding.playButton,
+ leftAudioMessageHolder.binding.audioLength, leftAudioMessageHolder.binding.audioSeekBar, true)
+ }
+ }
+
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ })
+
+ filePath?.let { Log.d("metaData", it) }
+
+ }
+
+
+ StringContract.ViewType.ACTION_MESSAGE -> {
+
+ val actionHolder = p0 as TextHeaderHolder
+
+ actionHolder.binding.txtMessageDate.setText((baseMessage as Action).message)
+ actionHolder.binding.txtMessageDate.setTextColor(StringContract.Color.black)
+ actionHolder.binding.txtMessageDate.typeface = StringContract.Font.status
+
+ }
+
+ StringContract.ViewType.CALL_MESSAGE -> {
+ val callHolder = p0 as TextHeaderHolder
+ callHolder.binding.txtMessageDate.setTextColor(StringContract.Color.black)
+ callHolder.binding.txtMessageDate.typeface = StringContract.Font.status
+
+ message = "Call " + (baseMessage as Call).callStatus
+
+ callHolder.binding.txtMessageDate.text = message
+
+ }
+
+
+
+
+ }
+ }
+
+ private fun startIntent(baseMessage: MediaMessage){
+
+ val imageIntent = Intent(context, ImageViewActivity::class.java)
+ imageIntent.putExtra(StringContract.IntentString.FILE_TYPE, baseMessage.type);
+ imageIntent.putExtra(StringContract.IntentString.URL, (baseMessage.url))
+ context.startActivity(imageIntent)
+ }
+
+
+ fun stopPlayer(){
+ try {
+ if (player!=null){
+ player?.stop()
+ player=null
+ }
+
+ }catch (e:Exception){
+
+ }
+ }
+
+ fun playAudio(message: String?, sentTimeStamp: Long, player: MediaPlayer, playButton: ImageView, audioLength: TextView, audioSeekBar: SeekBar,isleft:Boolean=false) {
+ try {
+ currentPlayingSong = message
+ currentlyPlayingId = sentTimeStamp
+ if (timerRunnable != null) {
+ seekHandler.removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ // setBtnColor(viewtype, playBtn, false);
+ player.reset()
+ player.setAudioStreamType(AudioManager.STREAM_MUSIC)
+ player.setDataSource(currentPlayingSong)
+ player.prepare()
+ player.start()
+
+ val duration = player.duration
+ audioSeekBar.max = duration
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player.currentPosition
+ audioSeekBar.progress = pos
+
+ if (player.isPlaying && pos < duration) {
+ audioLength.setText(DateUtil.convertTimeStampToDurationTime(player.currentPosition.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+
+ player.setOnCompletionListener { mp ->
+ currentPlayingSong = ""
+ currentlyPlayingId = 0L
+ // setBtnColor(viewtype, playBtn, true);
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ mp.stop()
+ audioLength.setText(DateUtil.convertTimeStampToDurationTime(duration.toLong()))
+ audioSeekBar.progress = 0
+ if (isleft) {
+ playButton.setImageResource(R.drawable.ic_play_arrow_black)
+ }
+ else{
+ playButton.setImageResource(R.drawable.ic_play_arrow)
+ }
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun getItemViewType(position: Int): Int {
+
+ if (messagesList.get(position).category.equals(CometChatConstants.CATEGORY_MESSAGE, ignoreCase = true)) {
+
+ if (ownerId.equals(messagesList.get(position).sender.uid, ignoreCase = true)) {
+
+ if ((messagesList.get(position) is TextMessage)
+ &&(messagesList[position] as TextMessage).metadata!=null
+ &&(messagesList[position] as TextMessage).metadata.has("reply")) {
+
+ return StringContract.ViewType.RIGHT_TEXT_REPLY_MESSAGE
+ }
+ else if ((messagesList[position] is MediaMessage)
+ &&(messagesList[position] as MediaMessage).metadata!=null
+ &&(messagesList[position] as MediaMessage).metadata.has("reply")){
+ return StringContract.ViewType.RIGHT_MEDIA_REPLY_MESSAGE
+ }
+ else {
+ when (messagesList.get(position).type) {
+
+ CometChatConstants.MESSAGE_TYPE_TEXT -> {
+ if ((messagesList.get(position) as TextMessage).text.equals("custom_location")) {
+ return StringContract.ViewType.RIGHT_LOCATION_MESSAGE
+ }
+ return StringContract.ViewType.RIGHT_TEXT_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_IMAGE -> {
+ return StringContract.ViewType.RIGHT_IMAGE_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_AUDIO -> {
+ return StringContract.ViewType.RIGHT_AUDIO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_VIDEO -> {
+ return StringContract.ViewType.RIGHT_VIDEO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_FILE -> {
+ return StringContract.ViewType.RIGHT_FILE_MESSAGE
+ }
+
+ }
+ }
+ } else {
+
+ if ((messagesList[position] is TextMessage)
+ &&(messagesList[position] as TextMessage).metadata!=null
+ &&(messagesList[position] as TextMessage).metadata.has("reply")) {
+
+ return StringContract.ViewType.LEFT_TEXT_REPLY_MESSAGE
+ }
+ else if ((messagesList[position] is MediaMessage)
+ &&(messagesList[position] as MediaMessage).metadata!=null
+ &&(messagesList[position] as MediaMessage).metadata.has("reply")){
+
+ return StringContract.ViewType.LEFT_MEDIA_REPLY_MESSAGE
+ }
+
+ else {
+ when (messagesList.get(position).type) {
+
+ CometChatConstants.MESSAGE_TYPE_TEXT -> {
+
+ if ((messagesList.get(position) as TextMessage).text.equals("custom_location")) {
+
+ return StringContract.ViewType.LEFT_LOCATION_MESSAGE
+ }
+ return StringContract.ViewType.LEFT_TEXT_MESSAGE
+
+ }
+
+ CometChatConstants.MESSAGE_TYPE_IMAGE -> {
+ return StringContract.ViewType.LEFT_IMAGE_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_AUDIO -> {
+ return StringContract.ViewType.LEFT_AUDIO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_VIDEO -> {
+ return StringContract.ViewType.LEFT_VIDEO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_FILE -> {
+ return StringContract.ViewType.LEFT_FILE_MESSAGE
+ }
+
+ }
+ }
+ }
+ } else if (messagesList.get(position).category.equals(CometChatConstants.CATEGORY_ACTION, ignoreCase = true)) {
+ return StringContract.ViewType.ACTION_MESSAGE
+
+ } else if (messagesList.get(position).category.equals(CometChatConstants.CATEGORY_CALL, ignoreCase = true)) {
+ return StringContract.ViewType.CALL_MESSAGE
+ }
+ return super.getItemViewType(position)
+ }
+
+ fun setMessageList(messageList: MutableList) {
+ this.messagesList = messageList
+
+ notifyDataSetChanged()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupListAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupListAdapter.kt
new file mode 100755
index 0000000..cbc79cd
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupListAdapter.kt
@@ -0,0 +1,55 @@
+package com.inscripts.cometchatpulse.Adapter
+
+import android.content.Context
+import android.databinding.DataBindingUtil
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.cometchat.pro.models.Group
+import com.inscripts.cometchatpulse.Helpers.ChildClickListener
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.databinding.GroupListItemBinding
+
+
+
+class GroupListAdapter(val context: Context?) : RecyclerView.Adapter() {
+
+ private var groupList: MutableList = arrayListOf()
+
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): GroupHolder {
+ val layoutInflater:LayoutInflater = LayoutInflater.from(context)
+
+ val binding: GroupListItemBinding = DataBindingUtil.inflate(layoutInflater,R.layout.group_list_item,p0,false)
+
+ return GroupHolder(binding)
+
+ }
+
+ override fun getItemCount(): Int {
+
+ return groupList.size
+ }
+
+ override fun onBindViewHolder(groupHolder: GroupHolder, p1: Int) {
+
+ val group = groupList[p1]
+
+ groupHolder.binding.group=group
+ groupHolder.binding.childClick=context as ChildClickListener
+ groupHolder.binding.textViewGroupName.typeface=StringContract.Font.name
+ groupHolder.binding.textViewUsersOnlineMessage.typeface=StringContract.Font.status
+ groupHolder.binding.executePendingBindings()
+ groupHolder.binding.root.setTag(R.string.group,group)
+
+ }
+
+ fun setGroup(it: MutableList) {
+ this.groupList = it
+ notifyDataSetChanged()
+ }
+
+
+ class GroupHolder(val binding:GroupListItemBinding) : RecyclerView.ViewHolder(binding.root)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupOptionAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupOptionAdapter.kt
new file mode 100755
index 0000000..5389c35
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/GroupOptionAdapter.kt
@@ -0,0 +1,58 @@
+package com.inscripts.cometchatpulse.Adapter
+
+import android.content.Context
+import android.databinding.DataBindingUtil
+import android.os.Bundle
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.inscripts.cometchatpulse.Fragment.MemberFragment
+import com.inscripts.cometchatpulse.Helpers.OnOptionClickListener
+import com.inscripts.cometchatpulse.Pojo.GroupOption
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.ViewHolder.GroupOptionViewHolder
+import com.inscripts.cometchatpulse.databinding.GroupOptionItemBinding
+
+
+class GroupOptionAdapter(val context:Context,val groupOptionList: MutableList,
+ val ownerId:String,val guid:String, onOptionClickListener: OnOptionClickListener): RecyclerView.Adapter() {
+
+ private var onOptionClickListener:OnOptionClickListener
+ init {
+ this.onOptionClickListener=onOptionClickListener
+ }
+
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): GroupOptionViewHolder {
+ val layoutInflater: LayoutInflater = LayoutInflater.from(context)
+
+ val binding: GroupOptionItemBinding =DataBindingUtil.inflate(layoutInflater, R.layout.group_option_item,p0,false)
+
+ return GroupOptionViewHolder(binding)
+ }
+
+ override fun getItemCount(): Int {
+ return groupOptionList.size
+ }
+
+ override fun onBindViewHolder(p0: GroupOptionViewHolder, p1: Int) {
+
+ val groupOption=groupOptionList.get(p1)
+
+ p0.binding.groupOption=groupOption
+
+ p0.binding.tvOption.typeface=StringContract.Font.name
+
+
+ p0.binding.root.setOnClickListener(object :View.OnClickListener{
+ override fun onClick(v: View?) {
+
+ onOptionClickListener.OnOptionClick(p0.adapterPosition)
+
+ }
+
+ })
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/MemberListAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/MemberListAdapter.kt
new file mode 100755
index 0000000..5899c36
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/MemberListAdapter.kt
@@ -0,0 +1,69 @@
+package com.inscripts.cometchatpulse.Adapter
+
+
+import android.databinding.DataBindingUtil
+import android.support.v4.app.Fragment
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.cometchat.pro.models.GroupMember
+import com.inscripts.cometchatpulse.Fragment.BanMemberFragment
+import com.inscripts.cometchatpulse.Fragment.MemberFragment
+import com.inscripts.cometchatpulse.Helpers.OnClickEvent
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.ViewHolder.GroupMemberHolder
+import com.inscripts.cometchatpulse.databinding.ContactItemBinding
+import com.inscripts.cometchatpulse.databinding.GroupMemberItemBinding
+
+class MemberListAdapter(val ownerId:String, val resId:Int,val listener: OnClickEvent): RecyclerView.Adapter() {
+
+ private var groupMemberList:MutableList = mutableListOf()
+
+ private var onClickevent:OnClickEvent = listener
+
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): GroupMemberHolder {
+ val layoutInflater: LayoutInflater = LayoutInflater.from(p0.context)
+ val binding: GroupMemberItemBinding = DataBindingUtil.inflate(layoutInflater,resId,p0,false)
+
+ return GroupMemberHolder(binding)
+ }
+
+ override fun getItemCount(): Int {
+ return groupMemberList.size
+ }
+
+ override fun onBindViewHolder(p0: GroupMemberHolder, p1: Int) {
+
+ val groupMember:GroupMember=groupMemberList.get(p1)
+
+ p0.binding.memeber=groupMember
+
+ p0.binding.textviewUserName.typeface=StringContract.Font.name
+
+ p0.binding.textviewUserStatus.typeface=StringContract.Font.status
+
+ p0.binding.root.setTag(R.string.user,groupMember.user)
+
+ p0.binding.executePendingBindings()
+
+ if (groupMember.uid.equals(ownerId))
+ p0.binding.textviewUserName.text="You"
+
+
+ p0.itemView.setOnClickListener {
+ onClickevent.onClickRl(p0.itemView,groupMember.user)
+ }
+
+ }
+
+ internal fun setMemberList(memberlist: MutableList) {
+ this.groupMemberList=memberlist
+ notifyDataSetChanged()
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/OneToOneAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/OneToOneAdapter.kt
new file mode 100755
index 0000000..23f0097
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/OneToOneAdapter.kt
@@ -0,0 +1,1369 @@
+package com.inscripts.cometchatpulse.Adapter
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.databinding.DataBindingUtil
+import android.graphics.Bitmap
+import android.graphics.PorterDuff
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.net.Uri
+import android.os.AsyncTask
+import android.os.Handler
+import android.support.v4.util.LongSparseArray
+import android.support.v7.widget.RecyclerView
+import android.text.TextUtils
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.SeekBar
+import android.widget.TextView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.RequestOptions
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.Call
+import com.cometchat.pro.models.BaseMessage
+import com.cometchat.pro.models.MediaMessage
+import com.cometchat.pro.models.TextMessage
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Activities.ImageViewActivity
+import com.inscripts.cometchatpulse.AsyncTask.DownloadFile
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.CustomView.StickyHeaderAdapter
+import com.inscripts.cometchatpulse.Helpers.CCPermissionHelper
+import com.inscripts.cometchatpulse.Helpers.OnClickEvent
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.DateUtil
+import com.inscripts.cometchatpulse.Utils.FileUtil
+import com.inscripts.cometchatpulse.ViewHolder.*
+import com.inscripts.cometchatpulse.databinding.*
+import org.json.JSONException
+import java.io.File
+import java.io.IOException
+import java.util.*
+
+class OneToOneAdapter(val context: Context, val ownerId: String,
+ val listener: OnClickEvent) : RecyclerView.Adapter(),
+ StickyHeaderAdapter {
+
+
+ private lateinit var viewHolder: RecyclerView.ViewHolder
+ private var messagesList: MutableList = mutableListOf()
+ private var currentPlayingSong: String? = null
+ private var timerRunnable: Runnable? = null
+ private val seekHandler = Handler()
+ private var onClickEvent: OnClickEvent
+ private var currentlyPlayingId = 0L
+ var player: MediaPlayer? = null
+
+ private var downloadFile: DownloadFile? = null
+
+ init {
+ if (player == null) {
+ player = MediaPlayer()
+ }
+ onClickEvent = listener
+ audioDurations = LongSparseArray()
+ videoThumbnails = LongSparseArray()
+ }
+
+ companion object {
+ private lateinit var audioDurations: LongSparseArray
+ private lateinit var videoThumbnails: LongSparseArray
+ }
+
+
+ override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
+
+ val layoutInflater: LayoutInflater = LayoutInflater.from(context)
+
+ when (p1) {
+
+ StringContract.ViewType.RIGHT_TEXT_MESSAGE -> {
+ val binding: RightTextBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_text, p0, false)
+ return RightTextMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_MESSAGE -> {
+ val binding: LeftTextBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_text, p0, false)
+ return LeftTextMessageHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_IMAGE_MESSAGE -> {
+ val binding: CcImageVideoLayoutRightBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_right, p0, false)
+ return RightImageVideoMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_IMAGE_MESSAGE -> {
+ val binding: CcImageVideoLayoutLeftBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_left, p0, false)
+ return LeftImageVideoMessageHolder(binding)
+
+ }
+
+ StringContract.ViewType.RIGHT_VIDEO_MESSAGE -> {
+
+ val binding: CcImageVideoLayoutRightBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_right, p0, false)
+ return RightImageVideoMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_VIDEO_MESSAGE -> {
+ val binding: CcImageVideoLayoutLeftBinding = DataBindingUtil.inflate(layoutInflater, R.layout.cc_image_video_layout_left, p0, false)
+ return LeftImageVideoMessageHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_AUDIO_MESSAGE -> {
+ val binding: RightAudioBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_audio, p0, false)
+ return RightAudioMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_AUDIO_MESSAGE -> {
+ val binding: LeftAudioBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_audio, p0, false)
+ return LeftAudioMessageHolder(binding)
+ }
+
+ StringContract.ViewType.CALL_MESSAGE -> {
+
+ val binding: ListHeaderBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_header, p0, false)
+ return TextHeaderHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_FILE_MESSAGE -> {
+ val binding: RightFileBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_file, p0, false)
+ return RightFileViewHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_FILE_MESSAGE -> {
+ val binding: LeftFileBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_file, p0, false)
+ return LeftFileViewHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_LOCATION_MESSAGE -> {
+ val binding: RightLocationBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_location, p0, false)
+ return RightLocationViewHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_LOCATION_MESSAGE -> {
+ val binding: LeftLocationBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_location, p0, false)
+ return LeftLocationViewHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_TEXT_REPLY_MESSAGE -> {
+
+ val binding: RightReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_reply, p0, false)
+ return RightReplyMessageHolder(binding)
+ }
+
+ StringContract.ViewType.RIGHT_MEDIA_REPLY_MESSAGE -> {
+
+ val binding: RightReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.right_reply, p0, false)
+ return RightReplyMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_REPLY_MESSAGE -> {
+
+ val binding: LeftReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_reply, p0, false)
+ return LeftReplyMessageHolder(binding)
+ }
+
+ StringContract.ViewType.LEFT_MEDIA_REPLY_MESSAGE -> {
+
+ val binding: LeftReplyBinding = DataBindingUtil.inflate(layoutInflater, R.layout.left_reply, p0, false)
+ return LeftReplyMessageHolder(binding)
+ }
+
+ else -> {
+ return viewHolder
+ }
+ }
+
+ }
+
+ override fun getHeaderId(var1: Int): Long {
+ return java.lang.Long.parseLong(DateUtil.getDateId(messagesList.get(var1).getSentAt() * 1000))
+ }
+
+ override fun onCreateHeaderViewHolder(var1: ViewGroup): TextHeaderHolder {
+ val layoutInflater: LayoutInflater = LayoutInflater.from(context)
+ val binding: ListHeaderBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_header, var1, false)
+ return TextHeaderHolder(binding)
+
+ }
+
+ override fun onBindHeaderViewHolder(var1: TextHeaderHolder, var2: Int, var3: Long) {
+ val date = Date(messagesList.get(var2).getSentAt() * 1000)
+
+ val formattedDate = DateUtil.getCustomizeDate(date.getTime())
+
+ var1.binding.txtMessageDate.setBackground(context.resources.getDrawable(R.drawable.cc_rounded_date_button))
+
+ var1.binding.txtMessageDate.setText(formattedDate)
+
+ }
+
+
+ override fun getItemCount(): Int {
+
+ return messagesList.size
+ }
+
+ override fun getItemViewType(position: Int): Int {
+
+ if (messagesList[position].category.equals(CometChatConstants.CATEGORY_MESSAGE, ignoreCase = true)) {
+
+ if (ownerId.equals(messagesList[position].sender.uid, ignoreCase = true)) {
+
+ if ((messagesList.get(position) is TextMessage)
+ && (messagesList[position] as TextMessage).metadata != null
+ && (messagesList[position] as TextMessage).metadata.has("reply")) {
+
+ return StringContract.ViewType.RIGHT_TEXT_REPLY_MESSAGE
+
+ } else if ((messagesList[position] is MediaMessage)
+ && (messagesList[position] as MediaMessage).metadata != null
+ && (messagesList[position] as MediaMessage).metadata.has("reply")) {
+
+ return StringContract.ViewType.RIGHT_MEDIA_REPLY_MESSAGE
+
+ } else {
+
+ when (messagesList.get(position).type) {
+
+ CometChatConstants.MESSAGE_TYPE_TEXT -> {
+
+ if ((messagesList[position] as TextMessage).text.equals("custom_location")) {
+ return StringContract.ViewType.RIGHT_LOCATION_MESSAGE
+ }
+
+ return StringContract.ViewType.RIGHT_TEXT_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_IMAGE -> {
+
+ return StringContract.ViewType.RIGHT_IMAGE_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_AUDIO -> {
+
+ return StringContract.ViewType.RIGHT_AUDIO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_VIDEO -> {
+
+ return StringContract.ViewType.RIGHT_VIDEO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_FILE -> {
+
+ return StringContract.ViewType.RIGHT_FILE_MESSAGE
+ }
+
+ }
+ }
+ } else {
+
+
+ if ((messagesList[position] is TextMessage)
+ && (messagesList[position] as TextMessage).metadata != null
+ && (messagesList[position] as TextMessage).metadata.has("reply")) {
+
+ return StringContract.ViewType.LEFT_TEXT_REPLY_MESSAGE
+ } else if ((messagesList[position] is MediaMessage)
+ && (messagesList[position] as MediaMessage).metadata != null
+ && (messagesList[position] as MediaMessage).metadata.has("reply")) {
+
+ return StringContract.ViewType.LEFT_MEDIA_REPLY_MESSAGE
+ } else {
+ when (messagesList[position].type) {
+
+ CometChatConstants.MESSAGE_TYPE_TEXT -> {
+
+ if ((messagesList[position] as TextMessage).text.equals("custom_location")) {
+
+ return StringContract.ViewType.LEFT_LOCATION_MESSAGE
+ }
+
+ return StringContract.ViewType.LEFT_TEXT_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_IMAGE -> {
+
+ return StringContract.ViewType.LEFT_IMAGE_MESSAGE
+
+ }
+
+ CometChatConstants.MESSAGE_TYPE_AUDIO -> {
+
+ return StringContract.ViewType.LEFT_AUDIO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_VIDEO -> {
+
+ return StringContract.ViewType.LEFT_VIDEO_MESSAGE
+ }
+
+ CometChatConstants.MESSAGE_TYPE_FILE -> {
+
+ return StringContract.ViewType.LEFT_FILE_MESSAGE
+ }
+
+ }
+ }
+ }
+ } else if (messagesList[position].category.equals(CometChatConstants.CATEGORY_CALL, ignoreCase = true)) {
+ return StringContract.ViewType.CALL_MESSAGE
+ }
+
+ return super.getItemViewType(position)
+ }
+
+ fun setMessageList(messageList: MutableList) {
+ this.messagesList = messageList
+ notifyDataSetChanged()
+
+ }
+
+
+ fun setLongClick(view: View, baseMessage: BaseMessage) {
+ var message: Any? = null
+ if (baseMessage is TextMessage)
+ message = baseMessage
+
+ if (baseMessage is MediaMessage)
+ message = baseMessage
+
+ view.setOnLongClickListener {
+ message?.let { it1 -> onClickEvent.onClickRl(view, it1) }
+ true
+ }
+ }
+
+ public fun stopPlayer() {
+ try {
+ if (player != null) {
+ player?.stop()
+ player = null
+ }
+
+ } catch (e: Exception) {
+
+ }
+ }
+
+
+ override fun onBindViewHolder(p0: RecyclerView.ViewHolder, p1: Int) {
+
+ val baseMessage = messagesList[p1]
+ val timeStampLong = messagesList[p1].sentAt
+ var message: String? = null
+ var filePath: String? = null
+ var mediaFile: String? = null
+
+ if (baseMessage is MediaMessage) {
+ if (baseMessage.metadata != null) {
+ try {
+ Log.d("metaAdapter", baseMessage.metadata.toString())
+
+ filePath = baseMessage.metadata.getString("path")
+ Log.d("OneToOneAdapter", filePath)
+ } catch (e: JSONException) {
+ e.printStackTrace()
+ }
+ }
+ mediaFile = baseMessage.url
+
+ }
+
+ if (baseMessage is Call) {
+ val user = baseMessage.callInitiator as User
+ val callReceiver = baseMessage.callReceiver as User
+
+ if (user.uid.equals(ownerId, ignoreCase = true)) {
+ message = "You Call " + callReceiver.name
+ } else {
+ message = "You received call from " + user.name
+ }
+ }
+
+ when (p0.itemViewType) {
+
+ StringContract.ViewType.RIGHT_TEXT_MESSAGE -> {
+ val rightTextMessageHolder = p0 as RightTextMessageHolder
+ rightTextMessageHolder.binding.message = (baseMessage as TextMessage)
+ rightTextMessageHolder.binding.tvMessage.typeface = StringContract.Font.message
+ rightTextMessageHolder.binding.timestamp.typeface = StringContract.Font.status
+ rightTextMessageHolder.binding.tvMessage.background.setColorFilter(StringContract.Color.rightMessageColor, PorterDuff.Mode.SRC_ATOP)
+ setLongClick(rightTextMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_MESSAGE -> {
+ val leftTextMessageHolder = p0 as LeftTextMessageHolder
+ leftTextMessageHolder.binding.message = (baseMessage as TextMessage)
+ leftTextMessageHolder.binding.tvMessage.typeface = StringContract.Font.message
+ leftTextMessageHolder.binding.senderName.typeface = StringContract.Font.status
+ leftTextMessageHolder.binding.timestamp.typeface = StringContract.Font.status
+ leftTextMessageHolder.binding.tvMessage.background.setColorFilter(StringContract.Color.leftMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ setLongClick(leftTextMessageHolder.binding.root, baseMessage)
+ }
+
+
+ StringContract.ViewType.RIGHT_TEXT_REPLY_MESSAGE -> {
+ val rightReplyMessageHolder = p0 as RightReplyMessageHolder
+ rightReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightReplyMessageHolder.binding.message = baseMessage
+ rightReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.rightMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is TextMessage) {
+
+ rightReplyMessageHolder.binding.txtNewmsg.visibility = View.VISIBLE
+ rightReplyMessageHolder.binding.txtNewmsg.text = baseMessage.text
+ rightReplyMessageHolder.binding.txtNewmsg.typeface = StringContract.Font.message
+ rightReplyMessageHolder.binding.tvNameReply.typeface = StringContract.Font.name
+ rightReplyMessageHolder.binding.ivNewMessage.visibility = View.GONE
+
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ rightReplyMessageHolder.binding.tvNameReply.text = "You"
+
+ } else {
+ rightReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName")
+ }
+
+ when {
+ baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT) -> {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text =
+ baseMessage.metadata?.getString("text")
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO) -> {
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.VISIBLE
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(rightReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO) -> {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE) -> {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ }
+
+ }
+
+ setLongClick(rightReplyMessageHolder.binding.root, baseMessage)
+
+ }
+
+ StringContract.ViewType.RIGHT_MEDIA_REPLY_MESSAGE -> {
+
+ val rightReplyMessageHolder = p0 as RightReplyMessageHolder
+ rightReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightReplyMessageHolder.binding.message = baseMessage
+ rightReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.rightMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is MediaMessage) {
+
+
+ if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_IMAGE)
+ || baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+
+ rightReplyMessageHolder.binding.ivNewMessage.visibility = View.VISIBLE
+
+ if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+ rightReplyMessageHolder.binding.ivVideoPlay.visibility=View.VISIBLE
+ rightReplyMessageHolder.binding.ivVideoPlay.setOnClickListener {
+ startIntent(baseMessage)
+ }
+
+ }
+
+ Glide.with(context).load(baseMessage.url)
+ .into(rightReplyMessageHolder.binding.ivNewMessage)
+ } else if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ rightReplyMessageHolder.binding.fileContainer.visibility = View.VISIBLE
+
+ rightReplyMessageHolder.binding.fileName.text = FileUtil.getFileName(baseMessage.url)
+ rightReplyMessageHolder.binding.fileType.text = FileUtil.getFileExtension(baseMessage.url)
+
+ rightReplyMessageHolder.binding.fileName.setOnClickListener {
+
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(baseMessage.url)))
+ }
+ } else if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ rightReplyMessageHolder.binding.audioContainer.visibility = View.VISIBLE
+ rightReplyMessageHolder.binding.audioSeekBar.progress = 0
+ rightReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightReplyMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+
+ try {
+
+ if (audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(filePath)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ audioDurations.put(timeStampLong, duration)
+ rightReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = audioDurations.get(timeStampLong)
+ rightReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ rightReplyMessageHolder.binding.playButton.setOnClickListener {
+
+ if (!TextUtils.isEmpty(filePath)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying()!!) {
+ player?.pause()
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow_black)
+ } else {
+
+ player?.getCurrentPosition()?.let { player?.seekTo(it) }
+ player?.getCurrentPosition()?.let { rightReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ rightReplyMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { rightReplyMessageHolder.binding.audioSeekBar.setMax(it) }
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.getCurrentPosition()
+ pos?.let { rightReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ rightReplyMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+ player?.let {
+ playAudio(filePath, timeStampLong, it, rightReplyMessageHolder.binding.playButton,
+ rightReplyMessageHolder.binding.audioLength, rightReplyMessageHolder.binding.audioSeekBar)
+ }
+ }
+
+ rightReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ }
+ }
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ rightReplyMessageHolder.binding.tvNameReply.text = "You"
+ } else {
+ rightReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ if (baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT)) {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text =
+ baseMessage.metadata?.getString("text")
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(rightReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ rightReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ rightReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ }
+ }
+
+ setLongClick(rightReplyMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_TEXT_REPLY_MESSAGE -> {
+
+ val leftReplyMessageHolder = p0 as LeftReplyMessageHolder
+ leftReplyMessageHolder.binding.message = baseMessage
+ leftReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.leftMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is TextMessage) {
+
+ leftReplyMessageHolder.binding.txtNewmsg.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.txtNewmsg.text = baseMessage.text
+ leftReplyMessageHolder.binding.txtNewmsg.typeface = StringContract.Font.message
+ leftReplyMessageHolder.binding.ivNewMessage.visibility = View.GONE
+ leftReplyMessageHolder.binding.tvNameReply.visibility = View.VISIBLE
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ leftReplyMessageHolder.binding.tvNameReply.text = "You"
+ } else {
+ leftReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ if (baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = baseMessage.metadata?.getString("text")
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(leftReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ } else if (baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE)) {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+
+ }
+
+ setLongClick(leftReplyMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_MEDIA_REPLY_MESSAGE -> {
+
+ val leftReplyMessageHolder = p0 as LeftReplyMessageHolder
+ leftReplyMessageHolder.binding.message = baseMessage
+ leftReplyMessageHolder.binding.rlMain.background.setColorFilter(StringContract.Color.leftMessageColor,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (baseMessage is MediaMessage) {
+
+ when {
+ baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_IMAGE)
+ || baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO) -> {
+
+ leftReplyMessageHolder.binding.ivNewMessage.visibility = View.VISIBLE
+
+ Glide.with(context).load(baseMessage.url)
+ .into(leftReplyMessageHolder.binding.ivNewMessage)
+
+ if (baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_VIDEO)) {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.visibility = View.VISIBLE;
+ leftReplyMessageHolder.binding.ivVideoPlay.setOnClickListener {
+ startIntent(baseMessage)
+ }
+ }
+
+ }
+ baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_FILE) -> {
+
+ leftReplyMessageHolder.binding.fileContainer.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.fileName.text = FileUtil.getFileName(baseMessage.url)
+ leftReplyMessageHolder.binding.fileType.text = FileUtil.getFileExtension(baseMessage.url)
+ leftReplyMessageHolder.binding.fileName.setOnClickListener {
+
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(baseMessage.url)))
+ }
+ }
+ baseMessage.type.equals(CometChatConstants.MESSAGE_TYPE_AUDIO) -> {
+
+ leftReplyMessageHolder.binding.audioContainer.visibility = View.VISIBLE
+ leftReplyMessageHolder.binding.audioSeekBar.progress = 0
+ leftReplyMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ leftReplyMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+
+ try {
+
+ if (audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(baseMessage.url)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ audioDurations.put(timeStampLong, duration)
+ leftReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = audioDurations.get(timeStampLong)
+ leftReplyMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ leftReplyMessageHolder.binding.playButton.setOnClickListener {
+
+ if (!TextUtils.isEmpty(baseMessage.url)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying()!!) {
+ player?.pause()
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow)
+ } else {
+
+ player?.getCurrentPosition()?.let { player?.seekTo(it) }
+ player?.getCurrentPosition()?.let { leftReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ leftReplyMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { leftReplyMessageHolder.binding.audioSeekBar.setMax(it) }
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.getCurrentPosition()
+ pos?.let { leftReplyMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ leftReplyMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler.removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ player?.let {
+ playAudio(baseMessage.url, timeStampLong, it, leftReplyMessageHolder.binding.playButton,
+ leftReplyMessageHolder.binding.audioLength,
+ leftReplyMessageHolder.binding.audioSeekBar)
+ }
+ }
+
+ leftReplyMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ }
+ }
+ }
+
+ if (baseMessage.metadata.has("senderUid")
+ && baseMessage.metadata.getString("senderUid").equals(ownerId)) {
+
+ leftReplyMessageHolder.binding.tvNameReply.text = "You"
+ } else {
+ leftReplyMessageHolder.binding.tvNameReply.text = baseMessage.metadata.getString("senderName");
+ }
+
+ when {
+ baseMessage.metadata.getString("type")
+ .equals(CometChatConstants.MESSAGE_TYPE_TEXT) -> {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text =
+ baseMessage.metadata?.getString("text")
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_IMAGE) ||
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_VIDEO) -> {
+
+
+ Glide.with(context).load(baseMessage.metadata.getString("url"))
+ .into(leftReplyMessageHolder.binding.ivReplyImage)
+
+ if (baseMessage.metadata.getString("type") == CometChatConstants.MESSAGE_TYPE_IMAGE) {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Photo"
+ } else {
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Video"
+ }
+
+ }
+
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_AUDIO) -> {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "Audio Message"
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+
+ }
+
+ baseMessage.metadata.getString("type").equals(CometChatConstants.MESSAGE_TYPE_FILE) -> {
+
+ leftReplyMessageHolder.binding.tvReplyTextMessage.text = "File Message"
+
+ leftReplyMessageHolder.binding.ivReplyImage.visibility = View.GONE
+ }
+ }
+ }
+
+ setLongClick(leftReplyMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.LEFT_IMAGE_MESSAGE -> {
+ val leftImageVideoMessageHolder = p0 as LeftImageVideoMessageHolder
+ leftImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ leftImageVideoMessageHolder.binding.senderName.typeface = StringContract.Font.status
+ leftImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ leftImageVideoMessageHolder.binding.imageMessage.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(leftImageVideoMessageHolder.binding.imageMessage, baseMessage)
+ }
+
+ StringContract.ViewType.RIGHT_IMAGE_MESSAGE -> {
+ val rightImageVideoMessageHolder = p0 as RightImageVideoMessageHolder
+ rightImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ rightImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightImageVideoMessageHolder.binding.imageMessage.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(rightImageVideoMessageHolder.binding.imageMessage, baseMessage)
+
+ }
+
+ StringContract.ViewType.RIGHT_LOCATION_MESSAGE -> {
+ val rightLocationViewHolder = p0 as RightLocationViewHolder
+ rightLocationViewHolder.binding.message = baseMessage as TextMessage
+ rightLocationViewHolder.binding.timestamp.typeface = StringContract.Font.status
+ rightLocationViewHolder.bindView(p1, messagesList)
+ }
+
+ StringContract.ViewType.LEFT_LOCATION_MESSAGE -> {
+ val leftLocationViewHolder = p0 as LeftLocationViewHolder
+ leftLocationViewHolder.binding.message = baseMessage as TextMessage
+ leftLocationViewHolder.binding.timestamp.typeface = StringContract.Font.status
+ leftLocationViewHolder.bindView(p1, messagesList)
+ }
+
+ StringContract.ViewType.RIGHT_FILE_MESSAGE -> {
+ try {
+
+ val rightFileViewHolder = p0 as RightFileViewHolder
+ rightFileViewHolder.binding.message = baseMessage as MediaMessage
+ rightFileViewHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.rightMessageColor, PorterDuff.Mode.SRC_ATOP)
+ rightFileViewHolder.binding.fileName.text = FileUtil.getFileName(mediaFile)
+ rightFileViewHolder.binding.fileType.text = FileUtil.getFileExtension(mediaFile)
+ val finalMediaFile = mediaFile
+ rightFileViewHolder.binding.fileName.typeface = StringContract.Font.name
+ rightFileViewHolder.binding.fileType.typeface = StringContract.Font.name
+ rightFileViewHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightFileViewHolder.binding.fileName.setOnClickListener(View.OnClickListener {
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(finalMediaFile)))
+ })
+ setLongClick(rightFileViewHolder.binding.root, baseMessage)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ StringContract.ViewType.LEFT_FILE_MESSAGE -> {
+
+ try {
+ val leftFileViewHolder = p0 as LeftFileViewHolder
+ leftFileViewHolder.binding.message = baseMessage as MediaMessage
+ leftFileViewHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.leftMessageColor, PorterDuff.Mode.SRC_ATOP)
+ leftFileViewHolder.binding.fileName.text = FileUtil.getFileName(mediaFile)
+ leftFileViewHolder.binding.fileType.text = FileUtil.getFileExtension(mediaFile)
+ val finalMediaFile = mediaFile
+ leftFileViewHolder.binding.fileName.typeface = StringContract.Font.name
+ leftFileViewHolder.binding.fileType.typeface = StringContract.Font.name
+ leftFileViewHolder.binding.timeStamp.typeface = StringContract.Font.status
+ leftFileViewHolder.binding.senderName.typeface = StringContract.Font.status
+ leftFileViewHolder.binding.fileName.setOnClickListener(View.OnClickListener {
+ context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(finalMediaFile)))
+ })
+ setLongClick(leftFileViewHolder.binding.root, baseMessage)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ StringContract.ViewType.LEFT_VIDEO_MESSAGE -> {
+ val leftImageVideoMessageHolder = p0 as LeftImageVideoMessageHolder
+ leftImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ leftImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+
+ val requestOptions = RequestOptions()
+ .fitCenter()
+ .placeholder(R.drawable.ic_broken_image)
+ Glide.with(context)
+ .load(baseMessage.url)
+ .apply(requestOptions)
+ .into(leftImageVideoMessageHolder.binding.imageMessage)
+
+ leftImageVideoMessageHolder.binding.btnPlayVideo.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(leftImageVideoMessageHolder.binding.root, baseMessage)
+ }
+
+ StringContract.ViewType.CALL_MESSAGE -> {
+ val listHeaderItem = p0 as TextHeaderHolder
+ listHeaderItem.binding.txtMessageDate.setTextColor(StringContract.Color.black)
+
+ message = "Call " + (baseMessage as Call).callStatus
+
+ listHeaderItem.binding.txtMessageDate.text = message
+ }
+
+ StringContract.ViewType.RIGHT_VIDEO_MESSAGE -> {
+ val rightImageVideoMessageHolder = p0 as RightImageVideoMessageHolder
+ rightImageVideoMessageHolder.binding.message = (baseMessage as MediaMessage)
+ rightImageVideoMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+
+ val requestOptions = RequestOptions()
+ .fitCenter()
+ .placeholder(R.drawable.ic_broken_image)
+ Glide.with(context)
+ .load(baseMessage.url)
+ .apply(requestOptions)
+ .into(rightImageVideoMessageHolder.binding.imageMessage)
+
+ rightImageVideoMessageHolder.binding.btnPlayVideo.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ startIntent(baseMessage)
+ }
+
+ })
+
+ setLongClick(rightImageVideoMessageHolder.binding.root, baseMessage)
+
+ }
+
+ StringContract.ViewType.RIGHT_AUDIO_MESSAGE -> {
+ val rightAudioMessageHolder = p0 as RightAudioMessageHolder
+ rightAudioMessageHolder.binding.message = (baseMessage as MediaMessage)
+ rightAudioMessageHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.rightMessageColor, PorterDuff.Mode.SRC_ATOP)
+ rightAudioMessageHolder.binding.audioSeekBar.progress = 0
+ rightAudioMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ rightAudioMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+ setLongClick(rightAudioMessageHolder.binding.root, baseMessage)
+ try {
+
+ if (audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(filePath)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ audioDurations.put(timeStampLong, duration)
+ rightAudioMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = audioDurations.get(timeStampLong)
+ rightAudioMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ rightAudioMessageHolder.binding.playButton.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(v: View?) {
+
+ if (!TextUtils.isEmpty(filePath)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying()!!) {
+ player?.pause()
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow)
+ } else {
+
+ player?.currentPosition?.let { player?.seekTo(it) }
+ player?.currentPosition?.let { rightAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ rightAudioMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { rightAudioMessageHolder.binding.audioSeekBar.setMax(it) }
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.getCurrentPosition()
+ pos?.let { rightAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ rightAudioMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ player?.let {
+ playAudio(filePath, timeStampLong, it, rightAudioMessageHolder.binding.playButton,
+ rightAudioMessageHolder.binding.audioLength, rightAudioMessageHolder.binding.audioSeekBar)
+ }
+ }
+
+ rightAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_white_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ })
+
+ filePath?.let { Log.d("metaData", it) }
+
+ }
+
+ StringContract.ViewType.LEFT_AUDIO_MESSAGE -> {
+
+ val leftAudioMessageHolder = p0 as LeftAudioMessageHolder
+ leftAudioMessageHolder.binding.message = (baseMessage as MediaMessage)
+ leftAudioMessageHolder.binding.fileContainer.background.setColorFilter(StringContract.Color.leftMessageColor, PorterDuff.Mode.SRC_ATOP)
+ leftAudioMessageHolder.binding.audioSeekBar.progress = 0
+ leftAudioMessageHolder.binding.audioLength.typeface = StringContract.Font.status
+ leftAudioMessageHolder.binding.timeStamp.typeface = StringContract.Font.status
+ setLongClick(leftAudioMessageHolder.itemView, baseMessage)
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+
+ val audioPath: String = FileUtil.getPath(context, CometChatConstants.MESSAGE_TYPE_AUDIO) +
+ FileUtil.getFileName(baseMessage.url)
+
+ val audioFile = File(audioPath)
+
+ if (audioFile.exists()) {
+
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+ leftAudioMessageHolder.binding.download.visibility = View.GONE
+ leftAudioMessageHolder.binding.playButton.visibility = View.VISIBLE
+
+ try {
+
+ if (audioDurations.get(timeStampLong) == null) {
+ player?.reset()
+ try {
+ player?.setDataSource(filePath)
+ player?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ val duration = player?.duration
+ audioDurations.put(timeStampLong, duration)
+ leftAudioMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ } else {
+ val duration = audioDurations.get(timeStampLong)
+ leftAudioMessageHolder.binding.audioLength.setText(duration?.toLong()?.let
+ { DateUtil.convertTimeStampToDurationTime(it) })
+
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+ leftAudioMessageHolder.binding.download.visibility = View.VISIBLE
+ leftAudioMessageHolder.binding.playButton.visibility = View.GONE
+
+ }
+
+ leftAudioMessageHolder.binding.download.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(v: View?) {
+
+ if (downloadFile?.status == AsyncTask.Status.RUNNING) {
+
+ downloadFile?.cancel(true)
+ leftAudioMessageHolder.binding.download.setImageResource(R.drawable.ic_file_download)
+ leftAudioMessageHolder.binding.progress.visibility = View.GONE
+ leftAudioMessageHolder.binding.playButton.visibility = View.GONE
+ } else {
+
+ if (CCPermissionHelper.hasPermissions(CometChatPro.applicationContext(), CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
+ if (FileUtil.checkDirExistence(context, CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ downloadFile = DownloadFile(CometChatConstants.MESSAGE_TYPE_AUDIO, baseMessage.url,
+ leftAudioMessageHolder.binding)
+
+ downloadFile?.execute()
+
+ }
+ } else {
+ CCPermissionHelper.requestPermissions(context as Activity,
+ arrayOf(CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE), StringContract.RequestCode.FILE_WRITE)
+ }
+ }
+ }
+ })
+
+
+ leftAudioMessageHolder.binding.playButton.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(v: View?) {
+
+ if (!TextUtils.isEmpty(baseMessage.url)) {
+
+ try {
+ if (baseMessage.sentAt == currentlyPlayingId) {
+ currentPlayingSong = ""
+
+ try {
+ if (player?.isPlaying!!) {
+ player?.pause()
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_play_arrow_black)
+ } else {
+ // player.setDataSource(message);
+ // player.prepare();
+ player?.currentPosition?.let { player?.seekTo(it) }
+ player?.currentPosition?.let { leftAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ leftAudioMessageHolder.binding.audioLength.setText(player?.getDuration()?.toLong()?.let { DateUtil.convertTimeStampToDurationTime(it) })
+ player?.getDuration()?.let { leftAudioMessageHolder.binding.audioSeekBar.setMax(it) }
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player?.currentPosition
+ pos?.let { leftAudioMessageHolder.binding.audioSeekBar.setProgress(it) }
+ if (player?.isPlaying()!! && pos!! < player?.getDuration()!!) {
+ leftAudioMessageHolder.binding.audioLength.setText(DateUtil.convertTimeStampToDurationTime(player?.getCurrentPosition()!!.toLong()))
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler
+ .removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+ player!!.start()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ } else {
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+ player?.let {
+ playAudio(if (audioFile.exists()) audioPath else baseMessage.url, timeStampLong, it, leftAudioMessageHolder.binding.playButton,
+ leftAudioMessageHolder.binding.audioLength, leftAudioMessageHolder.binding.audioSeekBar, true)
+ }
+ }
+
+ leftAudioMessageHolder.binding.playButton.setImageResource(R.drawable.ic_pause_black_24dp)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ })
+
+ filePath?.let { Log.d("metaData", it) }
+
+ }
+
+ }
+ }
+
+ private fun startIntent(baseMessage: MediaMessage) {
+
+ val imageIntent = Intent(context, ImageViewActivity::class.java)
+ imageIntent.putExtra(StringContract.IntentString.FILE_TYPE, baseMessage.type);
+ imageIntent.putExtra(StringContract.IntentString.URL, (baseMessage.url))
+ context.startActivity(imageIntent)
+
+ }
+
+ fun playAudio(message: String?, sentTimeStamp: Long, player: MediaPlayer,
+ playButton: ImageView, audioLength: TextView, audioSeekBar: SeekBar, isLeft: Boolean = false) {
+ try {
+ currentPlayingSong = message
+ currentlyPlayingId = sentTimeStamp
+ if (timerRunnable != null) {
+ seekHandler.removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ // setBtnColor(viewtype, playBtn, false);
+ player.reset()
+ player.setAudioStreamType(AudioManager.STREAM_MUSIC)
+ player.setDataSource(currentPlayingSong)
+ player.prepare()
+ player.start()
+
+ val duration = player.duration
+ audioSeekBar.max = duration
+ timerRunnable = object : Runnable {
+ override fun run() {
+
+ val pos = player.currentPosition
+ audioSeekBar.progress = pos
+
+ if (player.isPlaying && pos < duration) {
+ audioLength.text = DateUtil.convertTimeStampToDurationTime(player.currentPosition.toLong())
+ seekHandler.postDelayed(this, 250)
+ } else {
+ seekHandler.removeCallbacks(timerRunnable)
+ timerRunnable = null
+ }
+ }
+
+ }
+ seekHandler.postDelayed(timerRunnable, 100)
+ notifyDataSetChanged()
+
+ player.setOnCompletionListener { mp ->
+ currentPlayingSong = ""
+ currentlyPlayingId = 0L
+ // setBtnColor(viewtype, playBtn, true);
+ seekHandler.removeCallbacks(timerRunnable)
+ timerRunnable = null
+ mp.stop()
+ audioLength.text = DateUtil.convertTimeStampToDurationTime(duration.toLong())
+ audioSeekBar.progress = 0
+ if (isLeft) {
+ playButton.setImageResource(R.drawable.ic_play_arrow_black)
+ } else {
+ playButton.setImageResource(R.drawable.ic_play_arrow)
+ }
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Adapter/ViewPagerAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/ViewPagerAdapter.kt
new file mode 100755
index 0000000..07f158e
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Adapter/ViewPagerAdapter.kt
@@ -0,0 +1,31 @@
+package com.inscripts.cometchatpulse.Adapter
+
+import android.support.v4.app.Fragment
+import android.support.v4.app.FragmentManager
+import android.support.v4.app.FragmentPagerAdapter
+import java.util.ArrayList
+
+class ViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager) {
+
+ private val mFragmentList = ArrayList()
+ private val mFragmentTitleList = ArrayList()
+
+ override fun getItem(position: Int): Fragment {
+ return mFragmentList[position]
+
+ }
+
+ override fun getCount(): Int {
+ return mFragmentList.size
+ }
+
+ fun addFragment(fragment: Fragment, title: String) {
+ mFragmentList.add(fragment)
+ mFragmentTitleList.add(title)
+ }
+
+ override fun getPageTitle(position: Int): CharSequence? {
+ return mFragmentTitleList[position]
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/AsyncTask/DownloadFile.kt b/app/src/main/java/com/inscripts/cometchatpulse/AsyncTask/DownloadFile.kt
new file mode 100644
index 0000000..f26da97
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/AsyncTask/DownloadFile.kt
@@ -0,0 +1,137 @@
+package com.inscripts.cometchatpulse.AsyncTask
+
+import android.os.AsyncTask
+import android.view.View
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.Utils.FileUtil
+import com.inscripts.cometchatpulse.databinding.LeftAudioBinding
+import java.io.*
+import java.net.HttpURLConnection
+import java.net.URL
+
+
+class DownloadFile() : AsyncTask() {
+
+ private lateinit var mediaUrl: String
+
+ private lateinit var leftAudioBinding: LeftAudioBinding
+
+ private lateinit var type: String
+
+ constructor(type: String, mediaUrl: String, leftAudioBinding: LeftAudioBinding) : this() {
+ this.mediaUrl = mediaUrl
+ this.leftAudioBinding = leftAudioBinding
+ this.type = type
+ }
+
+ override fun onPreExecute() {
+ super.onPreExecute()
+ }
+
+ override fun doInBackground(vararg params: String?): String? {
+ var inputStream: InputStream? = null
+ var outputStream: OutputStream? = null
+ var connection: HttpURLConnection? = null
+ var file: File? = null
+ try {
+ var url: URL = URL(mediaUrl)
+ connection = url.openConnection() as HttpURLConnection
+ connection.connect()
+
+ if (connection.responseCode != HttpURLConnection.HTTP_OK) {
+
+ return ("Server " + connection.responseCode
+ + " " + connection.responseMessage)
+ }
+ val fileLength = connection.contentLength
+
+ inputStream = connection.inputStream
+
+
+ file = File(FileUtil.getPath(CometChatPro.applicationContext(), type) +
+ FileUtil.getFileName(mediaUrl))
+
+ outputStream = FileOutputStream(file)
+
+ val data = ByteArray(4096)
+
+ var total: Long = 0
+
+ var count = 0
+
+ do {
+
+ count = inputStream.read(data)
+
+ if (count != 1) {
+
+ if (isCancelled) {
+ inputStream.close()
+ return null
+
+ }
+ total += count
+
+ if (fileLength > 0) {
+ publishProgress((total * 100 / fileLength).toInt())
+ outputStream.write(data, 0, count)
+ }
+ } else {
+ break
+ }
+
+ } while (count != -1)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+
+ } finally {
+ try {
+ if (outputStream != null) {
+ outputStream.close()
+ }
+ if (inputStream != null) {
+ inputStream.close()
+ }
+
+
+ } catch (io: IOException) {
+
+ io.printStackTrace()
+ }
+
+ if (connection != null) {
+ connection.disconnect()
+ }
+ }
+ return null
+ }
+
+ override fun onProgressUpdate(vararg values: Int?) {
+ super.onProgressUpdate(*values)
+ try {
+ leftAudioBinding.progress.visibility = View.VISIBLE
+ leftAudioBinding.progress.max=100
+ leftAudioBinding.download.setImageResource(R.drawable.ic_close_24dp)
+ leftAudioBinding.progress.progress = values[0]!!
+ leftAudioBinding.playButton.visibility = View.GONE
+ } catch (e: java.lang.Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun onPostExecute(result: String?) {
+ super.onPostExecute(result)
+
+ try {
+ leftAudioBinding.progress.visibility = View.GONE
+ leftAudioBinding.download.visibility = View.GONE
+ leftAudioBinding.playButton.visibility = View.VISIBLE
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CometChatPro.kt b/app/src/main/java/com/inscripts/cometchatpulse/CometChatPro.kt
new file mode 100755
index 0000000..36aa7f6
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CometChatPro.kt
@@ -0,0 +1,43 @@
+package com.inscripts.cometchatpulse
+
+import android.app.Application
+import android.content.Context
+import android.util.Log
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.exceptions.CometChatException
+import com.inscripts.cometchatpulse.Utils.Appearance
+
+
+class CometChatPro : Application() {
+
+ private val TAG="CometChatPro"
+ init {
+ instance = this
+ }
+
+ companion object {
+ private var instance: CometChatPro? = null
+
+ fun applicationContext(): Context {
+ return instance!!.applicationContext
+ }
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ Appearance(Appearance.AppTheme.PERSIAN_BLUE)
+
+ CometChat.init(applicationContext, StringContract.AppDetails.APP_ID.trim(), object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: String?) {
+ Log.d("INIT", "Initialization completed successfully");
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Log.d(TAG,"onError: "+p0?.message)
+ }
+ })
+
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomBinder/CustomBinder.kt b/app/src/main/java/com/inscripts/cometchatpulse/CustomBinder/CustomBinder.kt
new file mode 100755
index 0000000..92faee4
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomBinder/CustomBinder.kt
@@ -0,0 +1,204 @@
+package com.inscripts.cometchatpulse.CustomBinder
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.databinding.BindingAdapter
+import android.graphics.PorterDuff
+import android.graphics.Typeface
+import android.graphics.drawable.Drawable
+import android.support.v4.content.ContextCompat
+import android.support.v7.widget.Toolbar
+import android.util.Log
+import android.widget.ImageView
+import android.widget.MediaController
+import android.widget.TextView
+import android.widget.VideoView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.RequestOptions
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.helpers.Logger
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.CustomView.CircleImageView
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.DateUtil
+import com.inscripts.cometchatpulse.Utils.MediaUtil
+import java.sql.Timestamp
+
+@BindingAdapter(value = ["setTimeStamp"])
+fun setTimeStamp(timeView: TextView, timeLong: Long) {
+
+ val dt = java.util.Date(timeLong * 1000)
+ val time = Timestamp(dt.getTime())
+ Logger.debug("timestamp", time.toString() + "rime" + dt.getDate() + " inside")
+ val str = DateUtil.getMessageTime(time.toString(), "hh:mm a")
+ timeView.setText(str)
+}
+
+
+@BindingAdapter(value = ["setDeliveryStatus"])
+fun setDeliveryStatus(deliveryStatusView: CircleImageView, deliveryStatus: Int) {
+
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ deliveryStatusView.circleBackgroundColor = StringContract.Color.iconTint
+ } else {
+ deliveryStatusView.circleBackgroundColor = StringContract.Color.primaryColor
+ }
+
+ if (deliveryStatus == 0) {
+ deliveryStatusView.setImageDrawable(ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.ic_access_time_24dp))
+ } else if (deliveryStatus == 1) {
+ deliveryStatusView.setImageDrawable(ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.ic_check_24dp))
+ }
+
+}
+
+
+
+@BindingAdapter(value = ["setVideoMessage", "setContext"])
+fun setVideoMessage(videoVideoView: VideoView, url: String, context: Context) {
+ videoVideoView.setVideoPath(url)
+ videoVideoView.setMediaController(MediaController(context))
+ videoVideoView.keepScreenOn = true
+ videoVideoView.start()
+}
+
+@BindingAdapter(value = ["setOptionImage"])
+fun setOptionImage(ivOption: CircleImageView,drawable: Drawable) {
+
+ try {
+ drawable.setColorFilter(StringContract.Color.white, PorterDuff.Mode.SRC_ATOP)
+ ivOption.setImageBitmap(MediaUtil.getPlaceholderImage(CometChatPro.applicationContext(),drawable))
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ ivOption.circleBackgroundColor = StringContract.Color.primaryDarkColor
+ } else {
+ ivOption.circleBackgroundColor = StringContract.Color.primaryColor
+ }
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+}
+
+@BindingAdapter(value = ["setGroupIcon"])
+fun setGroupIcon(view: CircleImageView, groupIcon: String?) {
+ val default: Drawable = ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.ic_group_default)!!
+ view.circleBackgroundColor = StringContract.Color.primaryColor
+ if (groupIcon != null) {
+ val requestOptions = RequestOptions()
+ requestOptions.placeholder(default)
+ Glide.with(CometChatPro.applicationContext()).applyDefaultRequestOptions(requestOptions)
+ .load(groupIcon).into(view)
+ } else {
+ try {
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ default.setColorFilter(StringContract.Color.primaryDarkColor, PorterDuff.Mode.SRC_ATOP)
+ }
+ view.setImageBitmap(MediaUtil.getPlaceholderImage(CometChatPro.applicationContext(), default))
+ } catch (e: Exception) {
+ view.setImageBitmap(MediaUtil.getPlaceholderImage(CometChatPro.applicationContext(), default))
+ }
+ }
+}
+
+@BindingAdapter(value = ["setStatus", "setLastActive"])
+fun setStatus(tvStatus: TextView, status: String, lastActive: Long?) {
+
+ if (status.equals(CometChatConstants.USER_STATUS_ONLINE, ignoreCase = true)) {
+ tvStatus.text = status
+ } else if (status.equals(CometChatConstants.USER_STATUS_OFFLINE, ignoreCase = true)) {
+ if (lastActive != null) {
+ tvStatus.text = DateUtil.getLastSeenDate(lastActive, CometChatPro.applicationContext())
+ } else {
+ tvStatus.text = status
+ }
+
+ }
+}
+
+@BindingAdapter(value = ["setStatusIcon"])
+fun setStatusIcon(ivStatus: ImageView, status: String) {
+
+ val statusDrawable: Drawable
+
+ if (status.equals(CometChatConstants.USER_STATUS_ONLINE, ignoreCase = true)) {
+ statusDrawable = ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.cc_status_available)!!
+ } else {
+ statusDrawable = ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.cc_status_offline)!!
+ }
+
+ ivStatus.setImageDrawable(statusDrawable)
+}
+
+@SuppressLint("CheckResult")
+@BindingAdapter(value = ["setImage"])
+fun setImage(imageView: ImageView, url: String?) {
+
+ try {
+ if (url != null) {
+ Log.d("corner", "called")
+ val requestOptions = RequestOptions()
+ requestOptions.placeholder(ContextCompat.getDrawable(CometChatPro.applicationContext(),
+ R.drawable.ic_broken_image_black))
+ requestOptions.centerCrop()
+ Glide.with(CometChatPro.applicationContext())
+ .applyDefaultRequestOptions(requestOptions)
+ .load(url)
+ .into(imageView)
+ }
+
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+}
+
+@BindingAdapter(value = ["groupDetailIcon"])
+fun setGroupDeatail(view: ImageView, url: String?) {
+ val default: Drawable = ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.ic_group_default)!!
+ try {
+ if (url != null) {
+
+ val requestOptions = RequestOptions()
+ requestOptions.placeholder(default)
+ Glide.with(CometChatPro.applicationContext()).applyDefaultRequestOptions(requestOptions)
+ .load(url).into(view)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+}
+
+@SuppressLint("CheckResult")
+@BindingAdapter(value = ["setUserImage"])
+fun setImage(view: CircleImageView, avatar: String?) {
+
+ val default: Drawable = ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.default_avatar)!!
+ if (avatar != null) {
+ val requestOptions = RequestOptions()
+ requestOptions.placeholder(default)
+ Glide.with(CometChatPro.applicationContext()).applyDefaultRequestOptions(requestOptions)
+ .load(avatar).into(view)
+ } else {
+
+ try {
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ default.setColorFilter(StringContract.Color.primaryDarkColor, PorterDuff.Mode.SRC_ATOP)
+ }
+ view.circleBackgroundColor = StringContract.Color.primaryColor
+ view.setImageBitmap(MediaUtil.getPlaceholderImage(CometChatPro.applicationContext(), default))
+ } catch (e: Exception) {
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ default.setColorFilter(StringContract.Color.primaryDarkColor, PorterDuff.Mode.SRC_ATOP)
+ }
+ view.circleBackgroundColor = StringContract.Color.primaryColor
+ view.setImageDrawable(ContextCompat.getDrawable(CometChatPro.applicationContext(), R.drawable.default_avatar))
+ e.printStackTrace()
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomView/AttachmentTypeSelector.kt b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/AttachmentTypeSelector.kt
new file mode 100755
index 0000000..3cdf258
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/AttachmentTypeSelector.kt
@@ -0,0 +1,282 @@
+package com.inscripts.cometchatpulse.CustomView
+
+import android.animation.Animator
+import android.annotation.TargetApi
+import android.app.Activity
+import android.content.Context
+import android.graphics.PorterDuff
+import android.graphics.Rect
+import android.graphics.drawable.BitmapDrawable
+import android.os.Build
+import android.support.annotation.RequiresApi
+import android.support.v4.content.ContextCompat
+import android.view.*
+import android.view.animation.*
+import android.widget.LinearLayout
+import android.widget.PopupWindow
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.StringContract.RequestCode.Companion.ADD_DOCUMENT
+import com.inscripts.cometchatpulse.StringContract.RequestCode.Companion.ADD_GALLERY
+import com.inscripts.cometchatpulse.StringContract.RequestCode.Companion.ADD_SOUND
+import com.inscripts.cometchatpulse.StringContract.RequestCode.Companion.LOCATION
+import com.inscripts.cometchatpulse.StringContract.RequestCode.Companion.TAKE_PHOTO
+import com.inscripts.cometchatpulse.StringContract.RequestCode.Companion.TAKE_VIDEO
+import com.inscripts.cometchatpulse.Utils.AnimUtil
+import com.inscripts.cometchatpulse.Utils.Appearance
+//import com.inscripts.cometchatpulse.R
+//import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.Utils.MediaUtil
+
+class AttachmentTypeSelector(context: Context, private var listener: AttachmentClickedListener?) : PopupWindow() {
+//
+ private val ANIMATION_DURATION = 300
+
+ private val TAG = AttachmentTypeSelector::class.java.simpleName
+
+ private var imageButton: CircleImageView
+
+ private var audioButton: CircleImageView
+ private var documentButton: CircleImageView
+
+ private var cameraButton: CircleImageView
+ private var locationButton: CircleImageView
+ private var videoButton: CircleImageView
+
+
+ private var currentAnchor: View? = null
+ private var rect: Rect? = null
+ private var winHeight: Int = 0
+
+ init {
+ val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
+ val layout = inflater.inflate(R.layout.attachment_type_selector, null, true) as LinearLayout
+
+ this.imageButton = CommonUtil.findById(layout, R.id.gallery_button) as CircleImageView
+ this.audioButton = CommonUtil.findById(layout, R.id.audio_button) as CircleImageView
+ this.documentButton = CommonUtil.findById(layout, R.id.document_button) as CircleImageView
+ this.cameraButton = CommonUtil.findById(layout, R.id.camera_button) as CircleImageView
+ this.locationButton = CommonUtil.findById(layout, R.id.close_button) as CircleImageView
+ this.videoButton = CommonUtil.findById(layout, R.id.video) as CircleImageView
+
+ var color:Int?
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE)
+ {
+ color=StringContract.Color.iconTint
+ }
+ else{
+ color=StringContract.Color.primaryColor
+ }
+
+ val imageDrawable = ContextCompat.getDrawable(context,R.drawable.ic_outline_image_24px)
+ val cameraDrawable = ContextCompat.getDrawable(context,R.drawable.ic_outline_add_a_photo_24px)
+ val audioDrawable = ContextCompat.getDrawable(context,R.drawable.ic_mic_24dp)
+ val videoDrawable = ContextCompat.getDrawable(context,R.drawable.ic_outline_videocam_24px)
+ val documentDrawable = ContextCompat.getDrawable(context,R.drawable.ic_outline_insert_drive_file_24px)
+ val locationDrawable = ContextCompat.getDrawable(context,R.drawable.ic_location_on_black_24dp)
+
+ imageDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+ cameraDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+ audioDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+ videoDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+ documentDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+ locationDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+
+ this.imageButton.setImageBitmap(imageDrawable?.let { MediaUtil.getPlaceholderImage(context, it) })
+ this.audioButton.setImageBitmap(audioDrawable?.let { MediaUtil.getPlaceholderImage(context, it) })
+ this.documentButton.setImageBitmap(documentDrawable?.let { MediaUtil.getPlaceholderImage(context, it) })
+ this.locationButton.setImageBitmap(locationDrawable?.let { MediaUtil.getPlaceholderImage(context, it) })
+ this.cameraButton.setImageBitmap(cameraDrawable?.let { MediaUtil.getPlaceholderImage(context, it) })
+ this.videoButton.setImageBitmap(videoDrawable?.let { MediaUtil.getPlaceholderImage(context, it) })
+
+ this.imageButton.setOnClickListener(PropagatingClickListener(ADD_GALLERY))
+ this.audioButton.setOnClickListener(PropagatingClickListener(ADD_SOUND))
+ this.documentButton.setOnClickListener(PropagatingClickListener(ADD_DOCUMENT))
+ this.cameraButton.setOnClickListener(PropagatingClickListener(TAKE_PHOTO))
+ this.videoButton.setOnClickListener(PropagatingClickListener(TAKE_VIDEO))
+ this.locationButton.setOnClickListener(PropagatingClickListener(LOCATION))
+
+
+ this.imageButton.borderColor=color
+ this.audioButton.borderColor=color
+ this.documentButton.borderColor=color
+ this.cameraButton.borderColor=color
+ this.videoButton.borderColor=color
+ this.locationButton.borderColor=color
+
+
+
+
+ contentView = layout
+ width = LinearLayout.LayoutParams.MATCH_PARENT
+ height = LinearLayout.LayoutParams.WRAP_CONTENT
+ setBackgroundDrawable(BitmapDrawable())
+ animationStyle = 0
+ isClippingEnabled = false
+ inputMethodMode = PopupWindow.INPUT_METHOD_NOT_NEEDED
+ isFocusable = true
+ isTouchable = true
+ }
+
+
+
+ fun show(activity: Activity, anchor: View) {
+
+ val y: Int
+// if (KeyboardVisibilityEvent.isKeyboardVisible(activity)) {
+// y = 0
+// val imm = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
+// //Find the currently focused view, so we can grab the correct window token from it.
+// imm.hideSoftInputFromWindow(activity.currentFocus!!.windowToken, 0)
+// } else {
+// rect = Rect()
+// activity.window.decorView.getWindowVisibleDisplayFrame(rect)
+// winHeight = activity.window.decorView.height
+// y = winHeight - rect!!.bottom
+// }
+
+ rect = Rect()
+ activity.window.decorView.getWindowVisibleDisplayFrame(rect)
+ winHeight = activity.window.decorView.height
+ y = winHeight - rect!!.bottom
+
+
+ this.currentAnchor = anchor
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
+ isAttachedInDecor=false
+ }
+
+ showAtLocation(anchor, Gravity.BOTTOM, 0,y)
+
+
+ contentView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ contentView.viewTreeObserver.removeOnGlobalLayoutListener(this)
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ animateWindowInCircular(anchor, contentView)
+ } else {
+ animateWindowInTranslate(contentView)
+ }
+ }
+ })
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ animateButtonIn(imageButton, ANIMATION_DURATION / 2)
+ animateButtonIn(cameraButton, ANIMATION_DURATION / 2)
+ animateButtonIn(audioButton, ANIMATION_DURATION / 3)
+ animateButtonIn(videoButton, ANIMATION_DURATION / 3)
+ animateButtonIn(documentButton, ANIMATION_DURATION / 4)
+ animateButtonIn(locationButton, 0)
+ }
+ }
+
+ override fun dismiss() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ animateWindowOutCircular(currentAnchor, contentView)
+ } else {
+ animateWindowOutTranslate(contentView)
+ }
+ }
+
+ fun setListener(listener: AttachmentClickedListener?) {
+ this.listener = listener
+ }
+
+ private fun animateButtonIn(button: View, delay: Int) {
+ val animation = AnimationSet(true)
+ val scale = ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,
+ Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.0f)
+
+ animation.addAnimation(scale)
+ animation.interpolator = OvershootInterpolator(1f)
+ animation.duration = ANIMATION_DURATION.toLong()
+ animation.startOffset = delay.toLong()
+ button.startAnimation(animation)
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private fun animateWindowInCircular(anchor: View?, contentView: View) {
+ val coordinates = AnimUtil.getClickOrigin(anchor, contentView)
+ val animator = ViewAnimationUtils.createCircularReveal(contentView,
+ coordinates.first,
+ coordinates.second,
+ 0f,
+ Math.max(contentView.width, contentView.height).toFloat())
+ animator.duration = ANIMATION_DURATION.toLong()
+ animator.start()
+ }
+
+ private fun animateWindowInTranslate(contentView: View) {
+ val animation = TranslateAnimation(0f, 0f, contentView.height.toFloat(), 0f)
+ animation.duration = ANIMATION_DURATION.toLong()
+
+ getContentView().startAnimation(animation)
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private fun animateWindowOutCircular(anchor: View?, contentView: View) {
+ val coordinates = AnimUtil.getClickOrigin(anchor, contentView)
+ val animator = ViewAnimationUtils.createCircularReveal(getContentView(),
+ coordinates.first,
+ coordinates.second,
+ Math.max(getContentView().width, getContentView().height).toFloat(),
+ 0f)
+
+ animator.duration = ANIMATION_DURATION.toLong()
+ animator.addListener(object : Animator.AnimatorListener {
+ override fun onAnimationStart(animation: Animator) {}
+
+ override fun onAnimationEnd(animation: Animator) {
+ super@AttachmentTypeSelector.dismiss()
+ }
+
+ override fun onAnimationCancel(animation: Animator) {}
+
+ override fun onAnimationRepeat(animation: Animator) {}
+ })
+
+ animator.start()
+ }
+
+ private fun animateWindowOutTranslate(contentView: View) {
+ val animation = TranslateAnimation(0f, 0f, 0f, (contentView.top + contentView.height).toFloat())
+ animation.duration = ANIMATION_DURATION.toLong()
+ animation.setAnimationListener(object : Animation.AnimationListener {
+ override fun onAnimationStart(animation: Animation) {}
+
+ override fun onAnimationEnd(animation: Animation) {
+ super@AttachmentTypeSelector.dismiss()
+ }
+
+ override fun onAnimationRepeat(animation: Animation) {}
+ })
+
+ getContentView().startAnimation(animation)
+ }
+
+
+ private inner class PropagatingClickListener (private val type: Int) : View.OnClickListener {
+
+ override fun onClick(v: View) {
+ animateWindowOutTranslate(contentView)
+
+ if (listener != null) listener!!.onClick(type)
+ }
+
+ }
+
+ private inner class CloseClickListener : View.OnClickListener {
+ override fun onClick(v: View) {
+ dismiss()
+ }
+ }
+
+ interface AttachmentClickedListener {
+ fun onClick(type: Int)
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomView/CircleImageView.java b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/CircleImageView.java
new file mode 100755
index 0000000..18cc3d1
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/CircleImageView.java
@@ -0,0 +1,477 @@
+package com.inscripts.cometchatpulse.CustomView;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Build;
+import android.support.annotation.ColorInt;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.RequiresApi;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.widget.ImageView;
+
+import com.inscripts.cometchatpulse.R;
+
+public class CircleImageView extends ImageView {
+
+ private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
+
+ private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
+ private static final int COLORDRAWABLE_DIMENSION = 2;
+
+ private static final int DEFAULT_BORDER_WIDTH = 0;
+ private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
+ private static final int DEFAULT_CIRCLE_BACKGROUND_COLOR = Color.TRANSPARENT;
+ private static final boolean DEFAULT_BORDER_OVERLAY = false;
+
+ private final RectF mDrawableRect = new RectF();
+ private final RectF mBorderRect = new RectF();
+
+ private final Matrix mShaderMatrix = new Matrix();
+ private final Paint mBitmapPaint = new Paint();
+ private final Paint mBorderPaint = new Paint();
+ private final Paint mCircleBackgroundPaint = new Paint();
+
+ private int mBorderColor = DEFAULT_BORDER_COLOR;
+ private int mBorderWidth = DEFAULT_BORDER_WIDTH;
+ private int mCircleBackgroundColor = DEFAULT_CIRCLE_BACKGROUND_COLOR;
+
+ private Bitmap mBitmap;
+ private BitmapShader mBitmapShader;
+ private int mBitmapWidth;
+ private int mBitmapHeight;
+
+ private float mDrawableRadius;
+ private float mBorderRadius;
+
+ private ColorFilter mColorFilter;
+
+ private boolean mReady;
+ private boolean mSetupPending;
+ private boolean mBorderOverlay;
+ private boolean mDisableCircularTransformation;
+
+ public CircleImageView(Context context) {
+ super(context);
+
+ init();
+ }
+
+ public CircleImageView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
+
+ mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
+ mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
+ mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
+
+ // Look for deprecated civ_fill_color if civ_circle_background_color is not set
+ if (a.hasValue(R.styleable.CircleImageView_civ_circle_background_color)) {
+ mCircleBackgroundColor = a.getColor(R.styleable.CircleImageView_civ_circle_background_color,
+ DEFAULT_CIRCLE_BACKGROUND_COLOR);
+ } else if (a.hasValue(R.styleable.CircleImageView_civ_fill_color)) {
+ mCircleBackgroundColor = a.getColor(R.styleable.CircleImageView_civ_fill_color,
+ DEFAULT_CIRCLE_BACKGROUND_COLOR);
+ }
+
+ a.recycle();
+
+ init();
+ }
+
+ private void init() {
+ super.setScaleType(SCALE_TYPE);
+ mReady = true;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ setOutlineProvider(new OutlineProvider());
+ }
+
+ if (mSetupPending) {
+ setup();
+ mSetupPending = false;
+ }
+ }
+
+ @Override
+ public ScaleType getScaleType() {
+ return SCALE_TYPE;
+ }
+
+ @Override
+ public void setScaleType(ScaleType scaleType) {
+ if (scaleType != SCALE_TYPE) {
+ throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
+ }
+ }
+
+ @Override
+ public void setAdjustViewBounds(boolean adjustViewBounds) {
+ if (adjustViewBounds) {
+ throw new IllegalArgumentException("adjustViewBounds not supported.");
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mDisableCircularTransformation) {
+ super.onDraw(canvas);
+ return;
+ }
+
+ if (mBitmap == null) {
+ return;
+ }
+
+ if (mCircleBackgroundColor != Color.TRANSPARENT) {
+ canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mCircleBackgroundPaint);
+ }
+ canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);
+ if (mBorderWidth > 0) {
+ canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ setup();
+ }
+
+ @Override
+ public void setPadding(int left, int top, int right, int bottom) {
+ super.setPadding(left, top, right, bottom);
+ setup();
+ }
+
+ @Override
+ public void setPaddingRelative(int start, int top, int end, int bottom) {
+ super.setPaddingRelative(start, top, end, bottom);
+ setup();
+ }
+
+ public int getBorderColor() {
+ return mBorderColor;
+ }
+
+ public void setBorderColor(@ColorInt int borderColor) {
+ if (borderColor == mBorderColor) {
+ return;
+ }
+
+ mBorderColor = borderColor;
+ mBorderPaint.setColor(mBorderColor);
+ invalidate();
+ }
+
+ /**
+ * @deprecated Use {@link #setBorderColor(int)} instead
+ */
+ @Deprecated
+ public void setBorderColorResource(@ColorRes int borderColorRes) {
+ setBorderColor(getContext().getResources().getColor(borderColorRes));
+ }
+
+ public int getCircleBackgroundColor() {
+ return mCircleBackgroundColor;
+ }
+
+ public void setCircleBackgroundColor(@ColorInt int circleBackgroundColor) {
+ if (circleBackgroundColor == mCircleBackgroundColor) {
+ return;
+ }
+
+ mCircleBackgroundColor = circleBackgroundColor;
+ mCircleBackgroundPaint.setColor(circleBackgroundColor);
+ invalidate();
+ }
+
+ public void setCircleBackgroundColorResource(@ColorRes int circleBackgroundRes) {
+ setCircleBackgroundColor(getContext().getResources().getColor(circleBackgroundRes));
+ }
+
+ /**
+ * Return the color drawn behind the circle-shaped drawable.
+ *
+ * @return The color drawn behind the drawable
+ *
+ * @deprecated Use {@link #getCircleBackgroundColor()} instead.
+ */
+ @Deprecated
+ public int getFillColor() {
+ return getCircleBackgroundColor();
+ }
+
+ /**
+ * Set a color to be drawn behind the circle-shaped drawable. Note that
+ * this has no effect if the drawable is opaque or no drawable is set.
+ *
+ * @param fillColor The color to be drawn behind the drawable
+ *
+ * @deprecated Use {@link #setCircleBackgroundColor(int)} instead.
+ */
+ @Deprecated
+ public void setFillColor(@ColorInt int fillColor) {
+ setCircleBackgroundColor(fillColor);
+ }
+
+ /**
+ * Set a color to be drawn behind the circle-shaped drawable. Note that
+ * this has no effect if the drawable is opaque or no drawable is set.
+ *
+ * @param fillColorRes The color resource to be resolved to a color and
+ * drawn behind the drawable
+ *
+ * @deprecated Use {@link #setCircleBackgroundColorResource(int)} instead.
+ */
+ @Deprecated
+ public void setFillColorResource(@ColorRes int fillColorRes) {
+ setCircleBackgroundColorResource(fillColorRes);
+ }
+
+ public int getBorderWidth() {
+ return mBorderWidth;
+ }
+
+ public void setBorderWidth(int borderWidth) {
+ if (borderWidth == mBorderWidth) {
+ return;
+ }
+
+ mBorderWidth = borderWidth;
+ setup();
+ }
+
+ public boolean isBorderOverlay() {
+ return mBorderOverlay;
+ }
+
+ public void setBorderOverlay(boolean borderOverlay) {
+ if (borderOverlay == mBorderOverlay) {
+ return;
+ }
+
+ mBorderOverlay = borderOverlay;
+ setup();
+ }
+
+ public boolean isDisableCircularTransformation() {
+ return mDisableCircularTransformation;
+ }
+
+ public void setDisableCircularTransformation(boolean disableCircularTransformation) {
+ if (mDisableCircularTransformation == disableCircularTransformation) {
+ return;
+ }
+
+ mDisableCircularTransformation = disableCircularTransformation;
+ initializeBitmap();
+ }
+
+ @Override
+ public void setImageBitmap(Bitmap bm) {
+ super.setImageBitmap(bm);
+ initializeBitmap();
+ }
+
+ @Override
+ public void setImageDrawable(Drawable drawable) {
+ super.setImageDrawable(drawable);
+ initializeBitmap();
+ }
+
+ @Override
+ public void setImageResource(@DrawableRes int resId) {
+ super.setImageResource(resId);
+ initializeBitmap();
+ }
+
+ @Override
+ public void setImageURI(Uri uri) {
+ super.setImageURI(uri);
+ initializeBitmap();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ if (cf == mColorFilter) {
+ return;
+ }
+
+ mColorFilter = cf;
+ applyColorFilter();
+ invalidate();
+ }
+
+ @Override
+ public ColorFilter getColorFilter() {
+ return mColorFilter;
+ }
+
+ private void applyColorFilter() {
+ if (mBitmapPaint != null) {
+ mBitmapPaint.setColorFilter(mColorFilter);
+ }
+ }
+
+ private Bitmap getBitmapFromDrawable(Drawable drawable) {
+ if (drawable == null) {
+ return null;
+ }
+
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+ }
+
+ try {
+ Bitmap bitmap;
+
+ if (drawable instanceof ColorDrawable) {
+ bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
+ } else {
+ bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
+ }
+
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return bitmap;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private void initializeBitmap() {
+ if (mDisableCircularTransformation) {
+ mBitmap = null;
+ } else {
+ mBitmap = getBitmapFromDrawable(getDrawable());
+ }
+ setup();
+ }
+
+ private void setup() {
+ if (!mReady) {
+ mSetupPending = true;
+ return;
+ }
+
+ if (getWidth() == 0 && getHeight() == 0) {
+ return;
+ }
+
+ if (mBitmap == null) {
+ invalidate();
+ return;
+ }
+
+ mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+
+ mBitmapPaint.setAntiAlias(true);
+ mBitmapPaint.setShader(mBitmapShader);
+
+ mBorderPaint.setStyle(Paint.Style.STROKE);
+ mBorderPaint.setAntiAlias(true);
+ mBorderPaint.setColor(mBorderColor);
+ mBorderPaint.setStrokeWidth(mBorderWidth);
+
+ mCircleBackgroundPaint.setStyle(Paint.Style.FILL);
+ mCircleBackgroundPaint.setAntiAlias(true);
+ mCircleBackgroundPaint.setColor(mCircleBackgroundColor);
+
+ mBitmapHeight = mBitmap.getHeight();
+ mBitmapWidth = mBitmap.getWidth();
+
+ mBorderRect.set(calculateBounds());
+ mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
+
+ mDrawableRect.set(mBorderRect);
+ if (!mBorderOverlay && mBorderWidth > 0) {
+ mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);
+ }
+ mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
+
+ applyColorFilter();
+ updateShaderMatrix();
+ invalidate();
+ }
+
+ private RectF calculateBounds() {
+ int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
+ int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+
+ int sideLength = Math.min(availableWidth, availableHeight);
+
+ float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
+ float top = getPaddingTop() + (availableHeight - sideLength) / 2f;
+
+ return new RectF(left, top, left + sideLength, top + sideLength);
+ }
+
+ private void updateShaderMatrix() {
+ float scale;
+ float dx = 0;
+ float dy = 0;
+
+ mShaderMatrix.set(null);
+
+ if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
+ scale = mDrawableRect.height() / (float) mBitmapHeight;
+ dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
+ } else {
+ scale = mDrawableRect.width() / (float) mBitmapWidth;
+ dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
+ }
+
+ mShaderMatrix.setScale(scale, scale);
+ mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
+
+ mBitmapShader.setLocalMatrix(mShaderMatrix);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return inTouchableArea(event.getX(), event.getY()) && super.onTouchEvent(event);
+ }
+
+ private boolean inTouchableArea(float x, float y) {
+ return Math.pow(x - mBorderRect.centerX(), 2) + Math.pow(y - mBorderRect.centerY(), 2) <= Math.pow(mBorderRadius, 2);
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+ private class OutlineProvider extends ViewOutlineProvider {
+
+ @Override
+ public void getOutline(View view, Outline outline) {
+ Rect bounds = new Rect();
+ mBorderRect.roundOut(bounds);
+ outline.setRoundRect(bounds, bounds.width() / 2.0f);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomView/RecordAudio.kt b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/RecordAudio.kt
new file mode 100755
index 0000000..f47e1ac
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/RecordAudio.kt
@@ -0,0 +1,392 @@
+package com.inscripts.cometchatpulse.CustomView
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.PorterDuff
+import android.media.MediaPlayer
+import android.os.SystemClock
+import android.support.v7.content.res.AppCompatResources
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.*
+import com.inscripts.cometchatpulse.Helpers.CCPermissionHelper
+import com.inscripts.cometchatpulse.Helpers.RecordListener
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.AnimUtil
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import java.io.IOException
+
+class RecordAudio : RelativeLayout {
+
+ private var recordMic: ImageView? = null
+
+ private var counterTime: Chronometer? = null
+
+ private var slideToCancel: TextView? = null
+
+ private var arrow: ImageView? = null
+
+ private var initialX: Float = 0.toFloat()
+ private var difX = 0f
+
+ private var cancelOffset = DEFAULT_CANCEL_OFFSET.toFloat()
+
+ private var startTime: Long = 0
+ private var elapsedTime: Long = 0
+
+ private var recordListener: RecordListener? = null
+
+ private var isSwiped: Boolean = false
+ private var isLessThanSecondAllowed = false
+
+ private var isSoundEnabled = true
+
+ private var RECORD_START = R.raw.record_start
+
+ private var RECORD_FINISHED = R.raw.record_finished
+
+ private var RECORD_ERROR = R.raw.record_error
+
+ private var player: MediaPlayer? = null
+
+ private val animUtil: AnimUtil? = null
+
+ private var slideToCancelLayout: FrameLayout? = null
+
+
+ constructor(context: Context) : super(context) {
+ initViewComponent(context, null, -1, -1)
+ }
+
+
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
+
+ initViewComponent(context, attrs, -1, -1)
+ }
+
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
+
+ initViewComponent(context, attrs, defStyleAttr, -1)
+ }
+
+ private fun initViewComponent(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) {
+ val view = View.inflate(context, R.layout.record_audio, null)
+ addView(view)
+
+ val viewGroup = view.parent as ViewGroup
+ viewGroup.clipChildren = false
+
+ arrow = view.findViewById(R.id.left_arrow)
+ slideToCancel = view.findViewById(R.id.slide_to_cancel_text)
+ counterTime = view.findViewById(R.id.record_time)
+ recordMic = view.findViewById(R.id.record_mic)
+ slideToCancelLayout = view.findViewById(R.id.slide_to_cancel_Layout)
+
+ recordMic?.drawable?.setColorFilter(StringContract.Color.primaryColor,PorterDuff.Mode.SRC_ATOP)
+ arrow?.drawable?.setColorFilter(StringContract.Color.primaryColor,PorterDuff.Mode.SRC_ATOP)
+
+ hideViews(true)
+
+
+ if (attrs != null && defStyleAttr == -1 && defStyleRes == -1) {
+ val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecordAudio,
+ defStyleAttr, defStyleRes)
+
+ val slideArrowResource = typedArray.getResourceId(R.styleable.RecordAudio_slide_to_cancel_arrow, -1)
+ val slideToCancelText = typedArray.getString(R.styleable.RecordAudio_slide_to_cancel_text)
+ val slideMarginRight = typedArray.getDimension(R.styleable.RecordAudio_slide_to_cancel_margin_right, 30f).toInt()
+ val counterTimeColor = typedArray.getColor(R.styleable.RecordAudio_counter_time_color, -1)
+ val arrowColor = typedArray.getColor(R.styleable.RecordAudio_slide_to_cancel_arrow_color, -1)
+
+
+ val cancelBounds = typedArray.getDimensionPixelSize(R.styleable.RecordAudio_slide_to_cancel_bounds, -1)
+
+ if (cancelBounds != -1)
+ setCancelOffset(cancelBounds.toFloat(), false)
+
+
+ if (slideArrowResource != -1) {
+ val slideArrow = AppCompatResources.getDrawable(getContext(), slideArrowResource)
+ arrow!!.setImageDrawable(slideArrow)
+ }
+
+ if (slideToCancelText != null)
+ slideToCancel!!.text = slideToCancelText
+
+ if (counterTimeColor != -1)
+ setCounterTimeColor(counterTimeColor)
+
+
+ if (arrowColor != -1)
+ setSlideToCancelArrowColor(arrowColor)
+
+
+
+ setMarginRight(slideMarginRight, true)
+
+ typedArray.recycle()
+ }
+
+ }
+
+
+ private fun hideViews(hideSmallMic: Boolean) {
+ slideToCancelLayout!!.visibility = View.GONE
+ counterTime!!.visibility = View.GONE
+ if (hideSmallMic)
+ recordMic!!.visibility = View.GONE
+ }
+
+ private fun showViews() {
+ slideToCancelLayout!!.visibility = View.VISIBLE
+ recordMic!!.visibility = View.VISIBLE
+ counterTime!!.visibility = View.VISIBLE
+ }
+
+
+ private fun isLessThanOneSecond(time: Long): Boolean {
+ return time <= 1000
+ }
+
+
+ private fun playSound(soundRes: Int) {
+
+ if (isSoundEnabled) {
+ if (soundRes == 0)
+ return
+
+ try {
+ player = MediaPlayer()
+ val afd = context!!.resources.openRawResourceFd(soundRes) ?: return
+ player!!.setDataSource(afd.fileDescriptor, afd.startOffset, afd.length)
+ afd.close()
+ player!!.prepare()
+ player!!.start()
+ player!!.setOnCompletionListener { mp -> mp.release() }
+ player!!.isLooping = false
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+
+ }
+
+
+ }
+
+
+ fun onActionDown(recordMicButton: RecordMicButton, context: Context) {
+
+ if (recordListener != null) {
+ if (CCPermissionHelper.hasPermissions(context, *StringContract.RequestPermission.RECORD_PERMISSION)) {
+ recordListener!!.onRecordStart()
+ } else {
+ CCPermissionHelper.requestPermissions(context as Activity, StringContract.RequestPermission.RECORD_PERMISSION,
+ StringContract.RequestCode.RECORD_CODE)
+ }
+ }
+
+ AnimUtil.setStartRecorded(true)
+ AnimUtil.resetSmallMic(recordMic!!)
+
+
+ recordMicButton.startScale()
+
+ initialX = recordMicButton.getX()
+
+ playSound(RECORD_START)
+
+ showViews()
+
+ AnimUtil.animateMic(recordMic!!)
+
+ counterTime!!.base = SystemClock.elapsedRealtime()
+
+ startTime = System.currentTimeMillis()
+
+ counterTime!!.start()
+ isSwiped = false
+
+ }
+
+
+ fun onActionMove(recordMicButton: RecordMicButton, motionEvent: MotionEvent) {
+
+
+ val time = System.currentTimeMillis() - startTime
+
+ if (!isSwiped) {
+
+ //Swipe To Cancel
+ val slideX = slideToCancelLayout!!.x
+ val right = counterTime!!.right
+
+ if (slideX != 0f && slideX <= right + cancelOffset) {
+
+ //if the time was less than one second then do not start basket animation
+ if (isLessThanOneSecond(time)) {
+ hideViews(true)
+ recordMic?.let { AnimUtil.clearAlphaAnimation(false, it) }
+
+ } else {
+ hideViews(true)
+ recordMic?.let { AnimUtil.clearAlphaAnimation(true, it) }
+ }
+
+ AnimUtil.moveSlideToCancel(recordMicButton, slideToCancelLayout!!, initialX, difX)
+ counterTime!!.stop()
+ isSwiped = true
+
+ AnimUtil.setStartRecorded(false)
+ if (recordListener != null) {
+
+ recordListener!!.onRecordCancel()
+ }
+
+
+ } else {
+
+ if (motionEvent.getRawX() < initialX) {
+ recordMicButton.animate()
+ .x(motionEvent.getRawX())
+ .setDuration(0)
+ .start()
+
+ if (difX == 0f)
+ difX = initialX - slideToCancelLayout!!.x
+
+
+ slideToCancelLayout!!.animate()
+ .x(motionEvent.getRawX() - difX)
+ .setDuration(0)
+ .start()
+
+ }
+
+
+ }
+
+ }
+ }
+
+ fun onActionUp(recordMicButton: RecordMicButton) {
+
+ elapsedTime = System.currentTimeMillis() - startTime
+
+ if (!isLessThanSecondAllowed && isLessThanOneSecond(elapsedTime) && !isSwiped) {
+ if (recordListener != null)
+ recordListener!!.onRecordLessTime()
+ AnimUtil.setStartRecorded(false)
+ playSound(RECORD_ERROR)
+
+
+ } else {
+ if (recordListener != null && !isSwiped)
+ recordListener!!.onRecordFinish(elapsedTime)
+
+ AnimUtil.setStartRecorded(false)
+
+ if (!isSwiped)
+ playSound(RECORD_FINISHED)
+
+ }
+
+
+ //if user has swiped then do not hide SmallMic since it will be hidden after swipe Animation
+ hideViews(!isSwiped)
+
+
+ if (!isSwiped)
+ recordMic?.let { AnimUtil.clearAlphaAnimation(true, it) }
+
+ slideToCancelLayout?.let { AnimUtil.moveSlideToCancel(recordMicButton, it, initialX, difX) }
+ counterTime!!.stop()
+
+
+ }
+
+
+ private fun setMarginRight(marginRight: Int, convertToDp: Boolean) {
+ val layoutParams = slideToCancelLayout!!.layoutParams as RelativeLayout.LayoutParams
+ if (convertToDp) {
+ layoutParams.rightMargin = CommonUtil.dpToPx(context, marginRight.toFloat()).toInt()
+ } else
+ layoutParams.rightMargin = marginRight
+
+ slideToCancelLayout!!.layoutParams = layoutParams
+ }
+
+
+ fun setOnRecordListener(recrodListener: RecordListener) {
+ this.recordListener = recrodListener
+ }
+
+
+ fun setSoundEnabled(isEnabled: Boolean) {
+ isSoundEnabled = isEnabled
+ }
+
+ fun setLessThanSecondAllowed(isAllowed: Boolean) {
+ isLessThanSecondAllowed = isAllowed
+ }
+
+ fun setSlideToCancelText(text: String) {
+ slideToCancel!!.text = text
+ }
+
+ fun setSlideToCancelTextColor(color: Int) {
+ slideToCancel!!.setTextColor(color)
+ }
+
+ fun setSmallMicColor(color: Int) {
+ recordMic!!.setColorFilter(color)
+ }
+
+ fun setSmallMicIcon(icon: Int) {
+ recordMic!!.setImageResource(icon)
+ }
+
+ fun setSlideMarginRight(marginRight: Int) {
+ setMarginRight(marginRight, true)
+ }
+
+
+ fun setCustomSounds(startSound: Int, finishedSound: Int, errorSound: Int) {
+ //0 means do not play sound
+ RECORD_START = startSound
+ RECORD_FINISHED = finishedSound
+ RECORD_ERROR = errorSound
+ }
+
+ fun getCancelOffset(): Float {
+ return cancelOffset
+ }
+
+ fun setCancelOffset(cancelBounds: Float) {
+ setCancelOffset(cancelBounds, true)
+ }
+
+ //set Chronometer color
+ fun setCounterTimeColor(color: Int) {
+ counterTime!!.setTextColor(color)
+ }
+
+ fun setSlideToCancelArrowColor(color: Int) {
+ arrow!!.setColorFilter(color)
+ }
+
+
+ private fun setCancelOffset(cancelBounds: Float, DpToPixel: Boolean) {
+ val bounds = if (DpToPixel) CommonUtil.dpToPx(context, cancelBounds) else cancelBounds
+ this.cancelOffset = bounds
+ }
+
+ companion object {
+
+ val DEFAULT_CANCEL_OFFSET = 8
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomView/RecordMicButton.kt b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/RecordMicButton.kt
new file mode 100755
index 0000000..2325c79
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/RecordMicButton.kt
@@ -0,0 +1,132 @@
+package com.inscripts.cometchatpulse.CustomView
+
+import android.content.Context
+import android.support.v7.content.res.AppCompatResources
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import com.inscripts.cometchatpulse.Helpers.OnRecordClickListener
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.Utils.AnimUtil
+
+
+class RecordMicButton : android.support.v7.widget.AppCompatImageView, View.OnTouchListener, View.OnClickListener {
+
+ private var scaleView: View? = null
+
+ var isRecord = true
+
+
+ private var onRecordClickListener: OnRecordClickListener? = null
+
+ private var recordAudio: RecordAudio? = null
+
+ fun setRecordAudio(recordAudio: RecordAudio?) {
+ this.recordAudio = recordAudio
+
+ }
+
+ constructor(context: Context) : super(context) {
+ initViewComponent(context, null)
+
+ }
+
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
+ initViewComponent(context, attrs)
+
+ }
+
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
+ initViewComponent(context, attrs)
+
+ }
+
+
+ private fun initViewComponent(context: Context, attrs: AttributeSet?) {
+ if (attrs != null) {
+ val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecordMic)
+
+ val imageResource = typedArray.getResourceId(R.styleable.RecordMic_mic_icon, -1)
+
+
+ if (imageResource != -1) {
+ setImage(imageResource)
+ }
+
+ scaleView = this
+
+
+ typedArray.recycle()
+ }
+
+ this.setOnTouchListener(this)
+ this.setOnClickListener(this)
+
+ }
+
+
+ private fun setImage(imageResource: Int) {
+ val image = AppCompatResources.getDrawable(getContext(), imageResource)
+ setImageDrawable(image)
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ setClip(this)
+ }
+
+ fun setClip(v: View) {
+ if (v.parent == null) {
+ return
+ }
+
+ if (v is ViewGroup) {
+ v.clipChildren = false
+ v.clipToPadding = false
+ }
+
+ if (v.parent is View) {
+ setClip(v.parent as View)
+ }
+ }
+
+ fun startScale() {
+ scaleView?.let { AnimUtil.start(it) }
+ }
+
+ fun stopScale() {
+ scaleView?.let { AnimUtil.stop(it) }
+ }
+
+ fun setListenForRecord(listenForRecord: Boolean) {
+ this.isRecord = listenForRecord
+
+ }
+
+ fun setOnRecordClickListener(onRecordClickListener: OnRecordClickListener) {
+ this.onRecordClickListener = onRecordClickListener
+ }
+
+
+ override fun onClick(view: View) {
+ if (onRecordClickListener != null)
+ onRecordClickListener!!.onRecordClick(view)
+
+ }
+
+ override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
+ if (isRecord) {
+ when (motionEvent.action) {
+
+ MotionEvent.ACTION_DOWN ->{ recordAudio!!.onActionDown(view as RecordMicButton, context)}
+
+ MotionEvent.ACTION_MOVE -> {recordAudio!!.onActionMove(view as RecordMicButton, motionEvent)}
+
+ MotionEvent.ACTION_UP -> {recordAudio!!.onActionUp(view as RecordMicButton)}
+ }
+
+ }
+ return isRecord
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomView/StickyHeaderAdapter.kt b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/StickyHeaderAdapter.kt
new file mode 100755
index 0000000..ad16e38
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/StickyHeaderAdapter.kt
@@ -0,0 +1,13 @@
+package com.inscripts.cometchatpulse.CustomView
+
+import android.support.v7.widget.RecyclerView
+import android.view.ViewGroup
+
+interface StickyHeaderAdapter {
+
+ fun getHeaderId(var1: Int): Long
+
+ fun onCreateHeaderViewHolder(var1: ViewGroup): T
+
+ fun onBindHeaderViewHolder(var1: T, var2: Int, var3: Long)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/CustomView/StickyHeaderDecoration.kt b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/StickyHeaderDecoration.kt
new file mode 100755
index 0000000..5559c7b
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/CustomView/StickyHeaderDecoration.kt
@@ -0,0 +1,147 @@
+package com.inscripts.cometchatpulse.CustomView
+
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.support.v4.view.ViewCompat
+import android.support.v7.widget.RecyclerView
+import android.view.View
+import android.view.ViewGroup
+import com.inscripts.cometchatpulse.ViewHolder.TextHeaderHolder
+import java.util.HashMap
+
+class StickyHeaderDecoration constructor(private val mAdapter: StickyHeaderAdapter
+ ) : RecyclerView.ItemDecoration() {
+
+ private val mHeaderCache: MutableMap
+ private val mRenderInline: Boolean = false
+ init {
+ this.mHeaderCache = HashMap()
+ }
+
+ override fun getItemOffsets(var1: Rect, var2: View, var3: RecyclerView, var4: RecyclerView.State) {
+ val var5 = var3.getChildAdapterPosition(var2)
+ var var6 = 0
+ if (var5 != -1 && this.hasHeader(var5) && this.showHeaderAboveItem(var5)) {
+ val var7 = this.getHeader(var3, var5).itemView
+ var6 = this.getHeaderHeightForLayout(var7)
+ }
+
+ var1.set(0, var6, 0, 0)
+ }
+
+ private fun showHeaderAboveItem(var1: Int): Boolean {
+ return if (var1 == 0) {
+ true
+ } else {
+ this.mAdapter.getHeaderId(var1 - 1) !== this.mAdapter.getHeaderId(var1)
+ }
+ }
+
+ fun clearHeaderCache() {
+ this.mHeaderCache.clear()
+ }
+
+ fun findHeaderViewUnder(var1: Float, var2: Float): View? {
+ val var3 = this.mHeaderCache.values.iterator()
+
+ var var5: View
+ var var6: Float
+ var var7: Float
+ do {
+ if (!var3.hasNext()) {
+ return null
+ }
+
+ var5 = var3.next().itemView
+ var6 = ViewCompat.getTranslationX(var5)
+ var7 = ViewCompat.getTranslationY(var5)
+ } while (var1 < var5.left.toFloat() + var6 || var1 > var5.right.toFloat() + var6 || var2 < var5.top.toFloat() + var7 || var2 > var5.bottom.toFloat() + var7)
+
+ return var5
+ }
+
+ private fun hasHeader(var1: Int): Boolean {
+ return this.mAdapter.getHeaderId(var1) !== -1L
+ }
+
+ private fun getHeader(var1: RecyclerView, var2: Int): RecyclerView.ViewHolder {
+ val var3 = this.mAdapter.getHeaderId(var2)
+ if (this.mHeaderCache.containsKey(var3)) {
+ return this.mHeaderCache[var3] as RecyclerView.ViewHolder
+ } else {
+ val var5 = this.mAdapter.onCreateHeaderViewHolder(var1)
+ val var6 = var5.itemView
+ this.mAdapter.onBindHeaderViewHolder(var5, var2, var3)
+ val var7 = View.MeasureSpec.makeMeasureSpec(var1.measuredWidth, 1073741824)
+ val var8 = View.MeasureSpec.makeMeasureSpec(var1.measuredHeight, 0)
+ val var9 = ViewGroup.getChildMeasureSpec(var7, var1.paddingLeft + var1.paddingRight, var6.getLayoutParams().width)
+ val var10 = ViewGroup.getChildMeasureSpec(var8, var1.paddingTop + var1.paddingBottom, var6.getLayoutParams().height)
+ var6.measure(var9, var10)
+ var6.layout(0, 0, var6.getMeasuredWidth(), var6.getMeasuredHeight())
+ this.mHeaderCache[var3] = var5
+ return var5
+ }
+ }
+
+ override fun onDrawOver(var1: Canvas, var2: RecyclerView, var3: RecyclerView.State) {
+ val var4 = var2.childCount
+ var var5 = -1L
+
+ for (var7 in 0 until var4) {
+ val var8 = var2.getChildAt(var7)
+ val var9 = var2.getChildAdapterPosition(var8)
+ if (var9 != -1 && this.hasHeader(var9)) {
+ val var10 = this.mAdapter.getHeaderId(var9)
+ if (var10 != var5) {
+ var5 = var10
+ val var12 = this.getHeader(var2, var9).itemView
+ var1.save()
+ val var13 = var8.left
+ val var14 = this.getHeaderTop(var2, var8, var12, var9, var7)
+ var1.translate(var13.toFloat(), var14.toFloat())
+ var12.translationX = var13.toFloat()
+ var12.translationY = var14.toFloat()
+ var12.draw(var1)
+ var1.restore()
+ }
+ }
+ }
+
+ }
+
+ private fun getHeaderTop(var1: RecyclerView, var2: View, var3: View, var4: Int, var5: Int): Int {
+ val var6 = this.getHeaderHeightForLayout(var3)
+ var var7 = var2.y.toInt() - var6
+ if (var5 == 0) {
+ val var8 = var1.childCount
+ val var9 = this.mAdapter.getHeaderId(var4)
+
+ for (var11 in 1 until var8) {
+ val var12 = var1.getChildAdapterPosition(var1.getChildAt(var11))
+ if (var12 != -1) {
+ val var13 = this.mAdapter.getHeaderId(var12)
+ if (var13 != var9) {
+ val var15 = var1.getChildAt(var11)
+ val var16 = var15.y.toInt() - (var6 + this.getHeader(var1, var12).itemView.height)
+ if (var16 < 0) {
+ return var16
+ }
+ break
+ }
+ }
+ }
+
+ var7 = Math.max(0, var7)
+ }
+
+ return var7
+ }
+
+ private fun getHeaderHeightForLayout(var1: View): Int {
+ return if (this.mRenderInline) 0 else var1.height
+ }
+
+ companion object {
+ val NO_HEADER_ID = -1L
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Extensions/Extentions.kt b/app/src/main/java/com/inscripts/cometchatpulse/Extensions/Extentions.kt
new file mode 100755
index 0000000..4df5d75
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Extensions/Extentions.kt
@@ -0,0 +1,18 @@
+package com.inscripts.cometchatpulse.Extensions
+
+import android.graphics.Typeface
+import android.support.v7.widget.Toolbar
+import android.widget.TextView
+
+
+fun Toolbar.setTitleTypeface(typeface: Typeface){
+
+ for (i in 0 until childCount)
+ {
+ val view=getChildAt(i)
+ if (view is TextView && view.text==title){
+ view.typeface=typeface
+ break
+ }
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fcm/FirebaseService.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fcm/FirebaseService.kt
new file mode 100755
index 0000000..cdb5851
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fcm/FirebaseService.kt
@@ -0,0 +1,65 @@
+package com.inscripts.cometchatpulse.Fcm
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.support.v4.app.NotificationCompat
+import android.support.v4.app.NotificationManagerCompat
+import android.support.v4.content.ContextCompat
+import android.util.Log
+import com.google.firebase.messaging.FirebaseMessaging
+import com.google.firebase.messaging.FirebaseMessagingService
+import com.google.firebase.messaging.RemoteMessage
+import com.inscripts.cometchatpulse.Activities.MainActivity
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import org.json.JSONObject
+
+class FirebaseService : FirebaseMessagingService() {
+
+ private val TAG="FirebaseService"
+
+ private val CHANNEL_ID:String="1"
+
+ private lateinit var json:JSONObject
+
+ private var REQUEST_CODE:Int=2
+
+// private lateinit var senderUid
+
+ override fun onNewToken(p0: String?) {
+ Log.d(TAG, "Refreshed token: $p0")
+ }
+
+ override fun onMessageReceived(p0: RemoteMessage?) {
+ Log.d(TAG, "From: ${p0?.from}")
+ Log.d(TAG, "RemoteMessage: ${p0?.data}")
+
+ json =JSONObject(p0?.data)
+
+ Log.d(TAG,"onMessageReceived: "+json.toString())
+
+ val intent=Intent(this,MainActivity::class.java).apply {
+ flags=Intent.FLAG_ACTIVITY_NEW_TASK
+ }
+ val pendingIntent=PendingIntent.getActivity(this,REQUEST_CODE,intent,0)
+
+ showNotification(pendingIntent)
+
+ }
+
+ private fun showNotification(pendingIntent: PendingIntent){
+ val builder=NotificationCompat.Builder(this,CHANNEL_ID)
+ .setSmallIcon(R.drawable.cc_small)
+ .setContentText(json.getString("alert"))
+ .setPriority(NotificationCompat.PRIORITY_HIGH)
+ .setBadgeIconType(R.drawable.cc_small)
+ .setColor(StringContract.Color.primaryColor)
+ .setContentIntent(pendingIntent)
+ .setAutoCancel(true)
+
+ with(NotificationManagerCompat.from(this)){
+ notify(json.getString("id").toInt(),builder.build())
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fragment/BanMemberFragment.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/BanMemberFragment.kt
new file mode 100755
index 0000000..7f0e49a
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/BanMemberFragment.kt
@@ -0,0 +1,167 @@
+package com.inscripts.cometchatpulse.Fragment
+
+
+import android.arch.lifecycle.Observer
+import android.arch.lifecycle.ViewModelProviders
+import android.graphics.PorterDuff
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.PopupMenu
+import android.support.v7.widget.RecyclerView
+import android.view.*
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Adapter.MemberListAdapter
+import com.inscripts.cometchatpulse.Extensions.setTitleTypeface
+import com.inscripts.cometchatpulse.Helpers.OnClickEvent
+import com.inscripts.cometchatpulse.Helpers.RecyclerviewTouchListener
+
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupChatViewModel
+import kotlinx.android.synthetic.main.fragment_ban_member.view.*
+import kotlinx.android.synthetic.main.fragment_home.view.*
+import kotlinx.coroutines.*
+import java.lang.Exception
+
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ *
+ */
+class BanMemberFragment : Fragment() {
+
+
+ private lateinit var guid: String
+
+ private lateinit var ownerId: String
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+
+ private lateinit var groupChatViewModel: GroupChatViewModel
+
+ private lateinit var memberListAdapter: MemberListAdapter
+
+ private lateinit var member: User
+
+ lateinit var my: View
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+ my = inflater.inflate(R.layout.fragment_ban_member, container, false)
+
+ groupChatViewModel = ViewModelProviders.of(this).get(GroupChatViewModel::class.java)
+
+ guid = arguments?.getString(StringContract.IntentString.GROUP_ID).toString()
+
+ ownerId = arguments?.getString(StringContract.IntentString.USER_ID).toString()
+
+ (activity as AppCompatActivity).setSupportActionBar(my.banmember_toolbar)
+ (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ my.banmember_toolbar.title = "Banned Members"
+ my.banmember_toolbar.setTitleTypeface(StringContract.Font.title)
+
+ my.banmember_toolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint,
+ PorterDuff.Mode.SRC_ATOP)
+
+ if (StringContract.AppDetails.theme== Appearance.AppTheme.AZURE_RADIANCE){
+ my.banmember_toolbar.setTitleTextColor(StringContract.Color.black)
+ }
+ else{
+ my.banmember_toolbar.setTitleTextColor(StringContract.Color.white)
+ }
+
+ my.banmember_toolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+ linearLayoutManager = LinearLayoutManager(context)
+ my.rv_ban_member.setLayoutManager(linearLayoutManager)
+ try {
+ memberListAdapter = MemberListAdapter(ownerId,R.layout.group_member_item, object : OnClickEvent {
+ override fun onClickRl(item: View, user: Any) {
+
+ if (user is User) {
+ member = user
+ if (ownerId != user.getUid()) {
+ val popup = context?.let { PopupMenu(it, item) }
+ //Inflating the Popup using xml file
+ popup?.getMenuInflater()?.inflate(R.menu.menu_group_action, popup.getMenu())
+
+ popup?.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener {
+ override fun onMenuItemClick(p0: MenuItem?): Boolean {
+
+ when (p0!!.itemId) {
+
+ R.id.menu_item_Reinstate -> {
+ groupChatViewModel.unbanMember(member.uid, guid)
+ }
+
+ }
+
+ return true
+ }
+
+ })
+
+ popup?.show()
+ }
+ }
+ }
+
+ })
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ my.rv_ban_member.adapter = memberListAdapter
+
+
+ Thread {
+ groupChatViewModel.getBanedMember(guid, LIMIT = 10)
+ }.start()
+
+
+
+ groupChatViewModel.banMemberList.observe(this, Observer { groupMember ->
+ groupMember?.let {
+ memberListAdapter.setMemberList(it)
+ }
+ })
+
+
+ my.rv_ban_member.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+
+ if (!recyclerView.canScrollVertically(1)) {
+ groupChatViewModel.getBanedMember(guid, LIMIT = 10)
+ }
+ }
+
+ })
+
+ return my
+ }
+ override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ when(item?.itemId){
+
+ android.R.id.home->{
+ activity?.onBackPressed()
+ }
+ }
+
+ return true
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fragment/ContactListFragment.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/ContactListFragment.kt
new file mode 100755
index 0000000..05afc66
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/ContactListFragment.kt
@@ -0,0 +1,134 @@
+package com.inscripts.cometchatpulse.Fragment
+
+
+import android.arch.lifecycle.Observer
+import android.arch.lifecycle.ViewModelProviders
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.PorterDuff
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v4.content.ContextCompat
+import android.support.v7.widget.DefaultItemAnimator
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.helper.ItemTouchHelper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Adapter.ContactListAdapter
+import com.inscripts.cometchatpulse.Helpers.CardItemTouchHelper
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.UserViewModel
+import kotlinx.android.synthetic.main.fragment_contact_list.view.*
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+
+class ContactListFragment : Fragment() {
+
+ companion object {
+ private val TAG = this::class.java.simpleName
+ }
+
+ lateinit var userViewModel: UserViewModel
+
+ lateinit var contactListAdapter: ContactListAdapter
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+
+ private lateinit var user:User
+
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+
+
+ val view: View = layoutInflater.inflate(R.layout.fragment_contact_list, container, false)
+ val config: Configuration = activity?.resources?.configuration!!
+ if (config.smallestScreenWidthDp < 600) {
+ CommonUtil.setCardView(view.contact_cardview)
+ }
+
+ userViewModel = ViewModelProviders.of(this).get(UserViewModel::class.java)
+ linearLayoutManager = LinearLayoutManager(activity)
+ view.contact_recycler.layoutManager = linearLayoutManager
+ view.contact_recycler.itemAnimator=DefaultItemAnimator()
+ contactListAdapter = ContactListAdapter(activity)
+ view.contact_recycler.adapter = contactListAdapter
+
+ try {
+
+ val icon = context?.let { ContextCompat.getDrawable(it, R.drawable.ic_outline_video_call_white_24px) }
+ icon?.setColorFilter(StringContract.Color.white,PorterDuff.Mode.SRC_ATOP)
+ val color = StringContract.Color.primaryDarkColor
+ val helper = object : CardItemTouchHelper(context!!,icon!!, color) {
+ override fun onSwiped(p0: RecyclerView.ViewHolder, p1: Int) {
+ contactListAdapter.notifyDataSetChanged()
+ user = (p0.itemView.getTag( R.string.user) as User)
+ showDialog("Are you sure you want to call ","Please Confirm",user.name,context)
+ }
+ }
+
+ val itemTouchHelper = ItemTouchHelper(helper)
+
+ itemTouchHelper.attachToRecyclerView(view.contact_recycler)
+
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+
+ userViewModel.fetchUser(LIMIT = 30,shimmer = view.contact_shimmer)
+
+
+ userViewModel.userList.observe(this, Observer { users ->
+ users?.let { contactListAdapter.setUser(it) }
+ })
+
+
+ view.contact_recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+
+ if (!recyclerView.canScrollVertically(1)) {
+ userViewModel.fetchUser(LIMIT = 30,shimmer = view.contact_shimmer)
+ }
+ }
+
+ })
+
+ return view
+ }
+
+ override fun onStart() {
+ super.onStart()
+ userViewModel.addPresenceListener(StringContract.ListenerName.USER_LISTENER)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ userViewModel.removeUserListener(StringContract.ListenerName.USER_LISTENER)
+ }
+
+ fun showDialog(message: String, title: String, contactName: String, context: Context) {
+ val builder = android.support.v7.app.AlertDialog.Builder(context)
+ builder.setTitle(CommonUtil.setTitle(title, context))
+
+ .setMessage(message + contactName)
+ .setCancelable(true)
+ .setNegativeButton(CommonUtil.setTitle("Cancel", context)) {
+ dialogInterface, i -> dialogInterface.dismiss() }
+ .setPositiveButton(CommonUtil.setTitle("Yes", context), {
+ dialogInterface, i -> userViewModel.initCall(context,user)
+ }).show()
+ }
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fragment/GroupFragment.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/GroupFragment.kt
new file mode 100755
index 0000000..3fa844e
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/GroupFragment.kt
@@ -0,0 +1,818 @@
+package com.inscripts.cometchatpulse.Fragment
+
+
+import android.app.Activity
+import android.arch.lifecycle.Observer
+import android.arch.lifecycle.ViewModelProviders
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.res.ColorStateList
+import android.content.res.Configuration
+import android.databinding.DataBindingUtil
+import android.graphics.PorterDuff
+import android.media.MediaRecorder
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v4.app.FragmentActivity
+import android.support.v4.content.ContextCompat
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.util.Log
+import android.view.*
+import android.widget.TextView
+import android.widget.Toast
+import com.bumptech.glide.Glide
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.helpers.Logger
+import com.cometchat.pro.models.GroupMember
+import com.cometchat.pro.models.MediaMessage
+import com.cometchat.pro.models.TextMessage
+import com.inscripts.cometchatpulse.Activities.GroupDetailActivity
+import com.inscripts.cometchatpulse.Activities.LocationActivity
+import com.inscripts.cometchatpulse.Adapter.GroupChatAdapter
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.CustomView.AttachmentTypeSelector
+import com.inscripts.cometchatpulse.CustomView.StickyHeaderDecoration
+import com.inscripts.cometchatpulse.Helpers.*
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.Utils.FileUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupChatViewModel
+import com.inscripts.cometchatpulse.ViewModel.GroupViewModel
+import com.inscripts.cometchatpulse.databinding.FragmentGroupBinding
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import org.json.JSONObject
+import java.io.File
+import java.io.IOException
+import kotlin.coroutines.CoroutineContext
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+private val TAG="GroupFragment"
+
+/**
+ * A simple [Fragment] subclass.
+ *
+ */
+class GroupFragment : Fragment(), View.OnClickListener, RecordListener,ActionMode.Callback,OnClickEvent {
+
+ private lateinit var binding: FragmentGroupBinding
+
+ private lateinit var guid: String
+
+ private lateinit var groupChatViewModel: GroupChatViewModel
+
+ private lateinit var config: Configuration
+
+ private lateinit var groupViewModel: GroupViewModel
+
+ private var audioFileNamewithPath: String? = null
+
+ private lateinit var clickListener: OnBackArrowClickListener
+
+ private var groupDescription: String? = null
+
+ var mediaRecorder: MediaRecorder? = null
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+
+ private lateinit var groupChatAdapter: GroupChatAdapter
+
+ private lateinit var groupName: String
+
+ private var attachmentTypeSelector: AttachmentTypeSelector? = null
+
+ private var parentJob = Job()
+
+ private val coroutineContext: CoroutineContext
+ get() = parentJob + Dispatchers.Main
+
+ private val scope = CoroutineScope(coroutineContext)
+
+ var scrollFlag: Boolean = true
+
+ private lateinit var any: Any
+
+ private var mode: ActionMode? = null
+
+ companion object {
+
+ var isReply: Boolean = false
+ var metaData: JSONObject?= JSONObject()
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+
+ binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_group,
+ container, false)
+
+ setHasOptionsMenu(true)
+
+ guid = arguments?.getString(StringContract.IntentString.GROUP_ID).toString()
+
+ groupName = arguments?.getString(StringContract.IntentString.GROUP_NAME).toString()
+
+ binding.name = arguments?.getString(StringContract.IntentString.GROUP_NAME)
+
+ binding.icon = arguments?.getString(StringContract.IntentString.GROUP_ICON)
+
+ groupDescription = arguments?.getString(StringContract.IntentString.GROUP_DESCRIPTION)
+
+ groupChatViewModel = ViewModelProviders.of(this).get(GroupChatViewModel::class.java)
+
+ groupViewModel = ViewModelProviders.of(this).get(GroupViewModel::class.java)
+
+ config = activity?.resources?.configuration!!
+
+ clickListener = context as OnBackArrowClickListener
+
+ linearLayoutManager = LinearLayoutManager(activity)
+ binding.recycler.layoutManager = linearLayoutManager
+
+
+ binding.recycler.getItemAnimator()?.changeDuration = 0
+ groupChatAdapter = GroupChatAdapter(context!!, guid, CometChat.getLoggedInUser().uid,this)
+ binding.recycler.adapter = groupChatAdapter
+
+ binding.recycler.addItemDecoration(StickyHeaderDecoration(groupChatAdapter))
+
+ (activity as AppCompatActivity).setSupportActionBar(binding.cometchatToolbar)
+ (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ binding.cometchatToolbar.title = ""
+
+ binding.cometchatToolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+ binding.title.typeface = StringContract.Font.name
+ binding.subTitle.typeface = StringContract.Font.status
+
+ binding.messageBox?.buttonSendMessage?.setOnClickListener(this)
+ binding.messageBox?.ivAttchment?.setOnClickListener(this)
+ binding.rlTitlecontainer.setOnClickListener(this)
+
+ binding.messageBox?.recordButton?.setListenForRecord(true)
+
+ binding.messageBox?.recordAudioView?.setCancelOffset(8.toFloat())
+
+ binding.messageBox?.recordAudioView?.setLessThanSecondAllowed(false)
+
+ binding.messageBox?.recordAudioView?.setSlideToCancelText(getString(R.string.slide_to_cancel))
+
+ binding.messageBox?.recordAudioView?.setCustomSounds(R.raw.record_start,
+ R.raw.record_finished, R.raw.record_error)
+
+ binding.messageBox?.recordButton?.setRecordAudio(binding.messageBox?.recordAudioView)
+
+ binding.messageBox?.recordAudioView?.setOnRecordListener(this)
+
+ binding.cometchatToolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+ binding.cometchatToolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ binding.messageBox?.buttonSendMessage?.backgroundTintList =
+ ColorStateList.valueOf(StringContract.Color.primaryColor)
+
+
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ binding.title.setTextColor(StringContract.Color.black)
+ binding.subTitle.setTextColor(StringContract.Color.black)
+ binding.messageBox?.buttonSendMessage?.drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.ivAttchment?.drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.recordButton?.drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ } else {
+ binding.messageBox?.buttonSendMessage?.drawable?.setColorFilter(StringContract.Color.primaryColor, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.ivAttchment?.drawable?.setColorFilter(StringContract.Color.primaryColor, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.recordButton?.drawable?.setColorFilter(StringContract.Color.primaryColor, PorterDuff.Mode.SRC_ATOP)
+ binding.title.setTextColor(StringContract.Color.white)
+ binding.subTitle.setTextColor(StringContract.Color.white)
+ binding.messageBox?.buttonSendMessage?.drawable?.setColorFilter(StringContract.Color.white, PorterDuff.Mode.SRC_ATOP)
+ }
+ binding.contactPic.borderColor = StringContract.Color.white
+ binding.contactPic.borderWidth = 2
+
+ binding.cometchatToolbar.overflowIcon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ Thread {
+ groupChatViewModel.fetchMessage(LIMIT = 30, guid = guid)
+
+ }.start()
+
+
+ Thread {
+ groupViewModel.fetchGroupMemeber(LIMIT = 30, guid = guid)
+ }.start()
+
+
+ groupChatViewModel.messageList.observe(this, Observer { messages ->
+ messages?.let {
+ groupChatAdapter.setMessageList(it)
+ if (scrollFlag) {
+ scrollBottom()
+ scrollFlag = false
+ }
+ }
+ })
+
+ groupViewModel.groupMemberList.observe(this, Observer { groupMemeberList ->
+ groupMemeberList?.let {
+ setGroupMemberList(it, binding.subTitle)
+
+ }
+ })
+
+ binding.recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+
+ binding.cometchatToolbar.isSelected = binding.recycler.canScrollVertically(-1)
+
+ if (!recyclerView.canScrollVertically(-1)) {
+ groupChatViewModel.fetchMessage(LIMIT = 30, guid = guid)
+
+
+ }
+
+ }
+
+ })
+
+ binding.rlGroup.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ try {
+ val heightDiff = binding.rlGroup.rootView.height - binding.rlGroup.height
+ if (heightDiff > CommonUtil.dpToPx(CometChatPro.applicationContext(), 200f)) {
+ binding.recycler.scrollToPosition(groupChatAdapter.itemCount - 1)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ })
+
+
+
+ return binding.root
+ }
+
+ private fun scrollBottom() {
+ binding.recycler.scrollToPosition(groupChatAdapter.itemCount - 1)
+ }
+
+ override fun onRecordCancel() {
+ binding.messageBox?.editTextChatMessage?.setHint(getString(R.string.type_your_message))
+ stopRecording(true)
+ }
+
+ override fun onRecordFinish(time: Long) {
+ binding.messageBox?.editTextChatMessage?.setHint(getString(R.string.type_your_message))
+ stopRecording(false)
+
+ if (audioFileNamewithPath != null) {
+ Logger.error("audioFileNamewithPath", audioFileNamewithPath)
+ groupChatViewModel.sendMediaMessage(audioFileNamewithPath,
+ CometChatConstants.MESSAGE_TYPE_AUDIO, guid,this)
+
+ }
+
+ }
+
+ override fun onRecordLessTime() {
+ binding.messageBox?.editTextChatMessage?.setHint(getString(R.string.type_your_message))
+ stopRecording(true)
+ }
+
+ override fun onRecordStart() {
+ binding.messageBox?.editTextChatMessage?.setHint("")
+ startRecording()
+ }
+
+
+ private fun startRecording() {
+ try {
+ mediaRecorder = MediaRecorder()
+ mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
+ mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
+ mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
+ audioFileNamewithPath = FileUtil.getOutputMediaFile(context).toString()
+ mediaRecorder?.setOutputFile(audioFileNamewithPath)
+
+ try {
+ mediaRecorder?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ mediaRecorder?.start()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ private fun stopRecording(isCancel: Boolean) {
+ try {
+ if (mediaRecorder != null) {
+ mediaRecorder?.stop()
+ mediaRecorder?.release()
+ mediaRecorder = null
+ if (isCancel) {
+ File(audioFileNamewithPath).delete()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+
+ override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+ menu?.clear()
+ inflater?.inflate(R.menu.option_menu, menu)
+
+ val audioCall = menu?.findItem(R.id.voice_call)
+ val videoCall = menu?.findItem(R.id.video_call)
+
+ val leaveMenu = menu?.findItem(R.id.menu_leave)
+ leaveMenu?.setVisible(true)
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ val drawable = context?.let { ContextCompat.getDrawable(it, R.drawable.ic_more_vert) }
+ drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ leaveMenu?.setIcon(drawable)
+ }
+
+ audioCall?.icon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ videoCall?.icon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ super.onCreateOptionsMenu(menu, inflater)
+
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ when (item?.itemId) {
+
+ android.R.id.home -> {
+
+ if (config.smallestScreenWidthDp >= 600) {
+ clickListener.onBackClick()
+ } else {
+ activity?.onBackPressed()
+ }
+ }
+ R.id.voice_call -> {
+
+ if (CCPermissionHelper.hasPermissions(activity, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ groupViewModel.initCall(context, guid, CometChatConstants.RECEIVER_TYPE_GROUP, CometChatConstants.CALL_TYPE_AUDIO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VOICE_CALL)
+ }
+ }
+
+ R.id.video_call -> {
+
+ if (CCPermissionHelper.hasPermissions(activity, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ groupViewModel.initCall(context, guid, CometChatConstants.RECEIVER_TYPE_GROUP, CometChatConstants.CALL_TYPE_VIDEO)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VIDEO_CALL)
+ }
+
+ }
+
+ R.id.menu_leave -> {
+
+ groupViewModel.leaveGroup(guid, activity)
+ }
+
+
+
+
+ }
+ return true
+ }
+
+
+ override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
+ mode?.finish()
+
+ when (item?.itemId) {
+
+ R.id.reply -> {
+
+ GroupFragment.isReply = true
+ GroupFragment.metaData =null
+ GroupFragment.metaData =JSONObject()
+ GroupFragment.metaData?.put("reply", "reply")
+
+ binding.messageBox?.replyLayout?.rlMain?.visibility = View.VISIBLE
+
+ if (any is TextMessage) {
+ binding.messageBox?.replyLayout?.tvNameReply?.text = (any as TextMessage).sender.name
+ binding.messageBox?.replyLayout?.tvTextMessage?.text = (any as TextMessage).text
+ GroupFragment.metaData?.put("senderName", (any as TextMessage).sender.name)
+ GroupFragment.metaData?.put("senderUid", (any as TextMessage).sender.uid)
+ GroupFragment.metaData?.put("type", (any as TextMessage).type)
+ GroupFragment.metaData?.put("id", (any as TextMessage).id)
+ GroupFragment.metaData?.put("text", (any as TextMessage).text)
+
+ Log.d(TAG, "onActionItemClicked: " + OneToOneFragment.metaData?.toString())
+
+ }
+
+ if (any is MediaMessage) {
+
+ binding.messageBox?.replyLayout?.tvNameReply?.text = (any as MediaMessage).sender.name
+ GroupFragment.metaData?.put("senderName", (any as MediaMessage).sender.name)
+ GroupFragment.metaData?.put("url", (any as MediaMessage).url)
+ GroupFragment.metaData?.put("id", (any as MediaMessage).id)
+ GroupFragment.metaData?.put("senderUid", (any as MediaMessage).sender.uid)
+ val type = (any as MediaMessage).type
+ GroupFragment.metaData?.put("type", type)
+
+ if (type == CometChatConstants.MESSAGE_TYPE_IMAGE
+ || type == CometChatConstants.MESSAGE_TYPE_VIDEO) {
+
+ binding.messageBox?.replyLayout?.ivReplyImage?.visibility = View.VISIBLE
+
+ binding.messageBox?.replyLayout?.ivReplyImage?.let { Glide.with(this).load((any as MediaMessage).url).into(it) }
+
+ } else if (type.equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ binding.messageBox?.replyLayout?.tvTextMessage?.text = "Audio message"
+
+ GroupFragment.metaData?.put("senderName", (any as MediaMessage).sender.name)
+ GroupFragment.metaData?.put("url", (any as MediaMessage).url)
+ GroupFragment.metaData?.put("id", (any as MediaMessage).id)
+
+ } else if (type == CometChatConstants.MESSAGE_TYPE_FILE) {
+
+ GroupFragment.metaData?.put("senderName", (any as MediaMessage).sender.name)
+ GroupFragment.metaData?.put("url", (any as MediaMessage).url)
+ GroupFragment.metaData?.put("id", (any as MediaMessage).id)
+// metaData.put("fileName",(any as MediaMessage).file.name)
+
+ binding.messageBox?.replyLayout?.tvTextMessage?.text = "File message"
+ }
+
+ }
+ }
+ }
+
+ return true
+ }
+
+ override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+ mode?.menuInflater?.inflate(R.menu.action_bar, menu)
+ this.mode = mode
+
+ mode?.title = groupName
+
+ return true
+ }
+
+ override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+ return false
+ }
+
+ override fun onDestroyActionMode(mode: ActionMode?) {
+ this.mode=null
+ }
+
+ override fun onClickRl(item: View, any: Any) {
+ binding.cometchatToolbar.startActionMode(this)
+ this.any = any
+ }
+
+ fun hideReplyContainer(){
+ isReply = false
+ metaData =null
+ metaData =JSONObject()
+ binding.messageBox?.replyLayout?.rlMain?.visibility = View.GONE
+ }
+ override fun onClick(p0: View?) {
+
+ when (p0?.id) {
+ R.id.buttonSendMessage -> {
+
+ val messageText: String? = binding.messageBox?.editTextChatMessage?.text.toString().trim()
+
+ if (messageText != null && !messageText.isEmpty()) {
+
+ val textMessage = TextMessage(guid, messageText, CometChatConstants.MESSAGE_TYPE_TEXT,
+ CometChatConstants.RECEIVER_TYPE_GROUP)
+
+ binding.messageBox?.editTextChatMessage?.setText("")
+
+ if (GroupFragment.isReply) {
+ binding.messageBox?.replyLayout?.rlMain?.visibility = View.GONE
+ textMessage.metadata = GroupFragment.metaData
+ GroupFragment.metaData =null
+ GroupFragment.metaData = JSONObject()
+ }
+
+ groupChatViewModel.sendTextMessage(textMessage)
+ scrollFlag = true
+ }
+ }
+
+ R.id.iv_attchment -> {
+ showPopUp()
+ }
+
+ R.id.rl_titlecontainer -> {
+ val groupDetailIntent = Intent(context, GroupDetailActivity::class.java)
+ groupDetailIntent.putExtra(StringContract.IntentString.GROUP_ID, guid)
+ groupDetailIntent.putExtra(StringContract.IntentString.GROUP_ICON,
+ arguments?.getString(StringContract.IntentString.GROUP_ICON))
+ groupDetailIntent.putExtra(StringContract.IntentString.GROUP_OWNER,
+ arguments?.getString(StringContract.IntentString.GROUP_OWNER))
+
+ groupDetailIntent.putExtra(StringContract.IntentString.GROUP_DESCRIPTION
+ , groupDescription)
+
+ groupDetailIntent.putExtra(StringContract.IntentString.GROUP_NAME,
+ arguments?.getString(StringContract.IntentString.GROUP_NAME))
+ startActivity(groupDetailIntent)
+
+ }
+ }
+ }
+
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array,
+ grantResults: IntArray) {
+
+ when (requestCode) {
+ StringContract.RequestCode.ADD_DOCUMENT ->
+
+ if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ AttachmentHelper.selectMedia(activity, "*/*", StringContract.IntentString.EXTRA_MIME_DOC)
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.ADD_GALLERY ->
+
+ if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ val intent = AttachmentHelper.selectMedia(activity, "*/*",
+ StringContract.IntentString.EXTRA_MIME_TYPE)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_GALLERY)
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.TAKE_PHOTO ->
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
+ grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ val intent = AttachmentHelper.captureImage()
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_PHOTO)
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.TAKE_VIDEO ->
+
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
+ grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ val intent = AttachmentHelper.captureVideo()
+
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_VIDEO)
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.RECORD_CODE ->
+
+ if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
+ grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.ADD_SOUND -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED) {
+
+ AttachmentHelper.selectMedia(activity, StringContract.IntentString.AUDIO_TYPE, null)
+ } else {
+ showToast()
+ }
+ StringContract.RequestCode.VOICE_CALL -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED) {
+
+ groupViewModel.initCall(context, guid, CometChatConstants.RECEIVER_TYPE_GROUP, CometChatConstants.CALL_TYPE_AUDIO)
+
+ } else {
+ showToast()
+ }
+ StringContract.RequestCode.VIDEO_CALL -> if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
+ && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ groupViewModel.initCall(context, guid,
+ CometChatConstants.RECEIVER_TYPE_GROUP, CometChatConstants.CALL_TYPE_VIDEO)
+
+ } else {
+ showToast()
+ }
+
+ }
+
+ }
+
+ private fun showToast() {
+ Toast.makeText(context, "PERMISSION NOT GRANTED", Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+
+ if (resultCode == Activity.RESULT_OK && data != null) {
+
+ when (requestCode) {
+
+ StringContract.RequestCode.ADD_GALLERY -> {
+ val filePath = AttachmentHelper.handleFile(context, data)
+ groupChatViewModel.sendMediaMessage(filePath[0], filePath[1], guid,this)
+ scrollFlag = true
+ }
+ StringContract.RequestCode.TAKE_PHOTO -> {
+ val filePath = AttachmentHelper.handleCameraImage(context, data)
+ groupChatViewModel.sendMediaMessage(filePath, CometChatConstants.MESSAGE_TYPE_IMAGE, guid,this)
+ scrollFlag = true
+ }
+
+ StringContract.RequestCode.TAKE_VIDEO -> {
+ val filePath = AttachmentHelper.handleCameraVideo(context, data)
+ groupChatViewModel.sendMediaMessage(filePath, CometChatConstants.MESSAGE_TYPE_VIDEO, guid,this)
+ scrollFlag = true
+ }
+
+ StringContract.RequestCode.ADD_SOUND -> {
+ val filePath = AttachmentHelper.handleFile(context, data)
+ groupChatViewModel.sendMediaMessage(filePath[0], CometChatConstants.MESSAGE_TYPE_AUDIO, guid,this)
+ scrollFlag = true
+ }
+
+ StringContract.RequestCode.ADD_DOCUMENT -> {
+ val filePath = AttachmentHelper.handleFile(context, data)
+ groupChatViewModel.sendMediaMessage(filePath[0], filePath[1], guid,this)
+ scrollFlag = true
+
+ }
+ }
+ }
+
+ }
+
+
+ private fun showPopUp() {
+
+ try {
+ if (attachmentTypeSelector == null) {
+ attachmentTypeSelector = AttachmentTypeSelector(context!!, AttachmentTypeListener())
+ }
+ attachmentTypeSelector!!.show(activity as Activity, binding.messageBox?.ivAttchment as View)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ private inner class AttachmentTypeListener : AttachmentTypeSelector.AttachmentClickedListener {
+ override fun onClick(type: Int) {
+ addAttachment(type, activity)
+ }
+ }
+
+ fun addAttachment(type: Int, activity: FragmentActivity?) {
+ when (type) {
+ StringContract.RequestCode.ADD_GALLERY ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.STORAGE_PERMISSION)) {
+
+ val intent = AttachmentHelper.selectMedia(activity, "*/*",
+ StringContract.IntentString.EXTRA_MIME_TYPE)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_GALLERY)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.STORAGE_PERMISSION, StringContract.RequestCode.ADD_GALLERY)
+ }
+ StringContract.RequestCode.ADD_DOCUMENT ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.STORAGE_PERMISSION)) {
+
+ val intent = AttachmentHelper.selectMedia(activity, "*/*",
+ StringContract.IntentString.DOCUMENT_TYPE)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_DOCUMENT)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.STORAGE_PERMISSION,
+ StringContract.RequestCode.ADD_DOCUMENT)
+ }
+ StringContract.RequestCode.ADD_SOUND ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.STORAGE_PERMISSION)) {
+
+ val intent = AttachmentHelper.selectMedia(activity, StringContract.IntentString.AUDIO_TYPE,
+ null)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_SOUND)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.STORAGE_PERMISSION, StringContract.RequestCode.ADD_SOUND)
+ }
+
+ StringContract.RequestCode.TAKE_PHOTO ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.CAMERA_PERMISSION)) {
+
+ val intent = AttachmentHelper.captureImage()
+
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_PHOTO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.CAMERA_PERMISSION, StringContract.RequestCode.TAKE_PHOTO)
+ }
+ StringContract.RequestCode.TAKE_VIDEO ->
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.CAMERA_PERMISSION)) {
+ val intent = AttachmentHelper.captureVideo()
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_VIDEO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.CAMERA_PERMISSION, StringContract.RequestCode.TAKE_VIDEO)
+
+ }
+
+ StringContract.RequestCode.LOCATION ->
+ locationIntent()
+
+ }
+ }
+
+
+ private fun locationIntent() {
+ val locationIntent = Intent(context, LocationActivity::class.java)
+ locationIntent.putExtra(StringContract.IntentString.ID, guid)
+ locationIntent.putExtra(StringContract.IntentString.RECIVER_TYPE, CometChatConstants.RECEIVER_TYPE_GROUP)
+ startActivity(locationIntent)
+ }
+
+
+ private fun setGroupMemberList(list: MutableList, subtitle: TextView) {
+ val builder = StringBuilder()
+
+ for (member in list) {
+
+ builder.append(member.user.name)
+ builder.append(",")
+
+ }
+ val memeberList = builder.deleteCharAt(builder.length - 1).toString()
+ Logger.errorLong("LISTMEMBER", memeberList)
+ subtitle.text = memeberList
+ }
+
+
+ override fun onResume() {
+ super.onResume()
+ Log.d(TAG,"onResume: ")
+ groupChatViewModel.addGroupEventListener(StringContract.ListenerName.GROUP_EVENT_LISTENER)
+ groupChatViewModel.addGroupMessageListener(StringContract.ListenerName.MESSAGE_LISTENER, CometChat.getLoggedInUser().uid)
+ }
+
+
+ override fun onPause() {
+ super.onPause()
+ Log.d(TAG,"onPause: ")
+ stopRecording(false)
+ groupChatViewModel.removeGroupEventListener(StringContract.ListenerName.GROUP_EVENT_LISTENER)
+ groupChatViewModel.removeMessageListener(StringContract.ListenerName.MESSAGE_LISTENER)
+ groupChatAdapter.stopPlayer()
+
+ }
+
+ override fun onStop() {
+ super.onStop()
+ stopRecording(false)
+ }
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fragment/GroupListFragment.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/GroupListFragment.kt
new file mode 100755
index 0000000..3b65d25
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/GroupListFragment.kt
@@ -0,0 +1,91 @@
+package com.inscripts.cometchatpulse.Fragment
+
+
+import android.app.ProgressDialog
+import android.arch.lifecycle.Observer
+import android.arch.lifecycle.ViewModelProviders
+import android.content.Intent
+import android.content.res.Configuration
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.models.Group
+import com.inscripts.cometchatpulse.Adapter.GroupListAdapter
+import com.inscripts.cometchatpulse.Helpers.RecyclerviewTouchListener
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupViewModel
+import kotlinx.android.synthetic.main.fragment_group_list.view.*
+import kotlinx.coroutines.*
+import kotlin.coroutines.CoroutineContext
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ *
+ */
+class GroupListFragment : Fragment() {
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+
+ private lateinit var groupListAdapter: GroupListAdapter
+
+ private lateinit var groupViewModel:GroupViewModel
+
+ private var twoPane: Boolean=false
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+ val view:View= inflater.inflate(R.layout.fragment_group_list, container, false)
+
+ val config: Configuration = activity?.resources?.configuration!!
+ if(config.smallestScreenWidthDp <600 ) {
+ CommonUtil.setCardView(view.group_Card)
+ }
+ //recycler view setup
+ linearLayoutManager= LinearLayoutManager(context)
+ view.group_recycler.layoutManager=linearLayoutManager
+ groupListAdapter= GroupListAdapter(context)
+ view.group_recycler.adapter=groupListAdapter
+
+ groupViewModel=ViewModelProviders.of(this).get(GroupViewModel::class.java)
+
+
+ groupViewModel.fetchGroups(LIMIT = 30,shimmerFrameLayout= view.contact_shimmer)
+
+
+ groupViewModel.groupList.observe(this, Observer { groups ->
+ groups?.let { groupListAdapter.setGroup(it) }
+ })
+
+ view.group_recycler.addOnScrollListener(object :RecyclerView.OnScrollListener(){
+
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+
+ if (!recyclerView.canScrollVertically(1)) {
+
+ groupViewModel.fetchGroups(LIMIT = 30,shimmerFrameLayout= view.contact_shimmer)
+
+ }
+ }
+ })
+
+
+ return view
+ }
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fragment/MemberFragment.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/MemberFragment.kt
new file mode 100755
index 0000000..96b348b
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/MemberFragment.kt
@@ -0,0 +1,196 @@
+package com.inscripts.cometchatpulse.Fragment
+
+
+import android.arch.lifecycle.Observer
+import android.arch.lifecycle.ViewModelProvider
+import android.arch.lifecycle.ViewModelProviders
+import android.content.Intent
+import android.content.res.Configuration
+import android.os.Bundle
+import android.support.v4.app.Fragment
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.view.*
+import android.widget.LinearLayout
+import android.widget.Toast
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Adapter.MemberListAdapter
+import com.inscripts.cometchatpulse.Helpers.OnClickEvent
+import com.inscripts.cometchatpulse.Helpers.RecyclerviewTouchListener
+
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.ViewModel.GroupChatViewModel
+import kotlinx.android.synthetic.main.fragment_ban_member.view.*
+import kotlinx.android.synthetic.main.fragment_contact_list.view.*
+import kotlinx.android.synthetic.main.fragment_home.view.*
+import kotlinx.coroutines.*
+import java.lang.Exception
+import android.R.attr.button
+import android.graphics.PorterDuff
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.PopupMenu
+import com.cometchat.pro.constants.CometChatConstants
+import com.inscripts.cometchatpulse.Activities.MainActivity
+import com.inscripts.cometchatpulse.Extensions.setTitleTypeface
+import com.inscripts.cometchatpulse.Utils.Appearance
+
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ *
+ */
+class MemberFragment : Fragment() {
+
+
+ private lateinit var guid: String
+
+ private lateinit var ownerId: String
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+
+ private lateinit var groupChatViewModel: GroupChatViewModel
+
+ private lateinit var memberListAdapter: MemberListAdapter
+
+ private lateinit var member: User
+
+ private lateinit var myView: View
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+ myView = inflater.inflate(R.layout.fragment_home, container, false)
+
+
+ guid = arguments?.getString(StringContract.IntentString.GROUP_ID).toString()
+
+ ownerId = arguments?.getString(StringContract.IntentString.USER_ID).toString()
+
+ (activity as AppCompatActivity).setSupportActionBar(myView.member_toolbar)
+ (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ myView.member_toolbar.title = "Group Members"
+
+ myView.member_toolbar.setTitleTypeface(StringContract.Font.title)
+
+ myView.member_toolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint,
+ PorterDuff.Mode.SRC_ATOP)
+
+ myView.member_toolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+
+ if (StringContract.AppDetails.theme== Appearance.AppTheme.AZURE_RADIANCE){
+ myView.member_toolbar.setTitleTextColor(StringContract.Color.black)
+ }
+ else{
+ myView.member_toolbar.setTitleTextColor(StringContract.Color.white)
+ }
+
+ groupChatViewModel = ViewModelProviders.of(this).get(GroupChatViewModel::class.java)
+
+ linearLayoutManager = LinearLayoutManager(context)
+ myView.rv_member.layoutManager = linearLayoutManager
+ try {
+
+ memberListAdapter = MemberListAdapter(ownerId,R.layout.group_member_item, object : OnClickEvent {
+ override fun onClickRl(item: View, user: Any) {
+
+ if (user is User) {
+ member = user
+ if (ownerId != user.getUid()) {
+
+ val popup = context?.let { PopupMenu(it, item) }
+ //Inflating the Popup using xml file
+ popup?.menuInflater?.inflate(R.menu.member_menu, popup.getMenu())
+
+ popup?.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener {
+ override fun onMenuItemClick(p0: MenuItem?): Boolean {
+
+ when (p0!!.itemId) {
+ R.id.menu_item_outcast -> {
+ groupChatViewModel.banMember(user.uid, guid)
+ }
+ R.id.menu_item_kick -> {
+ groupChatViewModel.kickMember(user.uid, guid)
+ }
+
+ R.id.menu_admin->{
+ groupChatViewModel.updateScope(this@MemberFragment,user.uid,guid,CometChatConstants.SCOPE_ADMIN)
+ }
+
+ R.id.menu_moderator->{
+ groupChatViewModel.updateScope(this@MemberFragment,user.uid,guid,CometChatConstants.SCOPE_MODERATOR)
+ }
+ R.id.menu_participant->{
+ groupChatViewModel.updateScope(this@MemberFragment,user.uid,guid,CometChatConstants.SCOPE_PARTICIPANT)
+ }
+
+
+
+ }
+
+ return true
+ }
+
+ })
+
+ popup?.show()
+//
+ }
+ }
+ }
+
+ })
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ myView.rv_member.adapter = memberListAdapter
+ registerForContextMenu(myView.rv_member)
+ groupChatViewModel.getMembers(guid, LIMIT = 10)
+
+
+ groupChatViewModel.groupMemberList.observe(this, Observer { groupMember ->
+ groupMember?.let {
+ memberListAdapter.setMemberList(it)
+ }
+ })
+
+
+ myView.rv_member.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+
+ if (!recyclerView.canScrollVertically(1)) {
+ groupChatViewModel.getMembers(guid, LIMIT = 10)
+ }
+ }
+
+ })
+
+ return myView
+ }
+
+
+
+ override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ when(item?.itemId){
+
+ android.R.id.home->{
+ activity?.onBackPressed()
+ }
+ }
+
+ return true
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Fragment/OneToOneFragment.kt b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/OneToOneFragment.kt
new file mode 100755
index 0000000..e1ef3dc
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Fragment/OneToOneFragment.kt
@@ -0,0 +1,831 @@
+package com.inscripts.cometchatpulse.Fragment
+
+
+import android.app.Activity
+import android.app.Activity.RESULT_OK
+import android.app.Application
+import android.arch.lifecycle.Observer
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.res.ColorStateList
+import android.content.res.Configuration
+import android.databinding.DataBindingUtil
+import android.graphics.PorterDuff
+import android.media.MediaRecorder
+import android.os.Bundle
+import android.os.Environment
+import android.provider.Settings
+import android.support.v4.app.Fragment
+import android.support.v4.app.FragmentActivity
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.util.Log
+import android.view.*
+import android.widget.Toast
+import com.bumptech.glide.Glide
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.helpers.Logger
+import com.cometchat.pro.models.MediaMessage
+import com.cometchat.pro.models.TextMessage
+import com.inscripts.cometchatpulse.Activities.LocationActivity
+import com.inscripts.cometchatpulse.Activities.UserProfileViewActivity
+import com.inscripts.cometchatpulse.Adapter.OneToOneAdapter
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.CustomView.AttachmentTypeSelector
+import com.inscripts.cometchatpulse.CustomView.StickyHeaderDecoration
+import com.inscripts.cometchatpulse.Helpers.*
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+import com.inscripts.cometchatpulse.StringContract.IntentString.Companion.EXTRA_MIME_DOC
+import com.inscripts.cometchatpulse.Utils.Appearance
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import com.inscripts.cometchatpulse.Utils.FileUtil
+import com.inscripts.cometchatpulse.ViewModel.OnetoOneViewModel
+import com.inscripts.cometchatpulse.databinding.FragmentContactDetailBinding
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import org.json.JSONObject
+import java.io.File
+import java.io.IOException
+import kotlin.coroutines.CoroutineContext
+import kotlin.random.Random
+
+
+class OneToOneFragment : Fragment(), View.OnClickListener, RecordListener, ActionMode.Callback, OnClickEvent {
+
+
+ companion object {
+ const val ARG_PARAM1 = "param1"
+ const val ARG_PARAM2 = "param2"
+ private val TAG = "OneToOneFragment"
+ var isReply: Boolean = false
+ var metaData: JSONObject? = JSONObject()
+
+ }
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+
+ private lateinit var oneToOneAdapter: OneToOneAdapter
+
+ private var ownerId: String
+
+ lateinit var binding: FragmentContactDetailBinding
+
+ private lateinit var userId: String
+
+ private lateinit var config: Configuration
+
+ private var status: String? = null
+
+ private var name: String? = null
+
+ private var avatar: String? = null
+
+ private var uid: String? = null
+
+ private lateinit var onetoOneViewModel: OnetoOneViewModel
+
+ private var audioFileNamewithPath: String? = null
+
+ private var parentJob = Job()
+
+ private lateinit var clickListener: OnBackArrowClickListener
+
+ var mediaRecorder: MediaRecorder? = null
+
+ var count: Int = 0
+
+ private var attachmentTypeSelector: AttachmentTypeSelector? = null
+
+ private val coroutineContext: CoroutineContext
+ get() = parentJob + Dispatchers.Main
+
+ private val scope = CoroutineScope(coroutineContext)
+
+ var currentScrollPosition = 0
+
+ var scrollFlag: Boolean = true
+
+ private var mode: ActionMode? = null
+
+ private var menuResId: Int? = null
+
+ private lateinit var any: Any
+
+ init {
+ ownerId = CometChat.getLoggedInUser().uid
+
+ }
+
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ // Inflate the layout for this fragment
+ binding = DataBindingUtil.inflate(layoutInflater, R.layout.fragment_contact_detail,
+ container, false)
+
+ setHasOptionsMenu(true)
+
+ name = arguments?.getString(StringContract.IntentString.USER_NAME)
+
+ status = arguments?.getString(StringContract.IntentString.USER_STATUS)
+
+ avatar = arguments?.getString(StringContract.IntentString.USER_AVATAR)
+
+ uid = arguments?.getString(StringContract.IntentString.USER_ID)
+
+ binding.name = name
+
+ binding.status = status
+
+ binding.avatar = avatar
+
+ binding.lastActive = arguments?.getLong(StringContract.IntentString.LAST_ACTIVE)
+
+ userId = arguments?.getString(StringContract.IntentString.USER_ID)!!
+
+ onetoOneViewModel = OnetoOneViewModel(CometChatPro.applicationContext() as Application)
+
+ binding.messageBox?.recordButton?.setListenForRecord(true)
+
+ binding.messageBox?.recordAudioView?.setCancelOffset(16.toFloat())
+
+ binding.messageBox?.recordAudioView?.setLessThanSecondAllowed(false)
+
+ binding.messageBox?.recordAudioView?.setSlideToCancelText(getString(R.string.slide_to_cancel))
+
+ binding.messageBox?.recordAudioView?.setCustomSounds(R.raw.record_start, R.raw.record_finished, R.raw.record_error)
+
+ binding.messageBox?.recordButton?.setRecordAudio(binding.messageBox?.recordAudioView)
+
+ binding.messageBox?.recordAudioView?.setOnRecordListener(this)
+
+ config = activity?.resources?.configuration!!
+
+ clickListener = context as OnBackArrowClickListener
+
+ linearLayoutManager = LinearLayoutManager(activity)
+ binding.recycler.layoutManager = linearLayoutManager
+
+ binding.title.typeface = StringContract.Font.name
+ binding.subTitle.typeface = StringContract.Font.status
+
+ binding.recycler.itemAnimator?.changeDuration = 0
+ oneToOneAdapter = OneToOneAdapter(context!!, CometChat.getLoggedInUser().uid, this)
+ binding.recycler.addItemDecoration(StickyHeaderDecoration(oneToOneAdapter))
+ binding.recycler.setRecyclerListener(RecycleListenerHelper())
+
+ binding.recycler.adapter = oneToOneAdapter
+
+
+ (activity as AppCompatActivity).setSupportActionBar(binding.cometchatToolbar)
+ (activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding.cometchatToolbar.title = ""
+
+ binding.cometchatToolbar.setBackgroundColor(StringContract.Color.primaryColor)
+
+ binding.cometchatToolbar.navigationIcon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ binding.subTitle.isSelected = true
+
+ binding.contactPic.borderColor = StringContract.Color.white
+ binding.contactPic.borderWidth = 2
+
+ binding.messageBox?.buttonSendMessage?.setOnClickListener(this)
+ binding.messageBox?.ivAttchment?.setOnClickListener(this)
+ binding.rlTitlecontainer.setOnClickListener(this)
+
+ binding.rlMain.viewTreeObserver.addOnGlobalLayoutListener {
+ val heightDiff = binding.rlMain.rootView.height - binding.rlMain.height
+ try {
+
+ if (heightDiff > CommonUtil.dpToPx(CometChatPro.applicationContext(), 200f)) {
+ binding.recycler.scrollToPosition(oneToOneAdapter.itemCount - 1)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+
+ binding.messageBox?.replyLayout?.ivClose?.setOnClickListener(object : View.OnClickListener {
+ override fun onClick(p0: View?) {
+ hideReplyContainer()
+ }
+
+ })
+
+
+ if (StringContract.AppDetails.theme == Appearance.AppTheme.AZURE_RADIANCE) {
+ binding.title.setTextColor(StringContract.Color.black)
+ binding.subTitle.setTextColor(StringContract.Color.black)
+ binding.messageBox?.buttonSendMessage?.drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.ivAttchment?.drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.recordButton?.drawable?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ } else {
+ binding.messageBox?.buttonSendMessage?.drawable?.setColorFilter(StringContract.Color.primaryColor, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.ivAttchment?.drawable?.setColorFilter(StringContract.Color.primaryColor, PorterDuff.Mode.SRC_ATOP)
+ binding.messageBox?.recordButton?.drawable?.setColorFilter(StringContract.Color.primaryColor, PorterDuff.Mode.SRC_ATOP)
+ binding.title.setTextColor(StringContract.Color.white)
+ binding.subTitle.setTextColor(StringContract.Color.white)
+ binding.messageBox?.buttonSendMessage?.drawable?.setColorFilter(StringContract.Color.white, PorterDuff.Mode.SRC_ATOP)
+ }
+
+ binding.cometchatToolbar.overflowIcon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ binding.messageBox?.buttonSendMessage?.backgroundTintList = ColorStateList.valueOf(StringContract.Color.primaryColor)
+
+
+ scope.launch(Dispatchers.IO) {
+ onetoOneViewModel.fetchMessage(LIMIT = 30, userId = userId)
+
+ }
+
+
+
+ onetoOneViewModel.messageList.observe(this, Observer { messages ->
+ messages?.let {
+ oneToOneAdapter.setMessageList(it)
+ if (scrollFlag) {
+ scrollBottom()
+ scrollFlag = false
+ }
+ }
+ })
+
+ onetoOneViewModel.user.observe(this, Observer { user ->
+ user?.let {
+ if (user.uid.equals(userId)) {
+ binding.lastActive = it.lastActiveAt
+ binding.status = it.status
+ }
+ }
+ })
+
+ binding.recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+
+ binding.cometchatToolbar.isSelected = binding.recycler.canScrollVertically(-1)
+
+ if (!recyclerView.canScrollVertically(-1)) {
+ onetoOneViewModel.fetchMessage(LIMIT = 30, userId = userId)
+ scrollFlag = false
+ }
+ }
+
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+
+ }
+
+ })
+
+ return binding.root
+ }
+
+
+ fun hideReplyContainer() {
+ isReply = false
+ metaData = null
+ metaData = JSONObject()
+ binding.messageBox?.replyLayout?.rlMain?.visibility = View.GONE
+ }
+
+
+ override fun onActionItemClicked(p0: ActionMode?, p1: MenuItem?): Boolean {
+
+ p0?.finish()
+
+ when (p1?.itemId) {
+ R.id.reply -> {
+
+ isReply = true
+ metaData = null
+ metaData = JSONObject()
+ metaData?.put("reply", "reply")
+
+ binding.messageBox?.replyLayout?.rlMain?.visibility = View.VISIBLE
+
+ if (any is TextMessage) {
+ binding.messageBox?.replyLayout?.tvNameReply?.text = (any as TextMessage).sender.name
+ binding.messageBox?.replyLayout?.tvTextMessage?.text = (any as TextMessage).text
+ metaData?.put("senderName", (any as TextMessage).sender.name)
+ metaData?.put("senderUid", (any as TextMessage).sender.uid)
+ metaData?.put("type", (any as TextMessage).type)
+ metaData?.put("id", (any as TextMessage).id)
+ metaData?.put("text", (any as TextMessage).text)
+
+ Log.d(TAG, "onActionItemClicked: " + metaData?.toString())
+
+ }
+
+ if (any is MediaMessage) {
+
+ metaData?.put("senderUid", (any as MediaMessage).sender.uid)
+ binding.messageBox?.replyLayout?.tvNameReply?.text = (any as MediaMessage).sender.name
+ metaData?.put("senderName", (any as MediaMessage).sender.name)
+ metaData?.put("url", (any as MediaMessage).url)
+ metaData?.put("id", (any as MediaMessage).id)
+ val type = (any as MediaMessage).type
+ metaData?.put("type", type)
+
+ if (type == CometChatConstants.MESSAGE_TYPE_IMAGE
+ || type == CometChatConstants.MESSAGE_TYPE_VIDEO) {
+
+ binding.messageBox?.replyLayout?.ivReplyImage?.visibility = View.VISIBLE
+
+ binding.messageBox?.replyLayout?.ivReplyImage?.let { Glide.with(this).load((any as MediaMessage).url).into(it) }
+
+ } else if (type.equals(CometChatConstants.MESSAGE_TYPE_AUDIO)) {
+
+ binding.messageBox?.replyLayout?.tvTextMessage?.text = "Audio Message"
+
+
+ } else if (type == CometChatConstants.MESSAGE_TYPE_FILE) {
+
+ binding.messageBox?.replyLayout?.tvTextMessage?.text = "File Message"
+ }
+
+ }
+ }
+ }
+
+ return true
+ }
+
+ override fun onCreateActionMode(p0: ActionMode?, p1: Menu?): Boolean {
+
+ p0?.menuInflater?.inflate(R.menu.action_bar, p1)
+ mode = p0
+
+ mode?.title = name
+ mode?.subtitle = status
+
+ return true
+ }
+
+ override fun onPrepareActionMode(p0: ActionMode?, p1: Menu?): Boolean {
+ return false
+ }
+
+ override fun onDestroyActionMode(p0: ActionMode?) {
+ mode = null
+ }
+
+ fun scrollBottom() {
+ binding.recycler.scrollToPosition(oneToOneAdapter.itemCount - 1)
+ }
+
+ override fun onClickRl(item: View, any: Any) {
+ binding.cometchatToolbar.startActionMode(this)
+ this.any = any
+ }
+
+
+ override fun onRecordCancel() {
+ binding.messageBox?.editTextChatMessage?.hint = getString(R.string.type_your_message)
+ stopRecording(true)
+ }
+
+ override fun onRecordFinish(time: Long) {
+ binding.messageBox?.editTextChatMessage?.hint = getString(R.string.type_your_message)
+ stopRecording(false)
+
+ if (audioFileNamewithPath != null) {
+ Logger.error("audioFileNamewithPath", audioFileNamewithPath)
+ onetoOneViewModel.sendMediaMessage(audioFileNamewithPath, CometChatConstants.MESSAGE_TYPE_AUDIO, userId, this)
+
+ }
+
+ }
+
+ override fun onRecordLessTime() {
+ binding.messageBox?.editTextChatMessage?.hint = getString(R.string.type_your_message)
+ stopRecording(true)
+ }
+
+ override fun onRecordStart() {
+ binding.messageBox?.editTextChatMessage?.hint = ""
+ startRecording()
+ }
+
+
+ private fun startRecording() {
+ try {
+ mediaRecorder = MediaRecorder()
+ mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
+ mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
+ mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
+ audioFileNamewithPath = FileUtil.getOutputMediaFile(context).toString()
+ mediaRecorder?.setOutputFile(audioFileNamewithPath)
+
+ try {
+ mediaRecorder?.prepare()
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+
+ mediaRecorder?.start()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ private fun stopRecording(isCancel: Boolean) {
+ try {
+ if (mediaRecorder != null) {
+ mediaRecorder?.stop()
+ mediaRecorder?.reset()
+ mediaRecorder?.release()
+ mediaRecorder = null
+ if (isCancel) {
+ File(audioFileNamewithPath).delete()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ (activity as AppCompatActivity).supportActionBar?.title = ""
+ }
+
+
+ override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
+
+ menu?.clear()
+ inflater?.inflate(R.menu.option_menu, menu)
+
+ val audioCall = menu?.findItem(R.id.voice_call)
+ val videoCall = menu?.findItem(R.id.video_call)
+
+ menu?.findItem(R.id.menu_leave)?.setVisible(false)
+
+ audioCall?.icon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+ videoCall?.icon?.setColorFilter(StringContract.Color.iconTint, PorterDuff.Mode.SRC_ATOP)
+
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+
+ when (item?.itemId) {
+
+ android.R.id.home -> {
+
+ if (config.smallestScreenWidthDp >= 600) {
+ clickListener.onBackClick()
+ } else {
+ activity?.onBackPressed()
+ }
+ }
+ R.id.voice_call -> {
+ if (CCPermissionHelper.hasPermissions(activity, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ onetoOneViewModel.initCall(context!!, userId, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_AUDIO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VOICE_CALL)
+ }
+
+ }
+
+ R.id.video_call -> {
+ if (CCPermissionHelper.hasPermissions(activity, *arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO))) {
+
+ onetoOneViewModel.initCall(context!!, userId, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_VIDEO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA, CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO),
+ StringContract.RequestCode.VIDEO_CALL)
+ }
+
+
+ }
+ }
+ return true
+ }
+
+
+ override fun onClick(p0: View?) {
+
+ when (p0?.id) {
+
+
+ R.id.buttonSendMessage -> {
+
+ val messageText: String? = binding.messageBox?.editTextChatMessage?.text.toString().trim()
+
+ if (messageText != null && !messageText.isEmpty()) {
+
+
+ val textMessage = TextMessage(userId, messageText, CometChatConstants.MESSAGE_TYPE_TEXT, CometChatConstants.RECEIVER_TYPE_USER)
+
+ binding.messageBox?.editTextChatMessage?.setText("")
+
+ if (isReply) {
+ binding.messageBox?.replyLayout?.rlMain?.visibility = View.GONE
+ textMessage.metadata = metaData
+ metaData = null
+ metaData = JSONObject()
+ }
+
+ onetoOneViewModel.sendTextMessage(textMessage)
+
+ }
+
+ scrollFlag = true
+
+ }
+
+ R.id.rl_titlecontainer -> {
+
+ val profilViewIntent = Intent(context, UserProfileViewActivity::class.java)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_NAME, name)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_ID, uid)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_STATUS, status)
+ profilViewIntent.putExtra(StringContract.IntentString.USER_AVATAR, avatar)
+ startActivity(profilViewIntent)
+
+ }
+
+ R.id.iv_attchment -> {
+ showPopUp()
+ }
+ }
+
+ }
+
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+ when (requestCode) {
+ StringContract.RequestCode.ADD_DOCUMENT ->
+
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ AttachmentHelper.selectMedia(activity, "", EXTRA_MIME_DOC)
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.ADD_GALLERY ->
+
+ if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ val intent = AttachmentHelper.selectMedia(activity, "", StringContract.IntentString.EXTRA_MIME_TYPE)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_GALLERY)
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.TAKE_PHOTO ->
+ if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
+ grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ val intent = AttachmentHelper.captureImage()
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_PHOTO)
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.TAKE_VIDEO ->
+
+ if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
+ grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ val intent = AttachmentHelper.captureVideo()
+
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_VIDEO)
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.RECORD_CODE ->
+
+ if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
+ grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.ADD_SOUND -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED) {
+
+ AttachmentHelper.selectMedia(activity, StringContract.IntentString.AUDIO_TYPE, null)
+ } else {
+ showToast()
+ }
+ StringContract.RequestCode.VOICE_CALL -> if (grantResults.size > 0 && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED) {
+
+ context?.let { onetoOneViewModel.initCall(it, userId, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_AUDIO) }
+
+ } else {
+ showToast()
+ }
+ StringContract.RequestCode.VIDEO_CALL -> if (grantResults.isNotEmpty() && grantResults[0] ==
+ PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
+
+ context?.let { onetoOneViewModel.initCall(it, userId, CometChatConstants.RECEIVER_TYPE_USER, CometChatConstants.CALL_TYPE_VIDEO) }
+ } else {
+ showToast()
+ }
+
+ StringContract.RequestCode.FILE_WRITE -> if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+
+ FileUtil.makeDirectory(context,CometChatConstants.MESSAGE_TYPE_AUDIO)
+ }
+
+
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+
+ if (resultCode == RESULT_OK && data != null) {
+
+ when (requestCode) {
+
+ StringContract.RequestCode.ADD_GALLERY -> {
+ val filePath = AttachmentHelper.handleFile(context, data)
+ onetoOneViewModel.sendMediaMessage(filePath[0], filePath[1], userId, this)
+ scrollFlag = true
+ }
+ StringContract.RequestCode.TAKE_PHOTO -> {
+ val filePath = AttachmentHelper.handleCameraImage(context, data)
+ scrollFlag = true
+ onetoOneViewModel.sendMediaMessage(filePath, CometChatConstants.MESSAGE_TYPE_IMAGE, userId, this)
+
+ }
+
+ StringContract.RequestCode.TAKE_VIDEO -> {
+ val filePath = AttachmentHelper.handleCameraVideo(context, data)
+ onetoOneViewModel.sendMediaMessage(filePath, CometChatConstants.MESSAGE_TYPE_VIDEO, userId, this)
+ scrollFlag = true
+
+ }
+
+ StringContract.RequestCode.ADD_SOUND -> {
+ val filePath = AttachmentHelper.handleFile(context, data)
+ onetoOneViewModel.sendMediaMessage(filePath[0], CometChatConstants.MESSAGE_TYPE_AUDIO, userId, this)
+ scrollFlag = true
+ }
+
+ StringContract.RequestCode.ADD_DOCUMENT -> {
+ val filePath = AttachmentHelper.handleFile(context, data)
+ onetoOneViewModel.sendMediaMessage(filePath[0], filePath[1], userId, this)
+ scrollFlag = true
+
+ }
+ }
+ }
+
+ }
+
+
+ private fun showToast() {
+ Toast.makeText(context, "PERMISSION NOT GRANTED", Toast.LENGTH_SHORT).show()
+ }
+
+ private fun showPopUp() {
+
+ try {
+ if (attachmentTypeSelector == null) {
+ attachmentTypeSelector = AttachmentTypeSelector(context!!, AttachmentTypeListener())
+ }
+ attachmentTypeSelector!!.show(activity as Activity, binding.messageBox?.ivAttchment as View)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ private inner class AttachmentTypeListener : AttachmentTypeSelector.AttachmentClickedListener {
+ override fun onClick(type: Int) {
+ addAttachment(type, activity)
+ }
+ }
+
+
+ fun addAttachment(type: Int, activity: FragmentActivity?) {
+ when (type) {
+ StringContract.RequestCode.ADD_GALLERY ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.STORAGE_PERMISSION)) {
+
+ val intent = AttachmentHelper.selectMedia(activity, "*/*", StringContract.IntentString.EXTRA_MIME_TYPE)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_GALLERY)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.STORAGE_PERMISSION, StringContract.RequestCode.ADD_GALLERY)
+ }
+ StringContract.RequestCode.ADD_DOCUMENT ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.STORAGE_PERMISSION)) {
+
+ val intent = AttachmentHelper.selectMedia(activity, "*/*", StringContract.IntentString.DOCUMENT_TYPE)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_DOCUMENT)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.STORAGE_PERMISSION, StringContract.RequestCode.ADD_DOCUMENT)
+ }
+ StringContract.RequestCode.ADD_SOUND ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.STORAGE_PERMISSION)) {
+
+ val intent = AttachmentHelper.selectMedia(activity, StringContract.IntentString.AUDIO_TYPE,
+ null)
+
+ startActivityForResult(intent, StringContract.RequestCode.ADD_SOUND)
+
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.STORAGE_PERMISSION, StringContract.RequestCode.ADD_SOUND)
+ }
+
+ StringContract.RequestCode.TAKE_PHOTO ->
+
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.CAMERA_PERMISSION)) {
+
+ val intent = AttachmentHelper.captureImage()
+
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_PHOTO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.CAMERA_PERMISSION, StringContract.RequestCode.TAKE_PHOTO)
+ }
+ StringContract.RequestCode.TAKE_VIDEO ->
+ if (CCPermissionHelper.hasPermissions(activity, *StringContract.RequestPermission.CAMERA_PERMISSION)) {
+ val intent = AttachmentHelper.captureVideo()
+ startActivityForResult(intent, StringContract.RequestCode.TAKE_VIDEO)
+ } else {
+ CCPermissionHelper.requestPermissions(activity as Activity, StringContract.RequestPermission.CAMERA_PERMISSION, StringContract.RequestCode.TAKE_VIDEO)
+
+ }
+
+ StringContract.RequestCode.LOCATION -> {
+
+ try {
+
+ if (CommonUtil.checkPermission(context!!)) {
+ val locationIntent = Intent(context, LocationActivity::class.java)
+ locationIntent.putExtra(StringContract.IntentString.ID, userId)
+ locationIntent.putExtra(StringContract.IntentString.RECIVER_TYPE,
+ CometChatConstants.RECEIVER_TYPE_USER)
+ startActivity(locationIntent)
+ } else {
+ showDialog("App requires to access your location", "Enable Location")
+ }
+
+ } catch (e: Exception) {
+
+ }
+ }
+ }
+ }
+
+
+ private fun showDialog(message: String, title: String) {
+ val builder = context?.let { android.support.v7.app.AlertDialog.Builder(it) }
+ builder?.setTitle(context?.let { CommonUtil.setTitle(title, it) })?.setMessage(message)
+ ?.setCancelable(true)
+ ?.setNegativeButton(context?.let { CommonUtil.setTitle("Cancel", it) }) { dialogInterface, i -> dialogInterface.dismiss() }
+ ?.setPositiveButton(context?.let { CommonUtil.setTitle("Go to settings to enable", it) }) { dialogInterface, i ->
+ startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
+ }?.show()
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ }
+
+
+ override fun onResume() {
+ super.onResume()
+ Log.d(TAG, "onResume: ")
+ onetoOneViewModel.receiveMessageListener(StringContract.ListenerName.MESSAGE_LISTENER, ownerId)
+ onetoOneViewModel.addPresenceListener(StringContract.ListenerName.USER_LISTENER)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ Log.d(TAG, "onPause: ")
+ parentJob.cancel()
+ onetoOneViewModel.removeMessageListener(StringContract.ListenerName.MESSAGE_LISTENER)
+ onetoOneViewModel.removePresenceListener(StringContract.ListenerName.USER_LISTENER)
+ stopRecording(false)
+ oneToOneAdapter.stopPlayer()
+ }
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/AttachmentHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/AttachmentHelper.kt
new file mode 100755
index 0000000..286419b
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/AttachmentHelper.kt
@@ -0,0 +1,138 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.app.Activity
+import android.content.ActivityNotFoundException
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.os.Build
+import android.provider.MediaStore
+import android.support.v4.app.FragmentActivity
+import android.util.Log
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.helpers.Logger
+import com.inscripts.cometchatpulse.Utils.FileUtil
+import com.inscripts.cometchatpulse.Utils.FileUtil.Companion.getPath
+import com.inscripts.cometchatpulse.Utils.MediaUtil
+import java.io.File
+import java.lang.Exception
+import java.net.URISyntaxException
+
+class AttachmentHelper {
+
+ companion object {
+
+ fun selectMedia(activity: FragmentActivity?, type: String,
+ extraMimeType: Array?):Intent {
+
+ val intent = Intent()
+ intent.type = type
+
+ if (extraMimeType != null && Build.VERSION.SDK_INT >= 19) {
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, extraMimeType)
+ }
+
+ intent.action = Intent.ACTION_OPEN_DOCUMENT
+
+ intent.action = Intent.ACTION_GET_CONTENT
+
+ return intent
+
+ }
+
+ fun captureImage():Intent {
+ val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+ return intent
+ }
+
+ fun captureVideo():Intent {
+ val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
+ intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0)
+ intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 15000000L)
+
+ return intent
+
+ }
+
+ fun handleCameraImage(context: Context?, data: Intent):String {
+ var filePath: String=""
+ try {
+ Logger.error("uri", data.data?.toString())
+ val bitmap = data.extras!!.get("data") as Bitmap
+ val fileUri = FileUtil.getImageUri(context!!, bitmap)
+
+ Logger.error("", "fileUri: $fileUri")
+ filePath= FileUtil.ImagePath(fileUri, context)
+
+ }catch (e:Exception){
+ e.printStackTrace()
+ }
+
+ return filePath
+ }
+
+ fun handleCameraVideo(context: Context?, data: Intent): String? {
+ val path = context?.let { FileUtil.getVideoPath(data.data, it) }
+ Logger.debug("handleCameraVideo", " Video Path $path")
+ return path
+
+ }
+
+ fun handleFile(context: Context?, data: Intent): Array {
+
+ var filePath: Array = arrayOfNulls(3)
+
+// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+// val uri = data.data
+// val file = File(uri!!.path)//create path from uri
+// val split = file.path.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()//split the path.
+// for (string in split){
+// Log.d("handleFile",string)
+// }
+// val path=split[0]
+// Log.d("File",split[1])
+// var messageType:String=""
+// try {
+// Log.d("filetype",context?.contentResolver?.getType(uri))
+// val type: String? =context?.contentResolver?.getType(uri)?.toLowerCase()
+//
+// if (type!=null) {
+// if (type.contains("image")||type.contains("picture")||type.contains("photo")){
+// messageType=CometChatConstants.MESSAGE_TYPE_IMAGE
+// }
+// else if (type.contains("video")||type.contains("mp4")||type.contains("avi")||
+// type.contains("flv")){
+// messageType=CometChatConstants.MESSAGE_TYPE_VIDEO
+// }
+// else if (type.contains("aac")||type.contains("m4a")||type.contains("amr")
+// ||type.contains("opus")||type.contains("mp3")){
+//
+// messageType=CometChatConstants.MESSAGE_TYPE_AUDIO
+// }
+// else{
+// messageType=CometChatConstants.MESSAGE_TYPE_FILE
+// }
+// }
+//
+// }catch (e:Exception){
+// e.printStackTrace()
+// }
+//
+//
+// filePath= arrayOf(path,messageType)
+//
+// } else {
+ try {
+ filePath = getPath(context!!, data.data)
+ } catch (e: URISyntaxException) {
+ e.printStackTrace()
+ }
+
+// }
+
+ return filePath
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CCPermissionHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CCPermissionHelper.kt
new file mode 100755
index 0000000..c3ce8b9
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CCPermissionHelper.kt
@@ -0,0 +1,63 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.Manifest
+import android.app.Activity
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Build
+import android.support.v4.app.ActivityCompat
+import com.cometchat.pro.helpers.Logger
+
+
+class CCPermissionHelper {
+
+
+ companion object {
+
+
+
+ private val TAG = CCPermissionHelper::class.java.simpleName
+
+
+ // requested permissions
+ val REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE
+ val REQUEST_PERMISSION_RECORD_AUDIO = Manifest.permission.RECORD_AUDIO
+ val REQUEST_PERMISSION_CAMERA = Manifest.permission.CAMERA
+ val REQUEST_PERMISSION_HARDWARE_LOCATION=Manifest.permission.LOCATION_HARDWARE
+ val REQUEST_PERMISSION_COARSE_LOCATION=Manifest.permission.ACCESS_COARSE_LOCATION
+ val REQUEST_PERMISSION_FINE_LOCATION=Manifest.permission.ACCESS_FINE_LOCATION
+ val REQUEST_PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE
+
+ /**
+ * method to check whether the permissions has been granted to the app
+ * @param context the context_menu of the requesting component
+ * @param permissions list of permissions requested
+ * @return boolean whether app has permission or not
+ */
+ fun hasPermissions(context: Context?, vararg permissions: String): Boolean {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null
+ && permissions != null) {
+ for (permission in permissions) {
+ Logger.error(TAG, " hasPermissions() : Permission : " + permission
+ + "checkSelfPermission : " + ActivityCompat.checkSelfPermission(context, permission))
+ if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
+ return false
+ }
+ }
+ }
+ return true
+ }
+
+ /**
+ * method to request permissions
+ * @param activity the activity requesting permissions
+ * @param permission list of the requested permissions
+ * @param requestCode int request code
+ */
+ fun requestPermissions(activity: Activity, permission: Array, requestCode: Int) {
+ ActivityCompat.requestPermissions(activity, permission, requestCode)
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CardItemTouchHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CardItemTouchHelper.kt
new file mode 100755
index 0000000..9d34c01
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CardItemTouchHelper.kt
@@ -0,0 +1,72 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.content.Context
+import android.graphics.*
+import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.Drawable
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.helper.ItemTouchHelper
+
+
+
+open class CardItemTouchHelper(val context: Context,val icon: Drawable, val backgroundColor:Int)
+ : ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT) {
+ override fun onSwiped(p0: RecyclerView.ViewHolder, p1: Int) {
+
+ }
+
+ private val intrinsicWidth:Int
+ private val intrinsicHeight:Int
+ private val background:ColorDrawable
+ private val clearPaint:Paint
+
+ init {
+ intrinsicWidth = icon.intrinsicWidth
+ intrinsicHeight = icon.intrinsicHeight
+ background=ColorDrawable()
+ clearPaint = Paint()
+ }
+
+
+ override fun onMove(p0: RecyclerView, p1: RecyclerView.ViewHolder, p2: RecyclerView.ViewHolder): Boolean {
+ return false
+ }
+
+
+ override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
+
+ val itemView = viewHolder.itemView
+ val itemHeight = itemView.bottom - itemView.top
+ val isCanceled = dX == 0f && !isCurrentlyActive
+
+ if (isCanceled) {
+ clearCanvas(c, itemView.right + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat())
+ super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
+ return
+ }
+
+ background.color = backgroundColor
+ background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
+ background.draw(c)
+
+ // Calculate position of icon
+ val IconTop = itemView.top + (itemHeight - intrinsicHeight) / 2
+ val IconMargin = (itemHeight - intrinsicHeight) / 2
+ val IconLeft = itemView.right - IconMargin - intrinsicWidth
+ val IconRight = itemView.right -IconMargin
+ val IconBottom = IconTop + intrinsicHeight
+
+ // Draw the icon
+ icon.setBounds(IconLeft, IconTop, IconRight, IconBottom)
+ icon.draw(c)
+
+ super.onChildDraw(c, recyclerView, viewHolder, dX/2.5f, dY, actionState, isCurrentlyActive)
+ }
+
+
+ private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) {
+ c?.drawRect(left, top, right, bottom, clearPaint)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/ChildClickListener.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/ChildClickListener.kt
new file mode 100755
index 0000000..dbd3c91
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/ChildClickListener.kt
@@ -0,0 +1,5 @@
+package com.inscripts.cometchatpulse.Helpers
+
+interface ChildClickListener {
+ fun OnChildClick(t:Any)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CometChatAudioHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CometChatAudioHelper.kt
new file mode 100755
index 0000000..263a7f4
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CometChatAudioHelper.kt
@@ -0,0 +1,107 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.content.Context
+import android.media.AudioManager
+import android.media.SoundPool
+import android.net.Uri
+import android.os.Build
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+
+class CometChatAudioHelper(private val context: Context) {
+
+ private val incomingAudioHelper: IncomingAudioHelper
+
+ private val outgoingAudioHelper: OutgoingAudioHelper
+
+ private val soundPool: SoundPool
+
+ private val disconnectedSoundId: Int
+
+ init {
+ this.incomingAudioHelper = IncomingAudioHelper(context)
+ this.outgoingAudioHelper = OutgoingAudioHelper(context)
+ this.soundPool = SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0)
+ this.disconnectedSoundId = this.soundPool.load(context, R.raw.beep2, 1)
+ }
+
+ fun initAudio() {
+ val audioManager = CommonUtil.getAudioManager(context)
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ audioManager.requestAudioFocus(null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)
+ } else {
+ audioManager.requestAudioFocus(null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
+ }
+ }
+
+ fun startIncomingAudio(ringtone: Uri, isVibarte: Boolean) {
+ val audioManager = CommonUtil.getAudioManager(context)
+ val speaker = !audioManager.isWiredHeadsetOn() && !audioManager.isBluetoothScoOn()
+
+ audioManager.setMode(AudioManager.MODE_RINGTONE)
+ audioManager.setMicrophoneMute(false)
+ audioManager.setSpeakerphoneOn(speaker)
+
+ incomingAudioHelper.start(ringtone, isVibarte)
+ }
+
+ fun startOutgoingAudio(type: OutgoingAudioHelper.Type) {
+ val audioManager = CommonUtil.getAudioManager(context)
+ audioManager.setMicrophoneMute(false)
+
+ if (type === OutgoingAudioHelper.Type.IN_COMMUNICATION) {
+ audioManager.setSpeakerphoneOn(false)
+ }
+
+ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION)
+
+ outgoingAudioHelper.start(type)
+ }
+
+ fun silenceIncomingRinger() {
+ incomingAudioHelper.stop()
+ }
+
+ fun startCall(preserveSpeakerphone: Boolean) {
+ val audioManager = CommonUtil.getAudioManager(context)
+
+ incomingAudioHelper.stop()
+ outgoingAudioHelper.stop()
+
+ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION)
+
+ if (!preserveSpeakerphone) {
+ audioManager.setSpeakerphoneOn(false)
+ }
+
+ }
+
+ fun stop(playDisconnected: Boolean) {
+ val audioManager = CommonUtil.getAudioManager(context)
+ audioManager.setSpeakerphoneOn(false)
+ audioManager.setMicrophoneMute(false)
+ audioManager.setMode(AudioManager.MODE_NORMAL)
+ audioManager.abandonAudioFocus(null)
+ incomingAudioHelper.stop()
+ outgoingAudioHelper.stop()
+
+ if (playDisconnected) {
+ soundPool.play(disconnectedSoundId, 1.0f, 1.0f, 0, 0, 1.0f)
+ }
+
+ if (audioManager.isBluetoothScoOn()) {
+ audioManager.setBluetoothScoOn(false)
+ audioManager.stopBluetoothSco()
+ }
+
+
+ }
+
+ companion object {
+
+ private val TAG = "CometChatAudioHelper"
+ }
+
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CustomAlertDialogHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CustomAlertDialogHelper.kt
new file mode 100755
index 0000000..e65105c
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/CustomAlertDialogHelper.kt
@@ -0,0 +1,83 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.app.AlertDialog
+import android.content.Context
+import android.content.DialogInterface
+import android.view.View
+import com.cometchat.pro.helpers.Logger
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+
+class CustomAlertDialogHelper: View.OnClickListener {
+
+ private val TAG = CustomAlertDialogHelper::class.java.simpleName
+
+ private lateinit var onAlertDialogButtonClick: OnAlertDialogButtonClickListener
+
+ private var view: View? = null
+
+ private lateinit var alertDialogCreater: AlertDialog
+
+ private var popupId: Int = 0
+ private var colorPrimary: Int = 0
+
+ // cc cometChat;
+ constructor(context: Context, title: String, view: View, positiveTitle: String, neutralTitle: String,
+ negativeTitle: String, onAlertDialogButton: OnAlertDialogButtonClickListener, popUpId: Int, isCancelable: Boolean) {
+ onAlertDialogButtonClick = onAlertDialogButton
+ // LayoutInflater inflater = (LayoutInflater)
+ // context_menu.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ this.view = view
+ val builder = AlertDialog.Builder(context)
+
+ //todo get color from cc Sdk
+ // cometChat = cc.getInstance(context_menu);
+ colorPrimary = StringContract.Color.primaryDarkColor
+ // colorPrimary = (int) cometChat.getCCSetting(new CCSettingMapper(SettingType.UI_SETTINGS, SettingSubType.COLOR_PRIMARY));
+ builder.setView(view)
+ builder.setCancelable(isCancelable)
+ if (title != "") {
+ builder.setTitle(title)
+ }
+
+ Logger.error(TAG, "ACTION_SEND title : $title")
+ Logger.error(TAG, "ACTION_SEND positiveTitle : $positiveTitle")
+ Logger.error(TAG, "ACTION_SEND negativeTitle : $negativeTitle")
+
+ if (positiveTitle != "") {
+ builder.setPositiveButton(positiveTitle, null)
+ }
+ if (negativeTitle != "") {
+ builder.setNegativeButton(negativeTitle, null)
+ }
+ if (neutralTitle != "") {
+ builder.setNeutralButton(neutralTitle, null)
+ }
+
+ alertDialogCreater = builder.create()
+ alertDialogCreater.show()
+
+ this.popupId = popUpId
+
+ val positiveButton = alertDialogCreater.getButton(DialogInterface.BUTTON_POSITIVE)
+ positiveButton.id = DialogInterface.BUTTON_POSITIVE
+ positiveButton.setTextColor(colorPrimary)
+ positiveButton.setOnClickListener(this)
+
+ val negativeButton = alertDialogCreater.getButton(DialogInterface.BUTTON_NEGATIVE)
+ negativeButton.id = DialogInterface.BUTTON_NEGATIVE
+ negativeButton.setTextColor(colorPrimary)
+ negativeButton.setOnClickListener(this)
+
+ val neutralButton = alertDialogCreater.getButton(DialogInterface.BUTTON_NEUTRAL)
+ neutralButton.id = DialogInterface.BUTTON_NEUTRAL
+ neutralButton.setTextColor(colorPrimary)
+ neutralButton.setOnClickListener(this)
+ }
+
+
+ override fun onClick(v: View) {
+ onAlertDialogButtonClick.onButtonClick(alertDialogCreater, view, v.id, popupId)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/IncomingAudioHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/IncomingAudioHelper.kt
new file mode 100755
index 0000000..6c8ad85
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/IncomingAudioHelper.kt
@@ -0,0 +1,138 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.annotation.TargetApi
+import android.content.Context
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.net.Uri
+import android.os.Build
+import android.os.Vibrator
+import com.cometchat.pro.helpers.Logger
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+import java.io.IOException
+
+
+class IncomingAudioHelper constructor(context: Context) {
+
+ private val context: Context
+ private val vibrator: Vibrator
+
+ private var player: MediaPlayer? = null
+
+ init {
+ this.context = context.applicationContext
+ this.vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+ }
+
+ fun start(uri: Uri?, vibrate: Boolean) {
+ val audioManager = CommonUtil.getAudioManager(context)
+
+ if (player != null) player!!.release()
+ if (uri != null) player = createPlayer(uri)
+
+ val ringerMode = audioManager.getRingerMode()
+
+ if (shouldVibrate(context, player, ringerMode, vibrate)) {
+ Logger.error(TAG, "Starting vibration")
+ vibrator.vibrate(VIBRATE_PATTERN, 1)
+ }
+
+ if (player != null && ringerMode == AudioManager.RINGER_MODE_NORMAL) {
+ try {
+ if (!player!!.isPlaying) {
+ player!!.prepare()
+ player!!.start()
+ Logger.error(TAG, "Playing ringtone now...")
+ } else {
+ Logger.error(TAG, "Ringtone is already playing, declining to restart.")
+ }
+ } catch (e: IllegalStateException) {
+ Logger.error(TAG, e.message)
+ player = null
+ } catch (e: IOException) {
+ Logger.error(TAG, e.message)
+ player = null
+ }
+
+ } else {
+ Logger.error(TAG, "Not ringing, mode: $ringerMode")
+ }
+ }
+
+ fun stop() {
+ if (player != null) {
+ Logger.error(TAG, "Stopping ringer")
+ player!!.release()
+ player = null
+ }
+
+ Logger.error(TAG, "Cancelling vibrator")
+ vibrator.cancel()
+ }
+
+ private fun shouldVibrate(context: Context, player: MediaPlayer?, ringerMode: Int, vibrate: Boolean): Boolean {
+ if (player == null) {
+ return true
+ }
+
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ shouldVibrateNew(context, ringerMode, vibrate)
+ } else {
+ shouldVibrateOld(context, vibrate)
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ private fun shouldVibrateNew(context: Context, ringerMode: Int, vibrate: Boolean): Boolean {
+ val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+
+ if (vibrator == null || !vibrator.hasVibrator()) {
+ return false
+ }
+
+ return if (vibrate) {
+ ringerMode != AudioManager.RINGER_MODE_SILENT
+ } else {
+ ringerMode == AudioManager.RINGER_MODE_VIBRATE
+ }
+ }
+
+ private fun shouldVibrateOld(context: Context, vibrate: Boolean): Boolean {
+ val audioManager = CommonUtil.getAudioManager(context)
+ return vibrate && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
+ }
+
+ private fun createPlayer(ringtoneUri: Uri): MediaPlayer? {
+ try {
+ val mediaPlayer = MediaPlayer()
+
+ mediaPlayer.setOnErrorListener(MediaPlayerErrorListener())
+ mediaPlayer.setDataSource(context, ringtoneUri)
+ mediaPlayer.isLooping = true
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING)
+
+ return mediaPlayer
+ } catch (e: IOException) {
+ Logger.error(TAG, "Failed to create player for incoming call ringer")
+ return null
+ }
+
+ }
+
+
+ private inner class MediaPlayerErrorListener : MediaPlayer.OnErrorListener {
+ override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
+ Logger.error(TAG, "onError($mp, $what, $extra")
+ player = null
+ return false
+ }
+ }
+
+ companion object {
+
+ private val TAG = "IncomingAudioHelper"
+
+ private val VIBRATE_PATTERN = longArrayOf(0, 1000, 1000)
+ }
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnAlertDialogButtonClickListener.java b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnAlertDialogButtonClickListener.java
new file mode 100755
index 0000000..77bbdde
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnAlertDialogButtonClickListener.java
@@ -0,0 +1,8 @@
+package com.inscripts.cometchatpulse.Helpers;
+
+import android.app.AlertDialog;
+import android.view.View;
+
+public interface OnAlertDialogButtonClickListener {
+ public void onButtonClick(AlertDialog alertDialog, View v, int which, int popupId);
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnBackArrowClickListener.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnBackArrowClickListener.kt
new file mode 100755
index 0000000..16f7581
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnBackArrowClickListener.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.Helpers
+
+interface OnBackArrowClickListener {
+
+ fun onBackClick()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnClickEvent.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnClickEvent.kt
new file mode 100755
index 0000000..15308a8
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnClickEvent.kt
@@ -0,0 +1,8 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.view.View
+import com.cometchat.pro.models.User
+
+interface OnClickEvent {
+ fun onClickRl(item:View,any: Any)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnOptionClickListener.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnOptionClickListener.kt
new file mode 100755
index 0000000..c58ccdb
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnOptionClickListener.kt
@@ -0,0 +1,10 @@
+package com.inscripts.cometchatpulse.Helpers
+
+abstract class OnOptionClickListener {
+ open fun OnOptionClick(position:Int){
+
+ }
+ open fun OnOptionClick( values:Array){
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnRecordClickListener.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnRecordClickListener.kt
new file mode 100755
index 0000000..e744a68
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OnRecordClickListener.kt
@@ -0,0 +1,9 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.view.View
+
+interface OnRecordClickListener {
+
+ fun onRecordClick(v: View)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OutgoingAudioHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OutgoingAudioHelper.kt
new file mode 100755
index 0000000..0097154
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/OutgoingAudioHelper.kt
@@ -0,0 +1,70 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.content.Context
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.net.Uri
+import com.cometchat.pro.helpers.Logger
+import com.inscripts.cometchatpulse.R
+import java.io.IOException
+
+class OutgoingAudioHelper(private val context: Context) {
+
+ private var type: Type? = null
+
+ private val handler = android.os.Handler()
+
+ private var mediaPlayer: MediaPlayer? = null
+
+ enum class Type {
+ IN_COMMUNICATION,
+ RINGING
+ }
+
+ fun start(type: Type) {
+ val soundId: Int
+ this.type = type
+ if (type == Type.IN_COMMUNICATION || type == Type.RINGING)
+ soundId = R.raw.ring
+ else
+ throw IllegalArgumentException("Not a valid sound type")
+
+ if (mediaPlayer != null) {
+ mediaPlayer!!.release()
+ }
+ mediaPlayer = MediaPlayer()
+ mediaPlayer!!.setAudioStreamType(AudioManager.STREAM_VOICE_CALL)
+ mediaPlayer!!.isLooping = true
+ val packageName = context.packageName
+ val dataUri = Uri.parse("android.resource://$packageName/$soundId")
+
+ try {
+ mediaPlayer!!.setDataSource(context, dataUri)
+ mediaPlayer!!.prepare()
+
+ mediaPlayer!!.start()
+
+ } catch (e: IllegalArgumentException) {
+ Logger.error(TAG, e.message)
+ } catch (e: SecurityException) {
+ Logger.error(TAG, e.message)
+ } catch (e: IllegalStateException) {
+ Logger.error(TAG, e.message)
+ } catch (e: IOException) {
+ Logger.error(TAG, e.message)
+ }
+
+ }
+
+ fun stop() {
+ if (mediaPlayer == null) return
+ mediaPlayer!!.stop()
+ mediaPlayer!!.release()
+ mediaPlayer = null
+ }
+
+ companion object {
+
+ private val TAG = "OutgoingAudioHelper"
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecordListener.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecordListener.kt
new file mode 100755
index 0000000..9e797d5
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecordListener.kt
@@ -0,0 +1,10 @@
+package com.inscripts.cometchatpulse.Helpers
+
+interface RecordListener {
+
+ fun onRecordStart()
+ fun onRecordCancel()
+ fun onRecordFinish(time: Long)
+ fun onRecordLessTime()
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecycleListenerHelper.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecycleListenerHelper.kt
new file mode 100755
index 0000000..533da1c
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecycleListenerHelper.kt
@@ -0,0 +1,22 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.support.v7.widget.RecyclerView
+import com.google.android.gms.maps.GoogleMap
+import com.inscripts.cometchatpulse.ViewHolder.LeftLocationViewHolder
+import com.inscripts.cometchatpulse.ViewHolder.RightLocationViewHolder
+
+class RecycleListenerHelper :RecyclerView.RecyclerListener {
+
+
+ override fun onViewRecycled(p0: RecyclerView.ViewHolder) {
+
+ if (p0 is RightLocationViewHolder){
+ p0.googleMap?.clear()
+ p0.googleMap?.mapType=GoogleMap.MAP_TYPE_NONE
+ }
+ if (p0 is LeftLocationViewHolder){
+ p0.googleMap?.clear()
+ p0.googleMap?.mapType=GoogleMap.MAP_TYPE_NONE
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecyclerviewTouchListener.kt b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecyclerviewTouchListener.kt
new file mode 100755
index 0000000..c36fec2
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Helpers/RecyclerviewTouchListener.kt
@@ -0,0 +1,47 @@
+package com.inscripts.cometchatpulse.Helpers
+
+import android.content.Context
+import android.support.v7.widget.RecyclerView
+import android.view.GestureDetector
+import android.view.MotionEvent
+import android.view.View
+
+class RecyclerviewTouchListener(var1: Context, var2: RecyclerView, private val clickListener: ClickListener?) :
+ RecyclerView.OnItemTouchListener {
+
+ private val gestureDetector: GestureDetector
+
+ init {
+ this.gestureDetector = GestureDetector(var1, object : GestureDetector.SimpleOnGestureListener() {
+ override fun onSingleTapUp(var1: MotionEvent): Boolean {
+ return true
+ }
+
+ override fun onLongPress(var1: MotionEvent) {
+ val var2x = var2.findChildViewUnder(var1.x, var1.y)
+ if (var2x != null && clickListener != null) {
+ clickListener!!.onLongClick(var2x, var2.getChildPosition(var2x))
+ }
+
+ }
+ })
+ }
+
+ override fun onInterceptTouchEvent(var1: RecyclerView, var2: MotionEvent): Boolean {
+ val var3 = var1.findChildViewUnder(var2.x, var2.y)
+ if (var3 != null && this.clickListener != null && this.gestureDetector.onTouchEvent(var2)) {
+ this.clickListener.onClick(var3, var1.getChildPosition(var3))
+ }
+
+ return false
+ }
+
+ override fun onTouchEvent(var1: RecyclerView, var2: MotionEvent) {}
+
+ override fun onRequestDisallowInterceptTouchEvent(var1: Boolean) {}
+
+ interface ClickListener {
+ fun onClick(var1: View, var2: Int)
+ fun onLongClick(var1: View?, var2: Int)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Pojo/GroupOption.kt b/app/src/main/java/com/inscripts/cometchatpulse/Pojo/GroupOption.kt
new file mode 100755
index 0000000..fc89016
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Pojo/GroupOption.kt
@@ -0,0 +1,9 @@
+package com.inscripts.cometchatpulse.Pojo
+
+import android.graphics.drawable.Drawable
+
+data class GroupOption(
+
+ var name:String,
+ var icon: Drawable?
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Repository/GroupRepository.kt b/app/src/main/java/com/inscripts/cometchatpulse/Repository/GroupRepository.kt
new file mode 100755
index 0000000..a7f7568
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Repository/GroupRepository.kt
@@ -0,0 +1,318 @@
+package com.inscripts.cometchatpulse.Repository
+
+
+import android.app.ProgressDialog
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import android.content.Intent
+import android.support.annotation.WorkerThread
+import android.support.v4.app.FragmentActivity
+import android.util.Log
+import android.view.View
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.exceptions.CometChatException
+import com.cometchat.pro.core.*
+import com.cometchat.pro.models.Group
+import com.cometchat.pro.models.GroupMember
+import com.facebook.shimmer.ShimmerFrameLayout
+import com.inscripts.cometchatpulse.Activities.CreateGroupActivity
+import com.inscripts.cometchatpulse.Activities.GroupDetailActivity
+import com.inscripts.cometchatpulse.Activities.MainActivity
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.Fragment.MemberFragment
+
+
+class GroupRepository {
+
+ var groupList: MutableLiveData> = MutableLiveData()
+
+ var group: MutableLiveData = MutableLiveData()
+
+ var groupListMutable = mutableListOf()
+
+ var groupMemberList = mutableListOf()
+
+ var banGroupMemberList= mutableListOf()
+
+ var groupMemberLiveData:MutableLiveData> = MutableLiveData()
+
+ var banMemberLiveData:MutableLiveData> = MutableLiveData()
+
+ var groupRequest: GroupsRequest? = null
+
+ var groupMemberRequest: GroupMembersRequest? = null
+
+ var groupBanMemberRequest:BannedGroupMembersRequest?=null
+
+ private lateinit var groupJoin:onGroupJoin
+
+
+ @WorkerThread
+ fun fetchGroup(LIMIT: Int,shimmerFrameLayout: ShimmerFrameLayout?) {
+
+ if (groupRequest == null) {
+
+ groupRequest = GroupsRequest.GroupsRequestBuilder().setLimit(LIMIT).build()
+
+ groupRequest!!.fetchNext(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+ p0?.let { groupListMutable.addAll(it) }
+ groupList.value = groupListMutable
+
+ shimmerFrameLayout?.stopShimmer()
+ shimmerFrameLayout?.visibility=View.GONE
+ }
+
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext(),p0?.message,Toast.LENGTH_SHORT).show()
+ shimmerFrameLayout?.stopShimmer()
+ shimmerFrameLayout?.visibility=View.GONE
+ }
+
+ })
+ } else {
+ groupRequest!!.fetchNext(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+ p0?.let { groupListMutable.addAll(it) }
+ groupList.value = groupListMutable
+ }
+
+ override fun onError(p0: CometChatException?) {
+ p0?.printStackTrace()
+ }
+
+ })
+ }
+ }
+
+ @WorkerThread
+ fun getGroup(guid: String) {
+ CometChat.getGroup(guid, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: Group?) {
+
+ Log.d("onSuccess",p0?.toString())
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+ })
+ }
+
+ @WorkerThread
+ fun unBanMember(guid: String,uid: String){
+
+ CometChat.unbanGroupMember(uid,guid,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: String?) {
+
+ showToast("Successfully unbanned Member")
+ }
+
+ override fun onError(p0: CometChatException?) {
+ p0?.message?.let { showToast(it) }
+ }
+
+ })
+ }
+
+
+ @WorkerThread
+ fun getBannedMember(guid: String,LIMIT: Int){
+ if (groupBanMemberRequest==null){
+
+ groupBanMemberRequest=BannedGroupMembersRequest.BannedGroupMembersRequestBuilder(guid).setLimit(LIMIT).build()
+
+ groupBanMemberRequest?.fetchNext(object :CometChat.CallbackListener>(){
+ override fun onSuccess(p0: List?) {
+
+ p0?.let { banGroupMemberList.addAll(it) }
+ banMemberLiveData.value=banGroupMemberList
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+ }
+ else{
+ groupBanMemberRequest?.fetchNext(object :CometChat.CallbackListener>(){
+ override fun onSuccess(p0: List?) {
+ p0?.let { banGroupMemberList.addAll(it) }
+ banMemberLiveData.value=banGroupMemberList
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+ }
+ }
+ @WorkerThread
+ fun getGroupMember(guid: String, LIMIT: Int){
+
+ if (groupMemberRequest==null) {
+
+ groupMemberRequest = GroupMembersRequest.GroupMembersRequestBuilder(guid).setLimit(LIMIT).build()
+
+ groupMemberRequest?.fetchNext(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+
+ p0?.let { groupMemberList.addAll(it) }
+
+ groupMemberLiveData.value=groupMemberList
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+ }
+ else{
+ groupMemberRequest?.fetchNext(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+
+ p0?.let { groupMemberList.addAll(it) }
+ groupMemberLiveData.value=groupMemberList
+ }
+
+ override fun onError(p0: CometChatException?) {
+ p0?.printStackTrace()
+ }
+
+
+ })
+ }
+
+ }
+
+ @WorkerThread
+ fun clearjob() {
+
+ }
+
+ @WorkerThread
+ fun joinGroup(group: Group, progressDialog: ProgressDialog?,resId:Int,context:Context) {
+
+ groupJoin=context as onGroupJoin
+
+ CometChat.joinGroup(group.guid,group.groupType,group.password,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: String?) {
+ progressDialog?.dismiss()
+ group.setHasJoined(true)
+ groupJoin.onJoined(group,resId)
+ }
+
+ override fun onError(p0: CometChatException?) {
+ progressDialog?.dismiss()
+ Toast.makeText(CometChatPro.applicationContext(),p0?.message,Toast.LENGTH_SHORT).show()
+ }
+
+ })
+ }
+ @WorkerThread
+ fun createGroup(context: Context,group: Group) {
+ CometChat.createGroup(group,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: Group?) {
+
+ (context as CreateGroupActivity).finish()
+ Toast.makeText(CometChatPro.applicationContext(),p0?.groupType+" group created ",Toast.LENGTH_SHORT).show()
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext()," group creation failed ",Toast.LENGTH_SHORT).show()
+ }
+
+ })
+ }
+ @WorkerThread
+ fun banMember(uid: String, guid: String) {
+ CometChat.banGroupMember(uid,guid,object :CometChat.CallbackListener(){
+
+ override fun onSuccess(p0: String?) {
+ showToast("Successfully banned Member")
+ }
+ override fun onError(p0: CometChatException?) {
+ showToast(p0?.message.toString())
+ }
+
+ })
+
+ }
+
+ fun showToast(msg:String){
+ Toast.makeText(CometChatPro.applicationContext(), msg, Toast.LENGTH_SHORT).show()
+ }
+ @WorkerThread
+ fun kickMember(uid: String, guid: String) {
+ CometChat.kickGroupMember(uid,guid,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: String?) {
+ showToast("Successfully kicked Member")
+ }
+
+ override fun onError(p0: CometChatException?) {
+ p0?.message?.let { showToast(it) }
+ }
+
+ })
+ }
+ @WorkerThread
+ fun leaveGroup(guid: String,activity: FragmentActivity?) {
+ CometChat.leaveGroup(guid,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: String?) {
+ showToast("Successfully left group")
+
+ activity?.onBackPressed()
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext(),p0?.message,Toast.LENGTH_SHORT).show()
+ }
+
+ })
+ }
+
+ fun deleteGroup(groupId: String,context: Context) {
+
+ CometChat.deleteGroup(groupId,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: String?) {
+ context.startActivity(Intent(context,MainActivity::class.java))
+ (context as GroupDetailActivity).finish()
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext(),p0?.message,Toast.LENGTH_SHORT).show()
+ }
+
+ })
+ }
+
+ fun updateScope(fragment:MemberFragment,uid: String, guid: String,scope:String) {
+
+ CometChat.updateGroupMemberScope(uid,guid,scope,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: String?) {
+ Toast.makeText(CometChatPro.applicationContext(),"Success",Toast.LENGTH_SHORT).show()
+
+
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext(),p0?.message,Toast.LENGTH_SHORT).show()
+ }
+
+ })
+ }
+
+
+ interface onGroupJoin{
+ fun onJoined(group: Group,resId: Int)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Repository/MessageRepository.kt b/app/src/main/java/com/inscripts/cometchatpulse/Repository/MessageRepository.kt
new file mode 100755
index 0000000..6b086aa
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Repository/MessageRepository.kt
@@ -0,0 +1,534 @@
+package com.inscripts.cometchatpulse.Repository
+
+import android.app.Activity
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import android.support.annotation.WorkerThread
+import android.util.Log
+import android.widget.RelativeLayout
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.Call
+import com.cometchat.pro.core.CometChat
+import com.cometchat.pro.core.MessagesRequest
+import com.cometchat.pro.exceptions.CometChatException
+import com.cometchat.pro.models.*
+import com.inscripts.cometchatpulse.Activities.CallActivity
+import com.inscripts.cometchatpulse.Activities.LocationActivity
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+
+class MessageRepository {
+
+ var ownerId: String
+
+ var messageRequest: MessagesRequest? = null
+
+ var groupMessageRequest: MessagesRequest? = null
+
+ var user: MutableLiveData = MutableLiveData()
+
+ init {
+ ownerId = CometChat.getLoggedInUser().uid
+ }
+
+ var onetoOneMessageList: MutableLiveData> = MutableLiveData()
+
+ var groupMessageList: MutableLiveData> = MutableLiveData()
+
+ var mutableOneToOneMessageList = mutableListOf()
+
+ var mutableGroupMessageList = mutableListOf()
+
+ private val TAG = "MessageRepository"
+
+
+ @WorkerThread
+ fun fetchMessage(LIMIT: Int, userId: String) {
+
+ try {
+ if (messageRequest == null) {
+ messageRequest = MessagesRequest.MessagesRequestBuilder().setUID(userId).setLimit(LIMIT).build()
+
+ messageRequest!!.fetchPrevious(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+
+ p0?.let { mutableOneToOneMessageList.addAll(0, it) }
+ onetoOneMessageList.value = mutableOneToOneMessageList
+
+ Log.d(TAG, "messageRequest onSuccess: ${p0?.size}")
+
+// for (baseMessage in p0!!){
+// Log.d(TAG,"onSuccess: "+baseMessage.id)
+// }
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Log.d(TAG, "messageRequest onError: ${p0?.message}")
+ }
+
+
+ })
+
+ } else {
+ messageRequest!!.fetchPrevious(object : CometChat.CallbackListener>() {
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ override fun onSuccess(p0: List?) {
+
+ Log.d(TAG, "messageRequest 1 onSuccess: ${p0?.size}")
+
+ p0?.let { mutableOneToOneMessageList.addAll(0, it) }
+ onetoOneMessageList.value = mutableOneToOneMessageList
+
+ }
+
+ })
+ }
+ } catch (e: NullPointerException) {
+ e.printStackTrace()
+ }
+
+ }
+
+ @WorkerThread
+ fun fetchGroupMessage(guid: String, LIMIT: Int) {
+ if (groupMessageRequest == null) {
+
+ groupMessageRequest = MessagesRequest.MessagesRequestBuilder().setGUID(guid).setLimit(LIMIT).build()
+
+ groupMessageRequest!!.fetchPrevious(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+ p0?.let { mutableGroupMessageList.addAll(0, it) }
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Log.d(TAG, "fetchGroupMessageonError: " + p0?.message)
+ }
+
+
+ })
+ } else {
+
+ groupMessageRequest!!.fetchPrevious(object : CometChat.CallbackListener>() {
+ override fun onSuccess(p0: List?) {
+ p0?.let { mutableGroupMessageList.addAll(0, it) }
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+ })
+ }
+ }
+
+ @WorkerThread
+ fun sendTextMessage(textMessage: TextMessage, context: Context? = null) {
+
+ CometChat.sendMessage(textMessage, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: TextMessage?) {
+ if (p0 != null) {
+ Log.d("messageDao", " " + p0.toString())
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ if (context != null) {
+ if (context is LocationActivity)
+ context.finish()
+ }
+
+ }
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext(), p0?.details, Toast.LENGTH_SHORT).show()
+
+ }
+
+
+ })
+ }
+
+
+ fun addGroupListener(group_event_listener: String) {
+ CometChat.addGroupListener(group_event_listener, object : CometChat.GroupListener() {
+ override fun onGroupMemberKicked(action: Action?, kickedUser: User?, kickedBy: User?, kickedFrom: Group?) {
+ action?.let { mutableGroupMessageList.add(it) }
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ override fun onGroupMemberScopeChanged(action: Action?, user: User?, scopeChangedTo: String?, scopeChangedFrom: String?, group: Group?) {
+ action?.let { mutableGroupMessageList.add(it) }
+ groupMessageList.value = mutableGroupMessageList
+ }
+
+ override fun onGroupMemberUnbanned(action: Action?, unbannedUser: User?, unbannedBy: User?, unbannedFrom: Group?) {
+ action?.let { mutableGroupMessageList.add(it) }
+ groupMessageList.value = mutableGroupMessageList
+ }
+
+ override fun onGroupMemberBanned(action: Action?, bannedUser: User?, bannedBy: User?, bannedFrom: Group?) {
+ action?.let { mutableGroupMessageList.add(it) }
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ override fun onGroupMemberLeft(action: Action?, joinedUser: User?, joinedGroup: Group?) {
+ action?.let { mutableGroupMessageList.add(it) }
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ override fun onGroupMemberJoined(action: Action?, joinedUser: User?, joinedGroup: Group?) {
+ action?.let { mutableGroupMessageList.add(it) }
+ groupMessageList.value = mutableGroupMessageList
+
+ }
+
+ })
+ }
+
+
+ @WorkerThread
+ fun messageReceiveListener(listener: String, ownerId: String) {
+
+ CometChat.addMessageListener(listener, object : CometChat.MessageListener() {
+ override fun onTextMessageReceived(p0: TextMessage?) {
+ if (p0 != null) {
+
+// if (!ownerId.equals(p0.sender.uid)) {
+
+ if (!p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_GROUP)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+// }
+
+
+ }
+ }
+
+ override fun onMediaMessageReceived(p0: MediaMessage?) {
+ if (p0 != null) {
+
+ if (!ownerId.equals(p0.sender.uid)) {
+
+ if (!p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_GROUP)) {
+
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+ }
+ }
+
+ })
+ }
+
+ @WorkerThread
+ fun removeMessageListener(listener: String) {
+ CometChat.removeMessageListener(listener)
+
+ }
+
+ @WorkerThread
+ fun addPresenceListener(listener: String) {
+
+ CometChat.addUserListener(listener, object : CometChat.UserListener() {
+ override fun onUserOffline(p0: com.cometchat.pro.models.User?) {
+
+ if (p0 != null) {
+ user.value = p0
+ }
+ }
+
+ override fun onUserOnline(p0: com.cometchat.pro.models.User?) {
+ if (p0 != null) {
+ user.value = p0
+ }
+ }
+
+ })
+ }
+
+
+ @WorkerThread
+ fun removePresenceListener(listener: String) {
+ CometChat.removeUserListener(listener)
+ }
+
+ @WorkerThread
+ fun sendMediaMessage(mediaMessage: MediaMessage) {
+
+ CometChat.sendMediaMessage(mediaMessage, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: MediaMessage?) {
+
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+
+ }
+ Log.d("MediaMessage", "baseMessage")
+ }
+
+ override fun onError(p0: CometChatException?) {
+ p0?.printStackTrace()
+ }
+
+ })
+ }
+
+
+ fun removeGroupListener(group_event_listener: String) {
+ CometChat.removeGroupListener(group_event_listener)
+ }
+
+ fun addCallListener(context: Context, call_event_listener: String, view: RelativeLayout?) {
+
+ CometChat.addCallListener(call_event_listener, object : CometChat.CallListener() {
+
+ override fun onIncomingCallCancelled(p0: Call?) {
+ Log.d(TAG, "onIncomingCallCancelled " + p0.toString())
+
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+
+ if (context is CallActivity) {
+
+ context.finish()
+ }
+ }
+
+ override fun onOutgoingCallAccepted(p0: Call?) {
+
+ Log.d(TAG, "onOutgoingCallAccepted: " + p0?.toString())
+
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+ p0?.sessionId?.let {
+ if (view != null) {
+ CometChat.startCall(context as Activity, it, view, object : CometChat.OngoingCallListener {
+
+ override fun onUserJoined(p0: User?) {
+ Log.d(TAG, "onUserJoined: " + p0?.toString())
+ }
+
+ override fun onUserLeft(p0: User?) {
+ Log.d(TAG, "onUserLeft: " + p0?.toString())
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Log.d(TAG, "CallonError: " + p0?.message)
+ }
+
+ override fun onCallEnded(p0: Call?) {
+
+ Log.d(TAG, "onCallEnded " + "onOutgoingCallAccepted " + p0.toString())
+
+ if (context is CallActivity) {
+
+ context.finish()
+ }
+ }
+
+ })
+ }
+ }
+ }
+
+ override fun onIncomingCallReceived(p0: Call?) {
+
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+
+ Log.d(TAG, "onIncomingCallReceived: " + p0.toString())
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+
+ CommonUtil.startCallIntent(CometChatConstants.RECEIVER_TYPE_USER, context,
+ p0.callInitiator as User, p0.type, false, p0.sessionId)
+
+ } else if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_GROUP)) {
+ CommonUtil.startCallIntent(CometChatConstants.RECEIVER_TYPE_GROUP, context,
+ p0.callReceiver as Group, p0.type, false, p0.sessionId)
+ }
+ }
+ }
+
+ override fun onOutgoingCallRejected(p0: Call?) {
+
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+
+ Log.d(TAG, "onOutgoingCallRejected: " + p0?.toString())
+ if (context is CallActivity) {
+
+ context.finish()
+ }
+ }
+
+ })
+
+ }
+
+ fun removeCallListener(call_event_listener: String) {
+ CometChat.removeCallListener(call_event_listener)
+ }
+
+ fun acceptCall(sessionID: String, view: RelativeLayout, activity: Activity) {
+
+
+ CometChat.acceptCall(sessionID, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: Call?) {
+
+
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+
+ p0?.sessionId?.let {
+ CometChat.startCall(activity, it, view, object : CometChat.OngoingCallListener {
+ override fun onUserJoined(p0: User?) {
+ Log.d(TAG, "onUserJoined: " + p0?.toString())
+ }
+
+ override fun onUserLeft(p0: User?) {
+ Log.d(TAG, "onUserLeft: " + p0?.toString())
+ }
+
+ override fun onError(p0: CometChatException?) {
+ }
+
+ override fun onCallEnded(p0: Call?) {
+ Log.d(TAG, "onCallEnded: " + p0.toString())
+
+ activity.finish()
+ }
+
+ })
+ }
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+ }
+
+ fun rejectCall(sessionID: String, call_status_rejected: String, activity: Activity) {
+ CometChat.rejectCall(sessionID, call_status_rejected, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: Call?) {
+ Log.d(TAG, "onSuccess: " + p0?.toString())
+ activity.finish()
+ if (p0 != null) {
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ }
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+
+ }
+
+ fun initiateCall(call: Call, context: Context) {
+ CometChat.initiateCall(call, object : CometChat.CallbackListener() {
+ override fun onSuccess(p0: Call?) {
+ Log.d(TAG, "onSuccess: " + p0?.toString())
+ if (p0 != null) {
+
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ mutableOneToOneMessageList.add(p0)
+ onetoOneMessageList.value = mutableOneToOneMessageList
+ } else {
+ mutableGroupMessageList.add(p0)
+ groupMessageList.value = mutableGroupMessageList
+ }
+ if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_USER)) {
+ CommonUtil.startCallIntent(CometChatConstants.RECEIVER_TYPE_USER, context, p0.callReceiver as User, p0.type, true, p0.sessionId)
+ } else if (p0.receiverType.equals(CometChatConstants.RECEIVER_TYPE_GROUP)) {
+ CommonUtil.startCallIntent(CometChatConstants.RECEIVER_TYPE_GROUP, context, p0.callReceiver as Group, p0.type, true, p0.sessionId)
+ }
+ }
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Repository/UserRepository.kt b/app/src/main/java/com/inscripts/cometchatpulse/Repository/UserRepository.kt
new file mode 100755
index 0000000..2312051
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Repository/UserRepository.kt
@@ -0,0 +1,156 @@
+package com.inscripts.cometchatpulse.Repository
+
+
+import android.app.Activity
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import android.support.annotation.WorkerThread
+import android.util.Log
+import android.view.View
+import android.widget.RelativeLayout
+import android.widget.Toast
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.*
+import com.cometchat.pro.exceptions.CometChatException
+import com.cometchat.pro.models.*
+import com.facebook.shimmer.Shimmer
+import com.facebook.shimmer.ShimmerFrameLayout
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.Utils.CommonUtil
+
+
+
+class UserRepository() {
+
+ var usersList = MutableLiveData>()
+
+ var user = MutableLiveData()
+
+ var mutableUserList = mutableMapOf()
+
+ var userRequest: UsersRequest? = null
+
+
+
+
+ @WorkerThread
+ fun getUser(uid: String) {
+
+ CometChat.getUser(uid, object : CometChat.CallbackListener() {
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ override fun onSuccess(p0: User?) {
+ user.value = p0
+ }
+
+ })
+ }
+
+ @WorkerThread
+ fun fetchUsers(LIMIT: Int,shimmer: ShimmerFrameLayout?) {
+
+ if (userRequest == null) {
+
+ userRequest = UsersRequest.UsersRequestBuilder().setLimit(LIMIT).build()
+
+ userRequest?.fetchNext(object : CometChat.CallbackListener>() {
+
+ override fun onError(p0: CometChatException?) {
+ Toast.makeText(CometChatPro.applicationContext(),p0?.message,Toast.LENGTH_SHORT).show()
+ shimmer?.stopShimmer()
+ shimmer?.visibility=View.GONE
+ }
+
+ override fun onSuccess(p0: List?) {
+ if (p0 != null) {
+ Log.d("UsersRequest", " " + p0.size)
+ for (user:User in p0){
+ mutableUserList.put(user.uid,user)
+ }
+ shimmer?.stopShimmer()
+ shimmer?.visibility= View.GONE
+ usersList.value = mutableUserList
+ }
+ }
+
+
+ })
+
+
+ } else {
+
+ userRequest?.fetchNext(object : CometChat.CallbackListener>() {
+
+ override fun onSuccess(p0: List?) {
+ Log.d("UsersRequest", " " + p0?.size)
+ if (p0!=null) {
+ for (user: User in p0) {
+ mutableUserList.put(user.uid, user)
+ }
+ usersList.value = mutableUserList
+ }
+
+ }
+
+ override fun onError(p0: CometChatException?) {
+ Log.d("fetchNext","UsersRequest onError: ${p0?.message}")
+ }
+
+ })
+
+ }
+
+ }
+
+
+ @WorkerThread
+ fun addPresenceListener(listener: String) {
+
+ CometChat.addUserListener(listener, object : CometChat.UserListener() {
+ override fun onUserOnline(p0: com.cometchat.pro.models.User?) {
+
+ if (p0 != null) {
+ mutableUserList.put(p0.uid,p0)
+ usersList.value=mutableUserList
+ }
+ }
+
+ override fun onUserOffline(p0: com.cometchat.pro.models.User?) {
+ if (p0 != null) {
+ mutableUserList.put(p0.uid,p0)
+ usersList.value=mutableUserList
+ }
+ }
+
+ })
+
+ }
+
+ @WorkerThread
+ fun clearjob() {
+
+ }
+
+ fun removeUserListener(listener: String) {
+ CometChat.removeUserListener(listener)
+
+ }
+
+ fun initCall(context:Context,call: Call) {
+ CometChat.initiateCall(call,object :CometChat.CallbackListener(){
+ override fun onSuccess(p0: Call?) {
+
+ CommonUtil.startCallIntent(CometChatConstants.RECEIVER_TYPE_USER,context, p0?.callReceiver as User, p0.type, true, p0.sessionId)
+ }
+
+ override fun onError(p0: CometChatException?) {
+
+ }
+
+ })
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/StringContract.kt b/app/src/main/java/com/inscripts/cometchatpulse/StringContract.kt
new file mode 100755
index 0000000..bca277c
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/StringContract.kt
@@ -0,0 +1,246 @@
+package com.inscripts.cometchatpulse
+
+import android.graphics.Typeface
+import com.inscripts.cometchatpulse.Helpers.CCPermissionHelper
+import com.inscripts.cometchatpulse.Utils.Appearance
+
+class StringContract {
+
+ class AppDetails {
+
+ companion object {
+
+ const val APP_ID: String = "XXXXXXXXXXXXXX"
+
+ const val API_KEY: String = "XXXXXXXXXXXXX"
+
+
+ lateinit var theme: Appearance.AppTheme
+
+ }
+ }
+
+ class IntentString {
+
+ companion object {
+
+ val USER_ID: String = "user_id"
+
+ val USER_NAME: String = "user_name"
+
+ val USER_AVATAR: String = "user_avatar"
+
+ val USER_STATUS: String = "user_status"
+
+ val LAST_ACTIVE: String = "last_user"
+
+ val GROUP_ID: String = "group_id"
+
+ val GROUP_NAME: String = "group_name"
+
+ val GROUP_ICON: String = "group_icon"
+
+ val GROUP_OWNER: String = "group_owner"
+
+ val IMAGE_TYPE = "image/*"
+
+ val AUDIO_TYPE = "audio/*"
+
+ val DOCUMENT_TYPE = arrayOf("*/*")
+
+ val EXTRA_MIME_TYPE = arrayOf("image/*", "video/*")
+
+ val EXTRA_MIME_DOC = arrayOf("text/plane", "text/html", "application/pdf", "application/msword",
+ "application/vnd.ms.excel", "application/mspowerpoint", "application/zip")
+
+ val TITLE: String = "title"
+
+ val POSITION: String = "position"
+
+ val SESSION_ID: String = "session_id"
+
+ val OUTGOING: String = "outgoing"
+
+ val INCOMING: String = "incoming"
+
+ val RECIVER_TYPE: String = "receiver_type"
+
+ val URL: String = "image"
+
+ val FILE_TYPE: String = "file_type"
+
+ val ID: String = "id"
+
+ val GROUP_DESCRIPTION:String="description"
+
+
+ }
+ }
+
+ class ViewType {
+
+ companion object {
+
+ const val RIGHT_TEXT_MESSAGE = 334
+
+ const val LEFT_TEXT_MESSAGE = 734
+
+ const val LEFT_IMAGE_MESSAGE = 528
+
+ const val RIGHT_IMAGE_MESSAGE = 834
+
+ const val LEFT_VIDEO_MESSAGE = 580
+
+ const val RIGHT_VIDEO_MESSAGE = 797
+
+ const val RIGHT_AUDIO_MESSAGE = 70
+
+ const val LEFT_AUDIO_MESSAGE = 79
+
+ const val LEFT_FILE_MESSAGE = 24
+
+ const val RIGHT_FILE_MESSAGE = 55
+
+ const val CALL_MESSAGE = 84
+
+ const val ACTION_MESSAGE = 99
+
+ const val RIGHT_LOCATION_MESSAGE = 58
+
+ const val LEFT_LOCATION_MESSAGE = 59
+
+ const val RIGHT_MEDIA_REPLY_MESSAGE =345
+
+ const val RIGHT_TEXT_REPLY_MESSAGE=346
+
+ const val LEFT_MEDIA_REPLY_MESSAGE =756
+
+ const val LEFT_TEXT_REPLY_MESSAGE=748
+
+ }
+ }
+
+
+ class Font {
+
+
+ companion object {
+
+ lateinit var title: Typeface
+
+ lateinit var name: Typeface
+
+ lateinit var status: Typeface
+
+ lateinit var message: Typeface
+
+ }
+
+ }
+
+ class Color {
+
+ companion object {
+ var primaryColor: Int = 0;
+
+ var primaryDarkColor: Int = 0
+
+ var accentColor: Int = 0
+
+ var rightMessageColor = 0
+
+ var leftMessageColor = 0
+
+ var iconTint = 0
+
+ var white: Int = android.graphics.Color.parseColor("#ffffff")
+
+ var black: Int = android.graphics.Color.parseColor("#000000")
+
+ var grey: Int = android.graphics.Color.parseColor("#CACACC")
+
+ var inactiveColor = android.graphics.Color.parseColor("#9e9e9e");
+
+ }
+
+ }
+
+ class Dimensions {
+
+ companion object {
+
+ var marginStart: Int = 16
+
+ var marginEnd: Int = 16
+
+ var cardViewCorner: Float = 24f
+
+ var cardViewElevation: Float = 8f
+ }
+ }
+
+ class ListenerName {
+
+ companion object {
+
+ val MESSAGE_LISTENER = "message_listener"
+
+ val USER_LISTENER = "user_listener"
+
+ val GROUP_EVENT_LISTENER = "group_event_listener"
+
+ val CALL_EVENT_LISTENER = "call_event_listener"
+ }
+
+
+ }
+
+
+ class RequestPermission {
+
+ companion object {
+ val RECORD_PERMISSION = arrayOf(CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO,
+ CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE)
+
+ val CAMERA_PERMISSION = arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA,
+ CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE)
+
+ val VIDEO_CALL_PERMISSION = arrayOf(CCPermissionHelper.REQUEST_PERMISSION_CAMERA,
+ CCPermissionHelper.REQUEST_PERMISSION_RECORD_AUDIO)
+
+ val STORAGE_PERMISSION = arrayOf(CCPermissionHelper.REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE)
+
+// val LOCATION_PERMISSION= arrayOf(CCPermissionHelper.L)
+ }
+ }
+
+ class RequestCode {
+
+ companion object {
+
+ val ADD_GALLERY = 1
+
+ val ADD_DOCUMENT = 2
+
+ val ADD_SOUND = 3
+
+ val TAKE_PHOTO = 5
+
+ val LOCATION = 15
+
+ val TAKE_VIDEO = 7
+
+ val LEFT = 8
+
+ val RECORD_CODE = 10
+
+ val VIDEO_CALL = 12
+
+ val VOICE_CALL = 24
+
+ val FILE_WRITE =25
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/AnimUtil.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/AnimUtil.kt
new file mode 100755
index 0000000..cc40e17
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/AnimUtil.kt
@@ -0,0 +1,126 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.animation.ValueAnimator
+import android.util.Pair
+import android.view.View
+import android.view.animation.AccelerateDecelerateInterpolator
+import android.view.animation.AlphaAnimation
+import android.view.animation.Animation
+import android.widget.FrameLayout
+import android.widget.ImageView
+import com.inscripts.cometchatpulse.CustomView.RecordMicButton
+
+class AnimUtil {
+
+ companion object {
+
+ private lateinit var alphaAnimation: AlphaAnimation
+
+ private var isStartRecorded: Boolean = false
+
+ fun start(view: View) {
+ val set = AnimatorSet()
+ val scaleY = ObjectAnimator.ofFloat(view, "scaleY", 2.0f)
+ val scaleX = ObjectAnimator.ofFloat(view, "scaleX", 2.0f)
+ set.duration = 150
+ set.interpolator = AccelerateDecelerateInterpolator()
+ set.playTogether(scaleY, scaleX)
+ set.start()
+ }
+
+ fun stop(view: View) {
+ val set = AnimatorSet()
+ val scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f)
+
+ val scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f)
+ set.duration = 150
+ set.interpolator = AccelerateDecelerateInterpolator()
+ set.playTogether(scaleY, scaleX)
+ set.start()
+ }
+
+ fun getClickOrigin(anchor: View?, contentView: View): Pair {
+ if (anchor == null) return Pair(0, 0)
+
+ val anchorCoordinates = IntArray(2)
+ anchor.getLocationOnScreen(anchorCoordinates)
+ anchorCoordinates[0] += anchor.width / 2
+ anchorCoordinates[1] += anchor.height / 2
+
+ val contentCoordinates = IntArray(2)
+ contentView.getLocationOnScreen(contentCoordinates)
+
+ val x = anchorCoordinates[0] - contentCoordinates[0]
+ val y = anchorCoordinates[1] - contentCoordinates[1]
+
+ return Pair(x, y)
+ }
+
+
+ fun animateMic(recordMic: ImageView) {
+ alphaAnimation = AlphaAnimation(0.0f, 1.0f)
+ alphaAnimation.setDuration(500)
+ alphaAnimation.setRepeatMode(Animation.REVERSE)
+ alphaAnimation.setRepeatCount(Animation.INFINITE)
+ recordMic.startAnimation(alphaAnimation)
+ }
+
+ fun resetSmallMic(recordMic: ImageView) {
+ recordMic.alpha = 1.0f
+ recordMic.scaleX = 1.0f
+ recordMic.scaleY = 1.0f
+ }
+
+
+ fun getShakeAnimation(target: View) {
+// val animator = ObjectAnimator.ofFloat(target, target.translationX, 0, 25, -25, 25, -25, 15, -15, 6, -6, 0)
+// animator.setDuration(500)
+// animator.start()
+
+ }
+
+ fun moveSlideToCancel(recordMicButton: RecordMicButton, layout: FrameLayout, initialX: Float, difX: Float) {
+
+ val positionAnimator = ValueAnimator.ofFloat(recordMicButton.getX(), initialX)
+
+ positionAnimator.interpolator = AccelerateDecelerateInterpolator()
+ positionAnimator.addUpdateListener { animation ->
+ val x = animation.animatedValue as Float
+ recordMicButton.setX(x)
+ }
+
+ recordMicButton.stopScale()
+ positionAnimator.duration = 0
+ positionAnimator.start()
+
+
+ // if the move event was not called ,then the difX will still 0 and there is no need to move it back
+ if (difX != 0f) {
+ val x = initialX - difX
+ layout.animate()
+ .x(x)
+ .setDuration(0)
+ .start()
+ }
+
+
+ }
+
+ fun clearAlphaAnimation(hideView: Boolean, recordMic: ImageView) {
+ alphaAnimation.cancel()
+ alphaAnimation.reset()
+ recordMic.clearAnimation()
+ if (hideView) {
+ recordMic.visibility = View.GONE
+ }
+ }
+
+
+ fun setStartRecorded(startRecorded: Boolean) {
+ isStartRecorded = startRecorded
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/Appearance.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/Appearance.kt
new file mode 100755
index 0000000..ebd397f
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/Appearance.kt
@@ -0,0 +1,156 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.graphics.Color
+import android.graphics.Typeface
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.StringContract
+
+class Appearance(appearance: AppTheme) {
+
+
+ var appearance: AppTheme
+
+ enum class AppTheme {
+ AZURE_RADIANCE,
+ MOUNTAIN_MEADOW,
+ PERSIAN_BLUE
+ }
+
+
+ init {
+ this.appearance = appearance
+
+ StringContract.AppDetails.theme = appearance
+
+ when (this.appearance) {
+
+ AppTheme.PERSIAN_BLUE -> {
+
+ //fonts
+
+ StringContract.Font.title = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "GoogleSans-Bold.ttf")
+
+ StringContract.Font.message = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "GoogleSans-Regular.ttf")
+
+ StringContract.Font.name = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "GoogleSans-Regular.ttf")
+
+ StringContract.Font.status = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "GoogleSans-Medium.ttf")
+
+ //Dimensions
+
+ StringContract.Dimensions.cardViewCorner = 32f
+
+ StringContract.Dimensions.cardViewElevation = 8f
+
+ StringContract.Dimensions.marginEnd = 24
+
+ StringContract.Dimensions.marginStart = 24
+
+ //color
+
+ StringContract.Color.primaryColor = Color.parseColor("#2636be")
+
+ StringContract.Color.primaryDarkColor = Color.parseColor("#000f8c")
+
+ StringContract.Color.accentColor = Color.parseColor("#6861f2")
+
+ StringContract.Color.leftMessageColor = Color.parseColor("#eaeaea")
+
+ StringContract.Color.rightMessageColor = StringContract.Color.primaryColor
+
+ StringContract.Color.iconTint = StringContract.Color.white
+
+
+ }
+
+ AppTheme.MOUNTAIN_MEADOW -> {
+ //fonts
+ StringContract.Font.title = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "HelveticaNeueBold.ttf")
+
+ StringContract.Font.message = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "OpenSans-Regular.ttf")
+
+ StringContract.Font.name = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "HelveticaNeueMedium.ttf")
+
+ StringContract.Font.status = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "HelveticaNeueMedium.ttf")
+
+ //Dimensions
+
+ StringContract.Dimensions.cardViewCorner = 0f
+
+ StringContract.Dimensions.cardViewElevation = 0f
+
+ StringContract.Dimensions.marginEnd = 0
+
+ StringContract.Dimensions.marginStart = 0
+
+ //color
+
+ StringContract.Color.primaryColor = Color.parseColor("#25d366")
+
+ StringContract.Color.primaryDarkColor = Color.parseColor("#00a038")
+
+ StringContract.Color.accentColor = Color.parseColor("#6bff96")
+
+ StringContract.Color.leftMessageColor = Color.parseColor("#eaeaea")
+
+ StringContract.Color.rightMessageColor = StringContract.Color.primaryColor
+
+ StringContract.Color.iconTint = StringContract.Color.white
+
+
+ }
+
+ AppTheme.AZURE_RADIANCE -> {
+
+ StringContract.Font.title = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "Avenir_Next.ttf")
+
+ StringContract.Font.message = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "OpenSans-Regular.ttf")
+
+ StringContract.Font.name = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "Roboto-Medium.ttf")
+
+ StringContract.Font.status = Typeface.createFromAsset(CometChatPro.applicationContext().assets,
+ "RobotoCondensed-Regular.ttf")
+
+ //Dimensions
+
+ StringContract.Dimensions.cardViewCorner = 0f
+
+ StringContract.Dimensions.cardViewElevation = 0f
+
+ StringContract.Dimensions.marginEnd = 0
+
+ StringContract.Dimensions.marginStart = 0
+
+ //color
+
+ StringContract.Color.primaryColor = Color.parseColor("#ffffff")
+
+ StringContract.Color.primaryDarkColor = Color.parseColor("#a8a9ab")
+
+ StringContract.Color.accentColor = Color.parseColor("#ffffff")
+
+ StringContract.Color.leftMessageColor = Color.parseColor("#eaeaea")
+
+ StringContract.Color.rightMessageColor = Color.parseColor("#0084ff")
+
+ StringContract.Color.iconTint = Color.parseColor("#0084ff")
+
+
+ }
+
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/ColorUtil.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/ColorUtil.kt
new file mode 100755
index 0000000..cd749aa
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/ColorUtil.kt
@@ -0,0 +1,40 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.content.Context
+import android.graphics.Color
+import com.inscripts.cometchatpulse.R
+import java.util.concurrent.ThreadLocalRandom
+
+class ColorUtil{
+
+
+ companion object {
+
+ fun getMaterialColor(context: Context): Int {
+ var materialColor = 0
+ try {
+
+
+ materialColor = Color.WHITE
+
+ val colors = context.resources.obtainTypedArray(R.array.material_color)
+
+ materialColor = colors.getColor(getRandomIndex(), Color.WHITE)
+ colors.recycle()
+
+ return materialColor
+
+ } catch (se: StringIndexOutOfBoundsException) {
+
+ return context.resources.getColor(R.color.primaryColor)
+ }
+
+ }
+
+ public fun getRandomIndex(): Int {
+ return ThreadLocalRandom.current().nextInt(0, 80 + 1)
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/CommonUtil.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/CommonUtil.kt
new file mode 100755
index 0000000..2b695a9
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/CommonUtil.kt
@@ -0,0 +1,150 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.graphics.Typeface
+import android.location.LocationManager
+import android.media.AudioManager
+import android.net.ConnectivityManager
+import android.os.Build
+import android.support.annotation.IdRes
+import android.support.v7.widget.CardView
+import android.support.v7.widget.Toolbar
+import android.text.SpannableString
+import android.text.Spanned
+import android.text.style.ForegroundColorSpan
+import android.util.DisplayMetrics
+import android.view.View
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.TextView
+import com.cometchat.pro.models.Group
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Activities.CallActivity
+import com.inscripts.cometchatpulse.Activities.LocationActivity
+import com.inscripts.cometchatpulse.R
+import com.inscripts.cometchatpulse.StringContract
+
+class CommonUtil {
+
+ companion object {
+
+ var cm: ConnectivityManager?=null
+
+ fun setCardView(cardView: CardView) {
+ cardView.cardElevation = StringContract.Dimensions.cardViewElevation
+ cardView.radius = StringContract.Dimensions.cardViewCorner
+ val param = cardView.layoutParams as RelativeLayout.LayoutParams
+ param.marginEnd = StringContract.Dimensions.marginEnd
+ param.marginStart = StringContract.Dimensions.marginStart
+ cardView.layoutParams = param
+
+ }
+
+
+
+
+ fun checkPermission (context: Context):Boolean{
+
+ return (context.getSystemService(Context.LOCATION_SERVICE) as LocationManager)
+ .isProviderEnabled(LocationManager.GPS_PROVIDER)
+ }
+
+ fun startCallIntent(receiverType:String,context: Context, user: User, type: String,
+ isOutgoing: Boolean, sessionId: String) {
+ val callIntent = Intent(context, CallActivity::class.java)
+ callIntent.putExtra(StringContract.IntentString.USER_NAME, user.name)
+ callIntent.putExtra(StringContract.IntentString.USER_ID, user.uid)
+ callIntent.putExtra(StringContract.IntentString.SESSION_ID, sessionId)
+ callIntent.putExtra(StringContract.IntentString.USER_AVATAR, user.avatar)
+ callIntent.putExtra(StringContract.IntentString.RECIVER_TYPE, receiverType)
+ callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ callIntent.action = type
+
+ if (isOutgoing) {
+ callIntent.type = StringContract.IntentString.OUTGOING
+ } else {
+ callIntent.type = StringContract.IntentString.INCOMING
+ }
+ context.startActivity(callIntent)
+ }
+
+
+ fun getAudioManager(context: Context): AudioManager {
+ return context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
+ }
+
+ fun startCallIntent(receiverType:String,context: Context, group: Group, type: String,
+ isOutgoing: Boolean, sessionId: String) {
+ val callIntent = Intent(context, CallActivity::class.java)
+ callIntent.putExtra(StringContract.IntentString.GROUP_NAME, group.name)
+ callIntent.putExtra(StringContract.IntentString.GROUP_ID, group.guid)
+ callIntent.putExtra(StringContract.IntentString.SESSION_ID, sessionId)
+ callIntent.putExtra(StringContract.IntentString.GROUP_ICON, group.icon)
+ callIntent.putExtra(StringContract.IntentString.RECIVER_TYPE, receiverType)
+ callIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ callIntent.action = type
+
+ if (isOutgoing) {
+ callIntent.type = StringContract.IntentString.OUTGOING
+ } else {
+ callIntent.type = StringContract.IntentString.INCOMING
+ }
+ context.startActivity(callIntent)
+ }
+
+ fun isConnected(context: Context): Boolean {
+
+ if (cm == null) {
+ cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ }
+
+ val var0 = cm!!.getActiveNetworkInfo()
+ return null != var0 && var0!!.isConnectedOrConnecting()
+ }
+
+
+ fun setTitle(title: String, context: Context): SpannableString {
+ val ss = SpannableString(title)
+
+ var color:Int
+
+ if (StringContract.AppDetails.theme==Appearance.AppTheme.AZURE_RADIANCE){
+ color=StringContract.Color.iconTint
+ }
+ else{
+ color=StringContract.Color.primaryColor
+ }
+ ss.setSpan(ForegroundColorSpan(color), 0, title.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+
+ return ss
+ }
+
+
+ fun dpToPx(context: Context, valueInDp: Float): Float {
+ val resources = context.resources
+ val metrics = resources.displayMetrics
+ return valueInDp * (metrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
+ }
+
+
+ fun findById(parent: View, @IdRes resId: Int): Any {
+ return parent.findViewById(resId) as Any
+ }
+
+ fun setStatusBarColor(var0: Activity) {
+ try {
+ if (Build.VERSION.SDK_INT >= 21) {
+ val var2 = var0.window
+ var2.addFlags((-2147483648).toInt())
+ var2.statusBarColor = StringContract.Color.primaryDarkColor
+ }
+ } catch (var3: Exception) {
+ var3.printStackTrace()
+ }
+
+ }
+
+ }
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/DateUtil.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/DateUtil.kt
new file mode 100755
index 0000000..5ef85ba
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/DateUtil.kt
@@ -0,0 +1,73 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.content.Context
+import android.text.format.DateFormat
+import com.inscripts.cometchatpulse.R
+import java.text.SimpleDateFormat
+import java.util.*
+
+class DateUtil {
+
+ companion object {
+
+
+ fun getLastSeenDate(timeStamp: Long, context: Context): String {
+
+ val lastSeenTime = java.text.SimpleDateFormat("HH:mm a").format(java.util.Date(timeStamp))
+ val lastSeenDate = java.text.SimpleDateFormat("dd/MM/yyyy").format(java.util.Date(timeStamp))
+
+ val currentTimeStamp = System.currentTimeMillis()
+
+ val diffTimeStamp = (currentTimeStamp - timeStamp) / 1000
+
+ return if (diffTimeStamp < 24 * 60 * 60) {
+
+ context.getString(R.string.today_last_seen) + " " + lastSeenTime
+
+ } else if (diffTimeStamp < 48 * 60 * 60) {
+
+ context.getString(R.string.yesterday_last_seen) + " " + lastSeenTime
+ } else {
+ "Last seen at $lastSeenDate on $lastSeenTime"
+ }
+
+ }
+
+ fun getDateId(var0: Long): String {
+ val var2 = Calendar.getInstance(Locale.ENGLISH)
+ var2.timeInMillis = var0
+ return DateFormat.format("ddMMyyyy", var2).toString()
+ }
+
+ fun getCustomizeDate(time: Long): String {
+ val monthNames = arrayOf("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
+
+ var date = ""
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = time
+ val day = cal.get(Calendar.DAY_OF_MONTH)
+ val month = cal.get(Calendar.MONTH)
+ val year = cal.get(Calendar.YEAR)
+
+ date = day.toString() + " " + monthNames[month] + ", " + year
+
+ return date
+ }
+
+
+ fun convertTimeStampToDurationTime(var0: Long): String {
+ val var2 = var0 / 1000L
+ val var4 = var2 / 60L % 60L
+ val var6 = var2 / 60L / 60L % 24L
+ return if (var6 == 0L) String.format(Locale.getDefault(), "%02d:%02d", var4, var2 % 60L) else String.format(Locale.getDefault(), "%02d:%02d:%02d", var6, var4, var2 % 60L)
+ }
+
+ fun getMessageTime(time: String, dateFormat: String): String {
+ val format = SimpleDateFormat(dateFormat)
+ val timestamp = java.sql.Timestamp.valueOf(time)
+ return format.format(timestamp)
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/FileUtil.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/FileUtil.kt
new file mode 100755
index 0000000..33abe70
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/FileUtil.kt
@@ -0,0 +1,231 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.content.ContentUris
+import android.content.Context
+import android.database.Cursor
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.DocumentsContract
+import android.provider.MediaStore
+import com.cometchat.pro.constants.CometChatConstants
+import com.inscripts.cometchatpulse.R
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.net.URISyntaxException
+import java.text.SimpleDateFormat
+import java.util.*
+
+class FileUtil {
+
+ companion object {
+
+ @Throws(URISyntaxException::class)
+ fun getPath(context: Context, uri: Uri?): Array {
+ var uri = uri
+ val needToCheckUri = Build.VERSION.SDK_INT >= 19
+ var selection: String? = null
+ var selectionArgs: Array? = null
+ var ar: Array = arrayOf()
+ var type: String? = null
+ // Uri is different in versions after KITKAT (Android 4.4), we need to
+ // deal with different Uris.
+ if (needToCheckUri && DocumentsContract.isDocumentUri(context.applicationContext, uri)) {
+ if (isExternalStorageDocument(uri!!)) {
+ val docId = DocumentsContract.getDocumentId(uri)
+ val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+ ar = arrayOf(Environment.getExternalStorageDirectory().toString() + "/" + split[1], CometChatConstants.MESSAGE_TYPE_FILE)
+ return ar
+ } else if (isDownloadsDocument(uri)) {
+ val id = DocumentsContract.getDocumentId(uri)
+ uri = ContentUris.withAppendedId(
+ Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
+ } else if (isMediaDocument(uri)) {
+ val docId = DocumentsContract.getDocumentId(uri)
+ val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+ type = split[0]
+ if ("image".equals(type)) {
+ type = CometChatConstants.MESSAGE_TYPE_IMAGE
+ uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ } else if ("video".equals(type)) {
+ uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
+ type = CometChatConstants.MESSAGE_TYPE_VIDEO
+ } else if ("audio".equals(type)) {
+ uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
+ type = CometChatConstants.MESSAGE_TYPE_AUDIO
+ }
+ selection = "_id=?"
+ selectionArgs = arrayOf(split[1])
+ }
+ }
+ if ("content".equals(uri!!.scheme!!, ignoreCase = true)) {
+ val projection = arrayOf(MediaStore.Images.Media.DATA)
+ var cursor: Cursor? = null
+ try {
+ cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
+ val column_index = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
+ type = context.contentResolver?.getType(uri)?.toLowerCase()
+ if (type != null) {
+ if (type.contains("jpeg") || type.contains("jpg") || type.contains("png") || type.contains("image")
+ || type.contains("picture") || type.contains("photo")) {
+ type = CometChatConstants.MESSAGE_TYPE_IMAGE
+ } else if (type.contains("video") || type.contains("mp4")
+ || type.contains("avi") ||
+ type.contains("flv")) {
+ type = CometChatConstants.MESSAGE_TYPE_VIDEO
+ } else if (type.contains("aac") || type.contains("m4a") || type.contains("amr")
+ || type.contains("opus") || type.contains("mp3")) {
+
+ type = CometChatConstants.MESSAGE_TYPE_AUDIO
+ } else {
+ type = CometChatConstants.MESSAGE_TYPE_FILE
+ }
+ }
+ if (cursor.moveToFirst()) {
+ ar = arrayOf(cursor.getString(column_index), type)
+ return ar
+ }
+ } catch (e: Exception) {
+ }
+
+ } else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
+ ar = arrayOf(uri.path, CometChatConstants.MESSAGE_TYPE_FILE)
+ return ar
+ }
+ return ar;
+ }
+
+ /**
+ * @param uri The Uri to check.
+ * @return Whether the Uri authority is ExternalStorageProvider.
+ */
+ fun isExternalStorageDocument(uri: Uri): Boolean {
+ return "com.android.externalstorage.documents" == uri.authority
+ }
+
+ /**
+ * @param uri The Uri to check.
+ * @return Whether the Uri authority is DownloadsProvider.
+ */
+ fun isDownloadsDocument(uri: Uri): Boolean {
+ return "com.android.providers.downloads.documents" == uri.authority
+ }
+
+ /**
+ * @param uri The Uri to check.
+ * @return Whether the Uri authority is MediaProvider.
+ */
+ fun isMediaDocument(uri: Uri): Boolean {
+ return "com.android.providers.media.documents" == uri.authority
+ }
+
+ fun getImageUri(inContext: Context, inImage: Bitmap): Uri {
+ val bytes = ByteArrayOutputStream()
+ inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
+ val path = MediaStore.Images.Media.insertImage(inContext.contentResolver, inImage, "Title", null)
+ return Uri.parse(path)
+ }
+
+ fun ImagePath(uri: Uri, context: Context): String {
+ var path = ""
+ if (context.contentResolver != null) {
+ val cursor = context.contentResolver.query(uri, null, null, null, null)
+ if (cursor != null) {
+ cursor.moveToFirst()
+ val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
+ path = cursor.getString(idx)
+ cursor.close()
+ }
+ }
+ return path
+ }
+
+ fun getVideoPath(uri: Uri, context: Context): String {
+ var path = ""
+ if (context.contentResolver != null) {
+ val cursor = context.contentResolver.query(uri, null, null, null, null)
+ if (cursor != null) {
+ cursor.moveToFirst()
+ val idx = cursor.getColumnIndex(MediaStore.Video.VideoColumns.DATA)
+ path = cursor.getString(idx)
+ cursor.close()
+ }
+ }
+ return path
+ }
+
+ fun checkDirExistence(context: Context?,type: String): Boolean {
+
+ val audioDir = File( Environment.getExternalStorageDirectory().toString() + "/" +
+ context?.resources?.getString(R.string.app_name) + "/" + type + "/")
+
+ if (audioDir.isDirectory) {
+ return true
+ }
+
+ return false
+ }
+
+ fun checkFileExistence(path: String): Boolean {
+
+ val filepath = File(path)
+
+ if (filepath.exists()) {
+
+ return true
+ }
+
+ return false
+ }
+
+ fun getPath(context: Context, folder: String): String {
+
+ val path = Environment.getExternalStorageDirectory().toString() + "/" +
+ context.resources?.getString(R.string.app_name) + "/" + folder + "/"
+
+ return path
+ }
+
+ fun getFileName(mediaFile: String?): String? {
+
+ val t = mediaFile?.substring(mediaFile.lastIndexOf("/"))?.split("_".toRegex())?.dropLastWhile({ it.isEmpty() })?.toTypedArray()
+
+ return t?.get(2)
+ }
+
+ fun getFileExtension(mediaFile: String?): String? {
+
+ return mediaFile?.substring(mediaFile.lastIndexOf(".") + 1)
+ }
+
+
+ fun getOutputMediaFile(context: Context?): String? {
+ val var0 = File(Environment.getExternalStorageDirectory(), context?.resources?.getString(R.string.app_name))
+ if (!var0.exists() && !var0.mkdirs()) {
+ return null
+ } else {
+ val var1 = (Environment.getExternalStorageDirectory().toString() + "/" +
+ context?.resources?.getString(R.string.app_name) + "/" +"audio/")
+ createDirectory(var1)
+ return var1 + SimpleDateFormat("yyyyMMddHHmmss").format(Date()) + ".mp3"
+ }
+ }
+
+ fun createDirectory(var0: String) {
+ if (!File(var0).exists()) {
+ File(var0).mkdirs()
+ }
+
+ }
+
+ fun makeDirectory(context: Context?,type:String) {
+
+ val audioDir = Environment.getExternalStorageDirectory().toString() + "/" +
+ context?.resources?.getString(R.string.app_name) + "/" + type + "/"
+
+ createDirectory(audioDir)
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/Utils/MediaUtil.kt b/app/src/main/java/com/inscripts/cometchatpulse/Utils/MediaUtil.kt
new file mode 100755
index 0000000..c6e2b1c
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/Utils/MediaUtil.kt
@@ -0,0 +1,37 @@
+package com.inscripts.cometchatpulse.Utils
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.drawable.Drawable
+
+class MediaUtil {
+
+
+ companion object {
+
+ fun getPlaceholderImage(context: Context, drawable: Drawable): Bitmap {
+ var bitmap = getBitmapFromDrawable( drawable)
+
+ val outputImage = Bitmap.createBitmap(bitmap.getWidth() + 80, bitmap.getHeight() + 80, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(outputImage)
+ canvas.drawARGB(0, 0, 0, 0)
+ canvas.drawBitmap(bitmap, 40f, 40f, null)
+ bitmap = outputImage
+
+ return bitmap
+ }
+
+ private fun getBitmapFromDrawable(drawable: Drawable): Bitmap {
+ val bitmap: Bitmap
+
+ bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
+
+ val canvas = Canvas(bitmap)
+ drawable.setBounds(0, 0, canvas.width, canvas.height)
+ drawable.draw(canvas)
+
+ return bitmap
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/ContactViewHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/ContactViewHolder.kt
new file mode 100755
index 0000000..2433960
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/ContactViewHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.ContactItemBinding
+
+class ContactViewHolder(val binding:ContactItemBinding) : RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/GroupMemberHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/GroupMemberHolder.kt
new file mode 100755
index 0000000..31ab20e
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/GroupMemberHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.GroupMemberItemBinding
+
+class GroupMemberHolder( val binding:GroupMemberItemBinding) :RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/GroupOptionViewHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/GroupOptionViewHolder.kt
new file mode 100755
index 0000000..ae395fa
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/GroupOptionViewHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+
+class GroupOptionViewHolder(val binding: com.inscripts.cometchatpulse.databinding.GroupOptionItemBinding) :RecyclerView.ViewHolder(binding.root) {
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftAudioMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftAudioMessageHolder.kt
new file mode 100755
index 0000000..f0ab076
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftAudioMessageHolder.kt
@@ -0,0 +1,7 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.LeftAudioBinding
+import com.inscripts.cometchatpulse.databinding.RightAudioBinding
+
+class LeftAudioMessageHolder(val binding: LeftAudioBinding):RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftFileViewHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftFileViewHolder.kt
new file mode 100755
index 0000000..4858c29
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftFileViewHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.LeftFileBinding
+
+class LeftFileViewHolder(val binding:LeftFileBinding):RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftImageVideoMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftImageVideoMessageHolder.kt
new file mode 100755
index 0000000..9968e0c
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftImageVideoMessageHolder.kt
@@ -0,0 +1,7 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.CcImageVideoLayoutLeftBinding
+import com.inscripts.cometchatpulse.databinding.LeftTextBinding
+
+class LeftImageVideoMessageHolder(val binding: CcImageVideoLayoutLeftBinding): RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftLocationViewHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftLocationViewHolder.kt
new file mode 100755
index 0000000..943980e
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftLocationViewHolder.kt
@@ -0,0 +1,71 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.cometchat.pro.models.BaseMessage
+import com.cometchat.pro.models.TextMessage
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.MapsInitializer
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.MarkerOptions
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.databinding.LeftLocationBinding
+import java.lang.Exception
+
+class LeftLocationViewHolder(val binding:LeftLocationBinding):RecyclerView.ViewHolder(binding.root),OnMapReadyCallback {
+
+ var googleMap: GoogleMap? = null
+
+ init {
+
+ binding.map.onCreate(null)
+ binding.map.getMapAsync(this)
+ }
+
+
+ override fun onMapReady(p0: GoogleMap?) {
+ MapsInitializer.initialize(CometChatPro.applicationContext())
+ googleMap=p0
+ setMapLocation()
+ }
+
+ fun bindView(pos:Int,messageList:MutableList){
+ val item =messageList[pos]
+ binding.root.tag=this
+ binding.map.tag=item
+ setMapLocation()
+
+ }
+
+ private fun setMapLocation() {
+
+ try {
+
+
+ if (googleMap == null) return
+
+ val data: BaseMessage? = binding.map.tag as BaseMessage
+
+ if (data==null){
+ return
+ }
+
+ // Add a marker for this item and set the camera
+ val metadata=(data as TextMessage).metadata
+ val lat=metadata.getString("lat").toDouble()
+ val longt=metadata.getString("logt").toDouble()
+
+ googleMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(lat,longt), 20f))
+ googleMap?.addMarker(MarkerOptions().position(LatLng(lat,longt)))
+
+
+ // Set the map type back to normal.
+ googleMap?.mapType= GoogleMap.MAP_TYPE_NORMAL
+
+ }catch (e:Exception){
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftReplyMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftReplyMessageHolder.kt
new file mode 100755
index 0000000..d4b36b1
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftReplyMessageHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.LeftReplyBinding
+
+class LeftReplyMessageHolder(val binding:LeftReplyBinding):RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftTextMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftTextMessageHolder.kt
new file mode 100755
index 0000000..9db63dc
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/LeftTextMessageHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.LeftTextBinding
+
+class LeftTextMessageHolder(val binding: LeftTextBinding):RecyclerView.ViewHolder(binding.root)
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightAudioMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightAudioMessageHolder.kt
new file mode 100755
index 0000000..8f84087
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightAudioMessageHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.RightAudioBinding
+
+class RightAudioMessageHolder(val binding: RightAudioBinding):RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightFileViewHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightFileViewHolder.kt
new file mode 100755
index 0000000..5b59ee3
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightFileViewHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.RightFileBinding
+
+class RightFileViewHolder(val binding:RightFileBinding) :RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightImageVideoMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightImageVideoMessageHolder.kt
new file mode 100755
index 0000000..b2010d6
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightImageVideoMessageHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.CcImageVideoLayoutRightBinding
+
+class RightImageVideoMessageHolder (val binding: CcImageVideoLayoutRightBinding): RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightLocationViewHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightLocationViewHolder.kt
new file mode 100755
index 0000000..e657118
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightLocationViewHolder.kt
@@ -0,0 +1,78 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import android.view.View
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.MapsInitializer
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.inscripts.cometchatpulse.CometChatPro
+import com.inscripts.cometchatpulse.databinding.RightLocationBinding
+import android.widget.TextView
+import com.cometchat.pro.models.BaseMessage
+import com.cometchat.pro.models.MediaMessage
+import com.cometchat.pro.models.TextMessage
+import com.google.android.gms.maps.MapView
+import com.google.android.gms.maps.model.MarkerOptions
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.model.LatLng
+
+
+class RightLocationViewHolder(val binding: RightLocationBinding):
+ RecyclerView.ViewHolder(binding.root),OnMapReadyCallback{
+
+
+ var googleMap: GoogleMap? = null
+
+ init {
+
+ binding.map.onCreate(null)
+ binding.map.getMapAsync(this)
+ }
+
+
+ override fun onMapReady(p0: GoogleMap?) {
+ MapsInitializer.initialize(CometChatPro.applicationContext())
+ googleMap=p0
+ setMapLocation()
+ }
+
+ fun bindView(pos:Int,messageList:MutableList){
+ val item =messageList[pos]
+ binding.root.tag=this
+ binding.map.tag=item
+ setMapLocation()
+
+ }
+
+ private fun setMapLocation() {
+
+ try {
+
+
+ if (googleMap == null) return
+
+ val data:BaseMessage? = binding.map.tag as BaseMessage
+
+ if (data==null){
+ return
+ }
+
+ // Add a marker for this item and set the camera
+ val metadata=(data as TextMessage).metadata
+ val lat=metadata.getString("lat").toDouble()
+ val longt=metadata.getString("logt").toDouble()
+
+ googleMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(lat,longt), 20f))
+ googleMap?.addMarker(MarkerOptions().position(LatLng(lat,longt)))
+
+
+ // Set the map type back to normal.
+ googleMap?.mapType=GoogleMap.MAP_TYPE_NORMAL
+ }catch (e:Exception){
+
+ }
+ }
+
+
+
+}
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightReplyMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightReplyMessageHolder.kt
new file mode 100755
index 0000000..07d72bf
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightReplyMessageHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.RightReplyBinding
+
+class RightReplyMessageHolder(val binding:RightReplyBinding):RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightTextMessageHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightTextMessageHolder.kt
new file mode 100755
index 0000000..8175707
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/RightTextMessageHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.RightTextBinding
+
+class RightTextMessageHolder(val binding:RightTextBinding):RecyclerView.ViewHolder(binding.root)
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/TextHeaderHolder.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/TextHeaderHolder.kt
new file mode 100755
index 0000000..6f51542
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewHolder/TextHeaderHolder.kt
@@ -0,0 +1,6 @@
+package com.inscripts.cometchatpulse.ViewHolder
+
+import android.support.v7.widget.RecyclerView
+import com.inscripts.cometchatpulse.databinding.ListHeaderBinding
+
+class TextHeaderHolder(val binding:ListHeaderBinding): RecyclerView.ViewHolder(binding.root)
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/GroupChatViewModel.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/GroupChatViewModel.kt
new file mode 100755
index 0000000..786f715
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/GroupChatViewModel.kt
@@ -0,0 +1,116 @@
+package com.inscripts.cometchatpulse.ViewModel
+
+import android.app.Application
+import android.arch.lifecycle.AndroidViewModel
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.models.*
+import com.inscripts.cometchatpulse.Fragment.GroupFragment
+import com.inscripts.cometchatpulse.Fragment.MemberFragment
+import com.inscripts.cometchatpulse.Fragment.OneToOneFragment
+import com.inscripts.cometchatpulse.Repository.GroupRepository
+import com.inscripts.cometchatpulse.Repository.MessageRepository
+import com.inscripts.cometchatpulse.StringContract
+import org.json.JSONObject
+import java.io.File
+
+
+class GroupChatViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val groupRepository: GroupRepository
+
+ private val messageRepository: MessageRepository
+
+ val messageList: MutableLiveData>
+
+ val groupMemberList: MutableLiveData>
+
+ val banMemberList: MutableLiveData>
+
+
+ init {
+ groupRepository = GroupRepository()
+ messageRepository = MessageRepository()
+ banMemberList = groupRepository.banMemberLiveData
+ messageList = messageRepository.groupMessageList
+ groupMemberList = groupRepository.groupMemberLiveData
+ }
+
+ fun fetchMessage(LIMIT: Int, guid: String) {
+ messageRepository.fetchGroupMessage(guid, LIMIT)
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+
+ }
+
+ fun sendTextMessage(textMessage: TextMessage) {
+ messageRepository.sendTextMessage(textMessage)
+ }
+
+ fun addGroupEventListener(group_event_listener: String) {
+ messageRepository.addGroupListener(group_event_listener)
+ }
+
+ fun sendMediaMessage(path: String?, type: String?, guid: String,groupFragment:GroupFragment) {
+ val mediaMessage = MediaMessage(guid, File(path), type, CometChatConstants.RECEIVER_TYPE_GROUP)
+ val jObject = JSONObject()
+ jObject.put("path", path)
+ mediaMessage.metadata = jObject
+
+ if (GroupFragment.isReply){
+ GroupFragment.isReply=false
+ mediaMessage.metadata= GroupFragment.metaData?.put("path",path)
+ groupFragment.hideReplyContainer()
+ }
+ else{
+ mediaMessage.metadata=jObject
+ }
+ messageRepository.sendMediaMessage(mediaMessage)
+ }
+
+ fun removeGroupEventListener(group_event_listener: String) {
+ messageRepository.removeGroupListener(group_event_listener)
+ }
+
+
+
+ fun getMembers(guid: String, LIMIT: Int) {
+ groupRepository.getGroupMember(guid, LIMIT)
+ }
+
+ fun getBanedMember(guid: String, LIMIT: Int) {
+ groupRepository.getBannedMember(guid, LIMIT)
+ }
+
+ fun banMember(uid: String?, guid: String) {
+ uid?.let { groupRepository.banMember(it, guid) }
+ }
+
+ fun kickMember(uid: String?, guid: String) {
+ uid?.let { groupRepository.kickMember(it, guid) }
+ }
+
+ fun unbanMember(uid: String?, guid: String) {
+ uid?.let { groupRepository.unBanMember(guid, it) }
+ }
+
+ fun addGroupMessageListener(message_listener: String,ownerId:String) {
+ messageRepository.messageReceiveListener(message_listener,ownerId)
+ }
+
+ fun removeMessageListener(message_listener: String) {
+ messageRepository.removeMessageListener(message_listener)
+ }
+
+ fun removeCallListener(call_event_listener: String) {
+ messageRepository.removeCallListener(call_event_listener)
+ }
+
+ fun updateScope(fragment:MemberFragment,uid: String, guid: String,scope:String) {
+ groupRepository.updateScope(fragment,uid,guid,scope)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/GroupViewModel.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/GroupViewModel.kt
new file mode 100755
index 0000000..1b9bd6e
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/GroupViewModel.kt
@@ -0,0 +1,82 @@
+package com.inscripts.cometchatpulse.ViewModel
+
+import android.app.Application
+import android.app.ProgressDialog
+import android.arch.lifecycle.AndroidViewModel
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import android.support.v4.app.FragmentActivity
+import android.widget.RelativeLayout
+import com.cometchat.pro.core.Call
+import com.cometchat.pro.models.Group
+import com.cometchat.pro.models.GroupMember
+import com.facebook.shimmer.ShimmerFrameLayout
+import com.inscripts.cometchatpulse.Repository.MessageRepository
+import com.inscripts.cometchatpulse.Repository.GroupRepository
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlin.coroutines.CoroutineContext
+
+class GroupViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val groupRepository: GroupRepository
+
+ private val messageRepository:MessageRepository
+
+ val groupList:MutableLiveData>
+
+ val groupMemberList:MutableLiveData>
+
+
+
+ init {
+ groupRepository= GroupRepository()
+ messageRepository= MessageRepository()
+ groupList=groupRepository.groupList
+ groupMemberList=groupRepository.groupMemberLiveData
+
+ }
+
+ fun fetchGroups(LIMIT:Int,shimmerFrameLayout: ShimmerFrameLayout?){
+ groupRepository.fetchGroup(LIMIT,shimmerFrameLayout)
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+ groupRepository.clearjob()
+
+ }
+
+ fun createGroup(context: Context, group: Group) {
+ groupRepository.createGroup(context, group)
+ }
+
+ fun fetchGroupMemeber(LIMIT: Int,guid: String) {
+ groupRepository.getGroupMember(guid,LIMIT)
+ }
+
+ fun joinGroup(group: Group, progressDialog: ProgressDialog?,resId:Int,context: Context) {
+ groupRepository.joinGroup(group,progressDialog,resId,context)
+ }
+
+ fun initCall(context: Context?, guid: String, receiver_type: String, call_type: String) {
+ val call= Call(guid,receiver_type,call_type)
+ context?.let { messageRepository.initiateCall(call, it) }
+ }
+
+ fun leaveGroup(guid: String,activity: FragmentActivity?) {
+ groupRepository.leaveGroup(guid,activity)
+ }
+
+ fun deleteGroup(groupId: String,context: Context) {
+ groupRepository.deleteGroup(groupId,context)
+ }
+
+ fun addCallListener(applicationContext: Context, calL_EVENT_LISTENER: String, relative: RelativeLayout?) {
+ messageRepository.addCallListener(applicationContext,calL_EVENT_LISTENER,relative)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/OnetoOneViewModel.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/OnetoOneViewModel.kt
new file mode 100755
index 0000000..a94b11e
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/OnetoOneViewModel.kt
@@ -0,0 +1,116 @@
+package com.inscripts.cometchatpulse.ViewModel
+
+import android.app.Activity
+import android.app.Application
+import android.arch.lifecycle.AndroidViewModel
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import android.util.Log
+import android.widget.RelativeLayout
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.Call
+import com.cometchat.pro.models.BaseMessage
+import com.cometchat.pro.models.MediaMessage
+import com.cometchat.pro.models.TextMessage
+import com.cometchat.pro.models.User
+import com.inscripts.cometchatpulse.Fragment.OneToOneFragment
+import com.inscripts.cometchatpulse.Repository.MessageRepository
+import org.json.JSONObject
+import java.io.File
+
+class OnetoOneViewModel constructor(application: Application) : AndroidViewModel(application) {
+
+ private val messageRepository: MessageRepository
+
+ val messageList: MutableLiveData>
+
+ var user:MutableLiveData
+
+
+
+ init {
+ messageRepository = MessageRepository()
+ messageList = messageRepository.onetoOneMessageList
+ user=messageRepository.user
+
+ }
+
+ fun fetchMessage(LIMIT: Int,userId: String) {
+ messageRepository.fetchMessage(LIMIT, userId)
+ }
+
+
+ override fun onCleared() {
+ super.onCleared()
+
+ }
+
+ fun sendTextMessage(textMessage: TextMessage) {
+ messageRepository.sendTextMessage(textMessage)
+ }
+
+
+ fun receiveMessageListener(listener:String,ownerId: String) {
+ messageRepository.messageReceiveListener(listener,ownerId)
+ }
+
+ fun removeMessageListener(listener: String) {
+ messageRepository.removeMessageListener(listener)
+ }
+
+ fun addPresenceListener(listener: String) {
+ messageRepository.addPresenceListener(listener)
+ }
+
+ fun removePresenceListener(listener: String) {
+ messageRepository.removePresenceListener(listener)
+ }
+
+ fun sendMediaMessage(filePath:String?,type:String?,userId: String,oneToOneFragment:OneToOneFragment) {
+
+ val path = File(filePath)
+ Log.d("MediaMessage", " " + path.exists())
+
+ val mediaMessage = MediaMessage(userId, path, type, CometChatConstants.RECEIVER_TYPE_USER)
+ val jObject= JSONObject()
+ jObject.put("path",filePath)
+
+ Log.d("meta",jObject.toString())
+
+ if (OneToOneFragment.isReply){
+ OneToOneFragment.isReply=false
+ mediaMessage.metadata= OneToOneFragment.metaData?.put("path",filePath)
+ oneToOneFragment.hideReplyContainer()
+ }
+ else{
+ mediaMessage.metadata=jObject
+ }
+
+ messageRepository.sendMediaMessage(mediaMessage)
+ }
+
+ fun addCallListener(context: Context,call_event_listener: String,view:RelativeLayout?) {
+ messageRepository.addCallListener(context,call_event_listener, view)
+ }
+
+ fun removeCallListener(call_event_listener: String) {
+ messageRepository.removeCallListener(call_event_listener)
+ }
+
+ fun acceptCall(sessionID: String,view:RelativeLayout,activity: Activity) {
+ messageRepository.acceptCall(sessionID,view,activity)
+ }
+
+ fun rejectCall(sessionID: String, call_status_rejected: String,activity: Activity) {
+ messageRepository.rejectCall(sessionID,call_status_rejected,activity)
+ }
+
+ fun initCall(context: Context,userId: String, receiver_type: String, callType: String) {
+ val call=Call(userId,receiver_type,callType)
+ messageRepository.initiateCall(call,context)
+ }
+
+
+
+
+ }
\ No newline at end of file
diff --git a/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/UserViewModel.kt b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/UserViewModel.kt
new file mode 100755
index 0000000..dcd244a
--- /dev/null
+++ b/app/src/main/java/com/inscripts/cometchatpulse/ViewModel/UserViewModel.kt
@@ -0,0 +1,58 @@
+package com.inscripts.cometchatpulse.ViewModel
+
+import android.app.Application
+import android.arch.lifecycle.AndroidViewModel
+import android.arch.lifecycle.LiveData
+import android.arch.lifecycle.MutableLiveData
+import android.content.Context
+import com.cometchat.pro.constants.CometChatConstants
+import com.cometchat.pro.core.Call
+import com.cometchat.pro.models.User
+import com.facebook.shimmer.Shimmer
+import com.facebook.shimmer.ShimmerFrameLayout
+import com.inscripts.cometchatpulse.Repository.UserRepository
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlin.coroutines.CoroutineContext
+
+class UserViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val userRepository: UserRepository
+
+ val userList: MutableLiveData>
+
+ val user:MutableLiveData
+
+
+ init {
+ userRepository = UserRepository()
+ userList = userRepository.usersList
+ user=userRepository.user
+ }
+
+ fun fetchUser(LIMIT: Int,shimmer: ShimmerFrameLayout?){
+ userRepository.fetchUsers(LIMIT,shimmer)
+
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+ userRepository.clearjob()
+ }
+
+ fun addPresenceListener(listener: String) {
+ userRepository.addPresenceListener(listener)
+ }
+
+ fun removeUserListener(listener: String) {
+ userRepository.removeUserListener(listener)
+ }
+
+ fun initCall(context: Context, user: User) {
+ val call= Call(user.uid,CometChatConstants.RECEIVER_TYPE_USER,CometChatConstants.CALL_TYPE_VIDEO)
+ userRepository.initCall(context,call)
+ }
+}
+
diff --git a/app/src/main/res/animator/toolbar_elevation.xml b/app/src/main/res/animator/toolbar_elevation.xml
new file mode 100755
index 0000000..20e342d
--- /dev/null
+++ b/app/src/main/res/animator/toolbar_elevation.xml
@@ -0,0 +1,20 @@
+
+
+
+ -
+
+
+
+ -
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/cc_border.xml b/app/src/main/res/drawable-v21/cc_border.xml
new file mode 100755
index 0000000..2a15350
--- /dev/null
+++ b/app/src/main/res/drawable-v21/cc_border.xml
@@ -0,0 +1,13 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/cc_custom_left_bubble.xml b/app/src/main/res/drawable-v21/cc_custom_left_bubble.xml
new file mode 100755
index 0000000..53550c9
--- /dev/null
+++ b/app/src/main/res/drawable-v21/cc_custom_left_bubble.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-v21/cc_custom_right_bubble.xml b/app/src/main/res/drawable-v21/cc_custom_right_bubble.xml
new file mode 100755
index 0000000..db1436c
--- /dev/null
+++ b/app/src/main/res/drawable-v21/cc_custom_right_bubble.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-v21/cc_status_available.xml b/app/src/main/res/drawable-v21/cc_status_available.xml
new file mode 100755
index 0000000..3e4ece1
--- /dev/null
+++ b/app/src/main/res/drawable-v21/cc_status_available.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/cc_status_offline.xml b/app/src/main/res/drawable-v21/cc_status_offline.xml
new file mode 100755
index 0000000..d2fc195
--- /dev/null
+++ b/app/src/main/res/drawable-v21/cc_status_offline.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/edit_background.xml b/app/src/main/res/drawable-v21/edit_background.xml
new file mode 100755
index 0000000..5d58305
--- /dev/null
+++ b/app/src/main/res/drawable-v21/edit_background.xml
@@ -0,0 +1,11 @@
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/edit_text_round.xml b/app/src/main/res/drawable-v21/edit_text_round.xml
new file mode 100755
index 0000000..e88b48f
--- /dev/null
+++ b/app/src/main/res/drawable-v21/edit_text_round.xml
@@ -0,0 +1,14 @@
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v21/ic_attach_file_red_24dp.xml b/app/src/main/res/drawable-v21/ic_attach_file_red_24dp.xml
new file mode 100755
index 0000000..bd1adeb
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_attach_file_red_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_chevron_left_24dp.xml b/app/src/main/res/drawable-v21/ic_chevron_left_24dp.xml
new file mode 100755
index 0000000..b5f2815
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_chevron_left_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_keyboard_arrow_down_black_24dp.xml b/app/src/main/res/drawable-v21/ic_keyboard_arrow_down_black_24dp.xml
new file mode 100755
index 0000000..ce5f669
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_keyboard_arrow_down_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_lock_outline_red_24dp.xml b/app/src/main/res/drawable-v21/ic_lock_outline_red_24dp.xml
new file mode 100755
index 0000000..4396162
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_lock_outline_red_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_mic_24dp.xml b/app/src/main/res/drawable-v21/ic_mic_24dp.xml
new file mode 100755
index 0000000..28e8dbf
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_mic_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_outline_add_a_photo_24px.xml b/app/src/main/res/drawable-v21/ic_outline_add_a_photo_24px.xml
new file mode 100755
index 0000000..926eb2d
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_outline_add_a_photo_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_outline_call_24px.xml b/app/src/main/res/drawable-v21/ic_outline_call_24px.xml
new file mode 100755
index 0000000..62b2ac7
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_outline_call_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_outline_image_24px.xml b/app/src/main/res/drawable-v21/ic_outline_image_24px.xml
new file mode 100755
index 0000000..6e630ae
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_outline_image_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_outline_insert_drive_file_24px.xml b/app/src/main/res/drawable-v21/ic_outline_insert_drive_file_24px.xml
new file mode 100755
index 0000000..32d5406
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_outline_insert_drive_file_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_outline_video_call_24px.xml b/app/src/main/res/drawable-v21/ic_outline_video_call_24px.xml
new file mode 100755
index 0000000..b217fc7
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_outline_video_call_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_outline_videocam_24px.xml b/app/src/main/res/drawable-v21/ic_outline_videocam_24px.xml
new file mode 100755
index 0000000..e4214db
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_outline_videocam_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable-v21/ic_perm_24dp.xml b/app/src/main/res/drawable-v21/ic_perm_24dp.xml
new file mode 100755
index 0000000..696aba3
--- /dev/null
+++ b/app/src/main/res/drawable-v21/ic_perm_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100755
index 0000000..1f6bb29
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/button_background.xml b/app/src/main/res/drawable/button_background.xml
new file mode 100755
index 0000000..d6c08a4
--- /dev/null
+++ b/app/src/main/res/drawable/button_background.xml
@@ -0,0 +1,10 @@
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/cc_custom_left_bubble.xml b/app/src/main/res/drawable/cc_custom_left_bubble.xml
new file mode 100755
index 0000000..c9646f5
--- /dev/null
+++ b/app/src/main/res/drawable/cc_custom_left_bubble.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/cc_custom_right_bubble.xml b/app/src/main/res/drawable/cc_custom_right_bubble.xml
new file mode 100755
index 0000000..c0e457d
--- /dev/null
+++ b/app/src/main/res/drawable/cc_custom_right_bubble.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/cc_play_video_button.png b/app/src/main/res/drawable/cc_play_video_button.png
new file mode 100755
index 0000000..c0be7c1
Binary files /dev/null and b/app/src/main/res/drawable/cc_play_video_button.png differ
diff --git a/app/src/main/res/drawable/cc_rounded_date_button.xml b/app/src/main/res/drawable/cc_rounded_date_button.xml
new file mode 100755
index 0000000..761ec4e
--- /dev/null
+++ b/app/src/main/res/drawable/cc_rounded_date_button.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/cc_small.png b/app/src/main/res/drawable/cc_small.png
new file mode 100755
index 0000000..d66848a
Binary files /dev/null and b/app/src/main/res/drawable/cc_small.png differ
diff --git a/app/src/main/res/drawable/cc_status_available.xml b/app/src/main/res/drawable/cc_status_available.xml
new file mode 100755
index 0000000..10d4283
--- /dev/null
+++ b/app/src/main/res/drawable/cc_status_available.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/cc_status_offline.xml b/app/src/main/res/drawable/cc_status_offline.xml
new file mode 100755
index 0000000..af6414e
--- /dev/null
+++ b/app/src/main/res/drawable/cc_status_offline.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/cometchat.png b/app/src/main/res/drawable/cometchat.png
new file mode 100755
index 0000000..1024993
Binary files /dev/null and b/app/src/main/res/drawable/cometchat.png differ
diff --git a/app/src/main/res/drawable/default_avatar.xml b/app/src/main/res/drawable/default_avatar.xml
new file mode 100755
index 0000000..3e661e8
--- /dev/null
+++ b/app/src/main/res/drawable/default_avatar.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/edit_background.xml b/app/src/main/res/drawable/edit_background.xml
new file mode 100755
index 0000000..1c1e885
--- /dev/null
+++ b/app/src/main/res/drawable/edit_background.xml
@@ -0,0 +1,11 @@
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/edit_text_round.xml b/app/src/main/res/drawable/edit_text_round.xml
new file mode 100755
index 0000000..6b6c59f
--- /dev/null
+++ b/app/src/main/res/drawable/edit_text_round.xml
@@ -0,0 +1,14 @@
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_access_time_24dp.xml b/app/src/main/res/drawable/ic_access_time_24dp.xml
new file mode 100755
index 0000000..87e8fda
--- /dev/null
+++ b/app/src/main/res/drawable/ic_access_time_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_artboard.xml b/app/src/main/res/drawable/ic_artboard.xml
new file mode 100644
index 0000000..c9ea996
--- /dev/null
+++ b/app/src/main/res/drawable/ic_artboard.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_attach_file_red_24dp.xml b/app/src/main/res/drawable/ic_attach_file_red_24dp.xml
new file mode 100755
index 0000000..260f227
--- /dev/null
+++ b/app/src/main/res/drawable/ic_attach_file_red_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_broken_image.xml b/app/src/main/res/drawable/ic_broken_image.xml
new file mode 100755
index 0000000..39d7e9b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_broken_image.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_broken_image_black.xml b/app/src/main/res/drawable/ic_broken_image_black.xml
new file mode 100755
index 0000000..88157dd
--- /dev/null
+++ b/app/src/main/res/drawable/ic_broken_image_black.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_call_24dp.xml b/app/src/main/res/drawable/ic_call_24dp.xml
new file mode 100755
index 0000000..7e6f97c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_call_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_call_end_24dp.xml b/app/src/main/res/drawable/ic_call_end_24dp.xml
new file mode 100755
index 0000000..edca9bf
--- /dev/null
+++ b/app/src/main/res/drawable/ic_call_end_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_chat_bubble_outline_black_24dp.xml b/app/src/main/res/drawable/ic_chat_bubble_outline_black_24dp.xml
new file mode 100755
index 0000000..880a1b1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chat_bubble_outline_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_chats.xml b/app/src/main/res/drawable/ic_chats.xml
new file mode 100755
index 0000000..8b33d2a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chats.xml
@@ -0,0 +1,6 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_check_24dp.xml b/app/src/main/res/drawable/ic_check_24dp.xml
new file mode 100755
index 0000000..17aca2a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_check_black_24dp.xml b/app/src/main/res/drawable/ic_check_black_24dp.xml
new file mode 100755
index 0000000..17aca2a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_chevron_left_24dp.xml b/app/src/main/res/drawable/ic_chevron_left_24dp.xml
new file mode 100755
index 0000000..748786a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_chevron_left_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_close_24dp.xml b/app/src/main/res/drawable/ic_close_24dp.xml
new file mode 100755
index 0000000..a8cce60
--- /dev/null
+++ b/app/src/main/res/drawable/ic_close_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_contacts.xml b/app/src/main/res/drawable/ic_contacts.xml
new file mode 100644
index 0000000..7f4f035
--- /dev/null
+++ b/app/src/main/res/drawable/ic_contacts.xml
@@ -0,0 +1,18 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_createbutton.xml b/app/src/main/res/drawable/ic_createbutton.xml
new file mode 100644
index 0000000..3e2c896
--- /dev/null
+++ b/app/src/main/res/drawable/ic_createbutton.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_delete_black_24dp.xml b/app/src/main/res/drawable/ic_delete_black_24dp.xml
new file mode 100755
index 0000000..39e64d6
--- /dev/null
+++ b/app/src/main/res/drawable/ic_delete_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_description_black_24dp.xml b/app/src/main/res/drawable/ic_description_black_24dp.xml
new file mode 100755
index 0000000..74f6fc1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_description_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml b/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml
new file mode 100755
index 0000000..6f40d77
--- /dev/null
+++ b/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_file_download.xml b/app/src/main/res/drawable/ic_file_download.xml
new file mode 100644
index 0000000..84db281
--- /dev/null
+++ b/app/src/main/res/drawable/ic_file_download.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_group_default.xml b/app/src/main/res/drawable/ic_group_default.xml
new file mode 100755
index 0000000..3f6027b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_group_default.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_groups.xml b/app/src/main/res/drawable/ic_groups.xml
new file mode 100644
index 0000000..4f9b63a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_groups.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_info_outline_24dp.xml b/app/src/main/res/drawable/ic_info_outline_24dp.xml
new file mode 100755
index 0000000..20ae39f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_info_outline_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_insert_drive_file_24dp.xml b/app/src/main/res/drawable/ic_insert_drive_file_24dp.xml
new file mode 100755
index 0000000..a431a5e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_insert_drive_file_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_insert_drive_file_black_24dp.xml b/app/src/main/res/drawable/ic_insert_drive_file_black_24dp.xml
new file mode 100755
index 0000000..7a6d094
--- /dev/null
+++ b/app/src/main/res/drawable/ic_insert_drive_file_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml
new file mode 100755
index 0000000..7879b24
--- /dev/null
+++ b/app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_right_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_right_24dp.xml
new file mode 100755
index 0000000..0789c22
--- /dev/null
+++ b/app/src/main/res/drawable/ic_keyboard_arrow_right_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100755
index 0000000..0d025f9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_location_on_black_24dp.xml b/app/src/main/res/drawable/ic_location_on_black_24dp.xml
new file mode 100755
index 0000000..e3291a9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_location_on_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_lock_outline_black_24dp.xml b/app/src/main/res/drawable/ic_lock_outline_black_24dp.xml
new file mode 100755
index 0000000..9a14b68
--- /dev/null
+++ b/app/src/main/res/drawable/ic_lock_outline_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_lock_outline_grey_24dp.xml b/app/src/main/res/drawable/ic_lock_outline_grey_24dp.xml
new file mode 100755
index 0000000..520ef53
--- /dev/null
+++ b/app/src/main/res/drawable/ic_lock_outline_grey_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_lock_outline_red_24dp.xml b/app/src/main/res/drawable/ic_lock_outline_red_24dp.xml
new file mode 100755
index 0000000..76d5d79
--- /dev/null
+++ b/app/src/main/res/drawable/ic_lock_outline_red_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_mic_24dp.xml b/app/src/main/res/drawable/ic_mic_24dp.xml
new file mode 100755
index 0000000..d652f36
--- /dev/null
+++ b/app/src/main/res/drawable/ic_mic_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_more.xml b/app/src/main/res/drawable/ic_more.xml
new file mode 100755
index 0000000..7553fe4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_more.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_more_vert.xml b/app/src/main/res/drawable/ic_more_vert.xml
new file mode 100755
index 0000000..c097d3e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_more_vert.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_my_location_24dp.xml b/app/src/main/res/drawable/ic_my_location_24dp.xml
new file mode 100755
index 0000000..1d28825
--- /dev/null
+++ b/app/src/main/res/drawable/ic_my_location_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_account_circle_24px.xml b/app/src/main/res/drawable/ic_outline_account_circle_24px.xml
new file mode 100755
index 0000000..0c9a104
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_account_circle_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_add_a_photo_24px.xml b/app/src/main/res/drawable/ic_outline_add_a_photo_24px.xml
new file mode 100755
index 0000000..8333e3c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_add_a_photo_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_call_24px.xml b/app/src/main/res/drawable/ic_outline_call_24px.xml
new file mode 100755
index 0000000..e316545
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_call_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_group_add_24px.xml b/app/src/main/res/drawable/ic_outline_group_add_24px.xml
new file mode 100755
index 0000000..e8e9897
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_group_add_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_home_24px.xml b/app/src/main/res/drawable/ic_outline_home_24px.xml
new file mode 100755
index 0000000..ad6065c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_home_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_image_24px.xml b/app/src/main/res/drawable/ic_outline_image_24px.xml
new file mode 100755
index 0000000..97d080d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_image_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_insert_drive_file_24px.xml b/app/src/main/res/drawable/ic_outline_insert_drive_file_24px.xml
new file mode 100755
index 0000000..c803616
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_insert_drive_file_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_video_call_24px.xml b/app/src/main/res/drawable/ic_outline_video_call_24px.xml
new file mode 100755
index 0000000..444aeb9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_video_call_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_video_call_white_24px.xml b/app/src/main/res/drawable/ic_outline_video_call_white_24px.xml
new file mode 100755
index 0000000..b706c24
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_video_call_white_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_outline_videocam_24px.xml b/app/src/main/res/drawable/ic_outline_videocam_24px.xml
new file mode 100755
index 0000000..67b6f19
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_videocam_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_pause_black_24dp.xml b/app/src/main/res/drawable/ic_pause_black_24dp.xml
new file mode 100755
index 0000000..bb28a6c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_pause_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_pause_white_24dp.xml b/app/src/main/res/drawable/ic_pause_white_24dp.xml
new file mode 100755
index 0000000..1696640
--- /dev/null
+++ b/app/src/main/res/drawable/ic_pause_white_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_people_outline_black_24dp.xml b/app/src/main/res/drawable/ic_people_outline_black_24dp.xml
new file mode 100755
index 0000000..ecdc122
--- /dev/null
+++ b/app/src/main/res/drawable/ic_people_outline_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_perm_24dp.xml b/app/src/main/res/drawable/ic_perm_24dp.xml
new file mode 100755
index 0000000..d2d1693
--- /dev/null
+++ b/app/src/main/res/drawable/ic_perm_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_person_add_black_24dp.xml b/app/src/main/res/drawable/ic_person_add_black_24dp.xml
new file mode 100755
index 0000000..225ae0a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_person_add_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_person_black_24dp.xml b/app/src/main/res/drawable/ic_person_black_24dp.xml
new file mode 100755
index 0000000..b2cb337
--- /dev/null
+++ b/app/src/main/res/drawable/ic_person_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_play_arrow.xml b/app/src/main/res/drawable/ic_play_arrow.xml
new file mode 100755
index 0000000..5f18c23
--- /dev/null
+++ b/app/src/main/res/drawable/ic_play_arrow.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_play_arrow_black.xml b/app/src/main/res/drawable/ic_play_arrow_black.xml
new file mode 100755
index 0000000..a95b173
--- /dev/null
+++ b/app/src/main/res/drawable/ic_play_arrow_black.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_play_circle.xml b/app/src/main/res/drawable/ic_play_circle.xml
new file mode 100755
index 0000000..41bec11
--- /dev/null
+++ b/app/src/main/res/drawable/ic_play_circle.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_reply_24dp.xml b/app/src/main/res/drawable/ic_reply_24dp.xml
new file mode 100755
index 0000000..3aff3f9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_reply_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml
new file mode 100755
index 0000000..affc7ba
--- /dev/null
+++ b/app/src/main/res/drawable/ic_search_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_send_24dp.xml b/app/src/main/res/drawable/ic_send_24dp.xml
new file mode 100755
index 0000000..33efc5c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_send_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_supervisor_account_black_24dp.xml b/app/src/main/res/drawable/ic_supervisor_account_black_24dp.xml
new file mode 100755
index 0000000..8aa9c18
--- /dev/null
+++ b/app/src/main/res/drawable/ic_supervisor_account_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/login.png b/app/src/main/res/drawable/login.png
new file mode 100755
index 0000000..8252773
Binary files /dev/null and b/app/src/main/res/drawable/login.png differ
diff --git a/app/src/main/res/drawable/login_button.xml b/app/src/main/res/drawable/login_button.xml
new file mode 100755
index 0000000..c676111
--- /dev/null
+++ b/app/src/main/res/drawable/login_button.xml
@@ -0,0 +1,10 @@
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/password_background.xml b/app/src/main/res/drawable/password_background.xml
new file mode 100755
index 0000000..c5d376c
--- /dev/null
+++ b/app/src/main/res/drawable/password_background.xml
@@ -0,0 +1,11 @@
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/reply_container_border.xml b/app/src/main/res/drawable/reply_container_border.xml
new file mode 100755
index 0000000..6ccc05e
--- /dev/null
+++ b/app/src/main/res/drawable/reply_container_border.xml
@@ -0,0 +1,21 @@
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/reply_left.xml b/app/src/main/res/drawable/reply_left.xml
new file mode 100755
index 0000000..26c89aa
--- /dev/null
+++ b/app/src/main/res/drawable/reply_left.xml
@@ -0,0 +1,21 @@
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shimmer_status.xml b/app/src/main/res/drawable/shimmer_status.xml
new file mode 100755
index 0000000..4571223
--- /dev/null
+++ b/app/src/main/res/drawable/shimmer_status.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout-sw600dp/activity_main.xml b/app/src/main/res/layout-sw600dp/activity_main.xml
new file mode 100755
index 0000000..3dc9a56
--- /dev/null
+++ b/app/src/main/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout-sw600dp/fragment_contact_list.xml b/app/src/main/res/layout-sw600dp/fragment_contact_list.xml
new file mode 100755
index 0000000..3e1d976
--- /dev/null
+++ b/app/src/main/res/layout-sw600dp/fragment_contact_list.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout-sw600dp/fragment_group_list.xml b/app/src/main/res/layout-sw600dp/fragment_group_list.xml
new file mode 100755
index 0000000..c729bc4
--- /dev/null
+++ b/app/src/main/res/layout-sw600dp/fragment_group_list.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_call.xml b/app/src/main/res/layout/activity_call.xml
new file mode 100755
index 0000000..92ec8ea
--- /dev/null
+++ b/app/src/main/res/layout/activity_call.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_create_group.xml b/app/src/main/res/layout/activity_create_group.xml
new file mode 100755
index 0000000..46b8c3d
--- /dev/null
+++ b/app/src/main/res/layout/activity_create_group.xml
@@ -0,0 +1,238 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_group_chat.xml b/app/src/main/res/layout/activity_group_chat.xml
new file mode 100755
index 0000000..4fa8ff3
--- /dev/null
+++ b/app/src/main/res/layout/activity_group_chat.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_group_detail.xml b/app/src/main/res/layout/activity_group_detail.xml
new file mode 100755
index 0000000..f460b6e
--- /dev/null
+++ b/app/src/main/res/layout/activity_group_detail.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_image_view.xml b/app/src/main/res/layout/activity_image_view.xml
new file mode 100755
index 0000000..5faeb1a
--- /dev/null
+++ b/app/src/main/res/layout/activity_image_view.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_location.xml b/app/src/main/res/layout/activity_location.xml
new file mode 100755
index 0000000..a3aab47
--- /dev/null
+++ b/app/src/main/res/layout/activity_location.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
new file mode 100755
index 0000000..ad950b7
--- /dev/null
+++ b/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..7648b24
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_user_profile_view.xml b/app/src/main/res/layout/activity_user_profile_view.xml
new file mode 100755
index 0000000..27994fb
--- /dev/null
+++ b/app/src/main/res/layout/activity_user_profile_view.xml
@@ -0,0 +1,186 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/attachment_type_selector.xml b/app/src/main/res/layout/attachment_type_selector.xml
new file mode 100755
index 0000000..5ea5174
--- /dev/null
+++ b/app/src/main/res/layout/attachment_type_selector.xml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/cc_custom_dialog.xml b/app/src/main/res/layout/cc_custom_dialog.xml
new file mode 100755
index 0000000..a90b527
--- /dev/null
+++ b/app/src/main/res/layout/cc_custom_dialog.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/cc_image_video_layout_left.xml b/app/src/main/res/layout/cc_image_video_layout_left.xml
new file mode 100755
index 0000000..b34fca7
--- /dev/null
+++ b/app/src/main/res/layout/cc_image_video_layout_left.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/cc_image_video_layout_right.xml b/app/src/main/res/layout/cc_image_video_layout_right.xml
new file mode 100755
index 0000000..97e9ba2
--- /dev/null
+++ b/app/src/main/res/layout/cc_image_video_layout_right.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/contact_item.xml b/app/src/main/res/layout/contact_item.xml
new file mode 100755
index 0000000..7d7d9eb
--- /dev/null
+++ b/app/src/main/res/layout/contact_item.xml
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/contact_placeholder.xml b/app/src/main/res/layout/contact_placeholder.xml
new file mode 100755
index 0000000..3d4ee35
--- /dev/null
+++ b/app/src/main/res/layout/contact_placeholder.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_ban_member.xml b/app/src/main/res/layout/fragment_ban_member.xml
new file mode 100755
index 0000000..b0fc28a
--- /dev/null
+++ b/app/src/main/res/layout/fragment_ban_member.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_contact_detail.xml b/app/src/main/res/layout/fragment_contact_detail.xml
new file mode 100755
index 0000000..d2b6a35
--- /dev/null
+++ b/app/src/main/res/layout/fragment_contact_detail.xml
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_contact_list.xml b/app/src/main/res/layout/fragment_contact_list.xml
new file mode 100755
index 0000000..a501e0d
--- /dev/null
+++ b/app/src/main/res/layout/fragment_contact_list.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_group.xml b/app/src/main/res/layout/fragment_group.xml
new file mode 100755
index 0000000..6b47345
--- /dev/null
+++ b/app/src/main/res/layout/fragment_group.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_group_list.xml b/app/src/main/res/layout/fragment_group_list.xml
new file mode 100755
index 0000000..032a9e7
--- /dev/null
+++ b/app/src/main/res/layout/fragment_group_list.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
new file mode 100755
index 0000000..9ac9d5e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml
new file mode 100755
index 0000000..55eb3c4
--- /dev/null
+++ b/app/src/main/res/layout/fragment_profile.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/group_list_item.xml b/app/src/main/res/layout/group_list_item.xml
new file mode 100755
index 0000000..64ed148
--- /dev/null
+++ b/app/src/main/res/layout/group_list_item.xml
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/group_member_item.xml b/app/src/main/res/layout/group_member_item.xml
new file mode 100755
index 0000000..d7dfa6e
--- /dev/null
+++ b/app/src/main/res/layout/group_member_item.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/group_option_item.xml b/app/src/main/res/layout/group_option_item.xml
new file mode 100755
index 0000000..0d53d87
--- /dev/null
+++ b/app/src/main/res/layout/group_option_item.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/group_placeholder.xml b/app/src/main/res/layout/group_placeholder.xml
new file mode 100755
index 0000000..adff7f2
--- /dev/null
+++ b/app/src/main/res/layout/group_placeholder.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_list_content.xml b/app/src/main/res/layout/item_list_content.xml
new file mode 100755
index 0000000..395ec3e
--- /dev/null
+++ b/app/src/main/res/layout/item_list_content.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/left_audio.xml b/app/src/main/res/layout/left_audio.xml
new file mode 100755
index 0000000..7c818d2
--- /dev/null
+++ b/app/src/main/res/layout/left_audio.xml
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/left_file.xml b/app/src/main/res/layout/left_file.xml
new file mode 100755
index 0000000..7061156
--- /dev/null
+++ b/app/src/main/res/layout/left_file.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/left_location.xml b/app/src/main/res/layout/left_location.xml
new file mode 100755
index 0000000..b5d0803
--- /dev/null
+++ b/app/src/main/res/layout/left_location.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/left_reply.xml b/app/src/main/res/layout/left_reply.xml
new file mode 100755
index 0000000..e34273d
--- /dev/null
+++ b/app/src/main/res/layout/left_reply.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/left_text.xml b/app/src/main/res/layout/left_text.xml
new file mode 100755
index 0000000..955b09b
--- /dev/null
+++ b/app/src/main/res/layout/left_text.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_header.xml b/app/src/main/res/layout/list_header.xml
new file mode 100755
index 0000000..b155e76
--- /dev/null
+++ b/app/src/main/res/layout/list_header.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/message_edit_box.xml b/app/src/main/res/layout/message_edit_box.xml
new file mode 100755
index 0000000..27f0d0f
--- /dev/null
+++ b/app/src/main/res/layout/message_edit_box.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/record_audio.xml b/app/src/main/res/layout/record_audio.xml
new file mode 100755
index 0000000..d2fd3da
--- /dev/null
+++ b/app/src/main/res/layout/record_audio.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/reply_container.xml b/app/src/main/res/layout/reply_container.xml
new file mode 100755
index 0000000..6a8686d
--- /dev/null
+++ b/app/src/main/res/layout/reply_container.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/right_audio.xml b/app/src/main/res/layout/right_audio.xml
new file mode 100755
index 0000000..e6657b5
--- /dev/null
+++ b/app/src/main/res/layout/right_audio.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/right_file.xml b/app/src/main/res/layout/right_file.xml
new file mode 100755
index 0000000..2c0b96f
--- /dev/null
+++ b/app/src/main/res/layout/right_file.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/right_location.xml b/app/src/main/res/layout/right_location.xml
new file mode 100755
index 0000000..3d38c33
--- /dev/null
+++ b/app/src/main/res/layout/right_location.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/right_reply.xml b/app/src/main/res/layout/right_reply.xml
new file mode 100755
index 0000000..98dccbe
--- /dev/null
+++ b/app/src/main/res/layout/right_reply.xml
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/right_text.xml b/app/src/main/res/layout/right_text.xml
new file mode 100755
index 0000000..e7528f8
--- /dev/null
+++ b/app/src/main/res/layout/right_text.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/action_bar.xml b/app/src/main/res/menu/action_bar.xml
new file mode 100755
index 0000000..eed8f4e
--- /dev/null
+++ b/app/src/main/res/menu/action_bar.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/create_menu.xml b/app/src/main/res/menu/create_menu.xml
new file mode 100755
index 0000000..1c34af3
--- /dev/null
+++ b/app/src/main/res/menu/create_menu.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml
new file mode 100755
index 0000000..3eba669
--- /dev/null
+++ b/app/src/main/res/menu/main_menu.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/member_menu.xml b/app/src/main/res/menu/member_menu.xml
new file mode 100755
index 0000000..f094cc4
--- /dev/null
+++ b/app/src/main/res/menu/member_menu.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_group_action.xml b/app/src/main/res/menu/menu_group_action.xml
new file mode 100755
index 0000000..4e3e8b8
--- /dev/null
+++ b/app/src/main/res/menu/menu_group_action.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/navigation_menu.xml b/app/src/main/res/menu/navigation_menu.xml
new file mode 100755
index 0000000..6d2c930
--- /dev/null
+++ b/app/src/main/res/menu/navigation_menu.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/option_menu.xml b/app/src/main/res/menu/option_menu.xml
new file mode 100755
index 0000000..e48e9c9
--- /dev/null
+++ b/app/src/main/res/menu/option_menu.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100755
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100755
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100755
index 0000000..898f3ed
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100755
index 0000000..dffca36
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100755
index 0000000..64ba76f
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100755
index 0000000..dae5e08
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..e5ed465
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..14ed0af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..b0907ca
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..d8ae031
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/cc_small.png b/app/src/main/res/mipmap-xxxhdpi/cc_small.png
new file mode 100755
index 0000000..d66848a
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/cc_small.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100755
index 0000000..2c18de9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..beed3cd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/raw/beep2.mp3 b/app/src/main/res/raw/beep2.mp3
new file mode 100755
index 0000000..4d6da55
Binary files /dev/null and b/app/src/main/res/raw/beep2.mp3 differ
diff --git a/app/src/main/res/raw/record_error.wav b/app/src/main/res/raw/record_error.wav
new file mode 100755
index 0000000..9749c15
Binary files /dev/null and b/app/src/main/res/raw/record_error.wav differ
diff --git a/app/src/main/res/raw/record_finished.wav b/app/src/main/res/raw/record_finished.wav
new file mode 100755
index 0000000..3844708
Binary files /dev/null and b/app/src/main/res/raw/record_finished.wav differ
diff --git a/app/src/main/res/raw/record_start.wav b/app/src/main/res/raw/record_start.wav
new file mode 100755
index 0000000..cc4a1f3
Binary files /dev/null and b/app/src/main/res/raw/record_start.wav differ
diff --git a/app/src/main/res/raw/ring.mp3 b/app/src/main/res/raw/ring.mp3
new file mode 100755
index 0000000..e69de29
diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml
new file mode 100755
index 0000000..7fc50f3
--- /dev/null
+++ b/app/src/main/res/values/array.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+ - #e51c23
+ - #e91e63
+ - #9c27b0
+ - #673ab7
+ - #3f51b5
+ - #5677fc
+ - #03a9f4
+ - #00bcd4
+ - #009688
+ - #259b24
+ - #8bc34a
+ - #cddc39
+ - #ffeb3b
+ - #ff9800
+ - #ff5722
+ - #795548
+ - #9e9e9e
+ - #607d8b
+
+ - #d01716
+ - #c2185b
+ - #7b1fa2
+ - #512da8
+ - #303f9f
+ - #455ede
+ - #0288d1
+ - #0097a7
+ - #00796b
+ - #0a7e07
+ - #689f38
+ - #afb42b
+ - #fbc02d
+ - #f57c00
+ - #e64a19
+ - #5d4037
+ - #616161
+ - #455a64
+
+ - #c41411
+ - #ad1457
+ - #6a1b9a
+ - #4527a0
+ - #283593
+ - #3b50ce
+ - #0277bd
+ - #00838f
+ - #00695c
+ - #056f00
+ - #558b2f
+ - #9e9d24
+ - #f9a825
+ - #ef6c00
+ - #d84315
+ - #4e342e
+ - #424242
+ - #37474f
+
+ - #ff2d6f
+ - #f50057
+ - #d500f9
+ - #651fff
+ - #3d5afe
+ - #4d73ff
+ - #00b0ff
+ - #00e5ff
+ - #1de9b6
+ - #14e715
+ - #76ff03
+ - #c6ff00
+ - #ffea00
+ - #ff9100
+ - #ff3d00
+
+ - #e00032
+ - #c51162
+ - #aa00ff
+ - #6200ea
+ - #304ffe
+ - #4d69ff
+ - #0091ea
+ - #00b8d4
+ - #00bfa5
+ - #12c700
+ - #64dd17
+ - #aeea00
+ - #ffd600
+ - #ff6d00
+ - #dd2c00
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attr.xml b/app/src/main/res/values/attr.xml
new file mode 100755
index 0000000..7d75872
--- /dev/null
+++ b/app/src/main/res/values/attr.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100755
index 0000000..81fdcc9
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,21 @@
+
+
+ #0084ff
+ #69b3ff
+ #0058cb
+
+
+ #000000
+ #CACACC
+ #fafafa
+ #E53935
+ #ffffff
+ #ffffff
+ #9e9e9e
+ #65ef4d
+ #43A047
+ #f2a757
+ #eaeaea
+ #dddddd
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100755
index 0000000..62ff363
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,10 @@
+
+
+ 16sp
+ 12sp
+ 16dp
+ 200dp
+ 200dp
+ 16dp
+ 14sp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100755
index 0000000..4c9dffa
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,46 @@
+
+ CometChat Pro
+
+
+ Hello blank fragment
+ Items
+ Item Detail
+ Type your message
+
+
+
+ - Select Group Type
+ - public
+ - private
+ - password
+
+
+
+ Last seen today at
+ Slide to cancel
+ password
+ group
+ image
+ video
+ image
+ Last seen yesterday at
+ Gallary
+ Camera
+ Video
+ Audio
+ Document
+ user
+ Joining
+ Group Password
+ Cancel
+ Ok
+ Enter
+ Can Not Join Group No Internet
+ Incorrect Password
+ Members
+ Ban Members
+ Map
+ Group Members
+ Group Details
+
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100755
index 0000000..78750ac
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/release/res/values/google_maps_api.xml b/app/src/release/res/values/google_maps_api.xml
new file mode 100755
index 0000000..1ef79e9
--- /dev/null
+++ b/app/src/release/res/values/google_maps_api.xml
@@ -0,0 +1,20 @@
+
+
+ YOUR_KEY_HERE
+
diff --git a/app/src/test/java/com/inscripts/cometchatpulse/ExampleUnitTest.kt b/app/src/test/java/com/inscripts/cometchatpulse/ExampleUnitTest.kt
new file mode 100755
index 0000000..fef5d05
--- /dev/null
+++ b/app/src/test/java/com/inscripts/cometchatpulse/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.inscripts.cometchatpulse
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
diff --git a/app/src/test/java/com/inscripts/cometchatpulse/LoginTest.java b/app/src/test/java/com/inscripts/cometchatpulse/LoginTest.java
new file mode 100644
index 0000000..50c93f4
--- /dev/null
+++ b/app/src/test/java/com/inscripts/cometchatpulse/LoginTest.java
@@ -0,0 +1,11 @@
+package com.inscripts.cometchatpulse;
+
+import org.junit.Test;
+
+public class LoginTest {
+
+ @Test
+ public void loginWith(){
+
+ }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100755
index 0000000..dfa9aed
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,40 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.3.11'
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.2.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.google.gms:google-services:4.2.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ maven {
+ url "https://dl.bintray.com/cometchat/pro"
+ }
+ repositories {
+ maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
+ }
+
+ maven {
+ url "https://maven.google.com"
+ }
+ maven {url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases"}
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
+
diff --git a/gradle.properties b/gradle.properties
new file mode 100755
index 0000000..49b4c72
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,15 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+android.databinding.enableV2=false
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100755
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100755
index 0000000..9a4163a
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100755
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100755
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'