Merge branch 'development' into ishita-checkpoint-integration

This commit is contained in:
Adarsh S
2022-05-31 15:02:57 +05:30
committed by GitHub Enterprise
33 changed files with 377 additions and 70 deletions

View File

@@ -198,7 +198,9 @@ class OfferRejectedFragment : BaseFragment(), FragmentListener {
currentUserName = PreferenceManager.getObjectPrefrences(
Constants.CURRENT_USER,
UserDetail::class.java
)?.name.orEmpty()
)?.name.orEmpty(),
externalCustomerId = PreferenceManager.getStringPreference(USER_EXTERNAL_ID)
.orEmpty()
)
val intent = Intent(context, NaviChatActivity::class.java)
val bundle = Bundle()

View File

@@ -122,8 +122,12 @@ class ProfileRejectedFragment : BaseFragment(), FragmentListener {
}
).orEmpty(),
sourceId = DEFAULT_SOURCE_ID_FOR_PL,
currentUserName = PreferenceManager.getObjectPrefrences(Constants.CURRENT_USER,
UserDetail::class.java)?.name.orEmpty()
currentUserName = PreferenceManager.getObjectPrefrences(
Constants.CURRENT_USER,
UserDetail::class.java
)?.name.orEmpty(),
externalCustomerId = PreferenceManager.getStringPreference(USER_EXTERNAL_ID)
.orEmpty()
)
val intent = Intent(context, NaviChatActivity::class.java)
val bundle = Bundle()

View File

@@ -8,6 +8,7 @@ package com.navi.chat.base
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.navi.chat.R
import com.navi.chat.ui.fragments.NaviChatErrorFragment
import com.navi.chat.utils.ErrorState
import com.navi.chat.utils.LoaderState
@@ -34,7 +35,10 @@ abstract class ChatBaseActivity : AppCompatActivity(), LoaderState, ErrorState {
ft.remove(prev).commitAllowingStateLoss()
}
loader = null
loader = NaviLoader.getInstance(message)
loader = NaviLoader.getInstance(
title = message,
styleId = R.style.ChatDialogFragmentStyle
)
loader?.isCancelable = false
loader?.apply {
ft.add(this, TAG)

View File

@@ -15,6 +15,7 @@ import com.navi.chat.db.utils.convertMapToJson
import com.navi.chat.db.utils.transformFirestoreToDbModel
import com.navi.chat.provider.MessageOperation
import com.navi.naviwidgets.models.NaviChatWidget
import com.navi.naviwidgets.models.response.NaviChatControllerWidget
import com.navi.naviwidgets.models.response.NaviChatCsatRatingWidget
import com.navi.naviwidgets.models.response.NaviChatCsatUserResponse
import com.navi.naviwidgets.utils.NAVI_CHAT_RT_CREATED_AT
@@ -85,16 +86,20 @@ class ChatFireStoreDatabase {
for (dc in value!!.documentChanges) {
when (dc.type) {
DocumentChange.Type.ADDED -> {
if (dc.document.data[NAVI_CHAT_WIDGET_NAME] != NaviChatCsatRatingWidget.WIDGET_NAME) {
if (dc.document.data[NAVI_CHAT_WIDGET_NAME] == NaviChatCsatRatingWidget.WIDGET_NAME) {
messageOperation.showFeedbackFragment(
convertMapToJson<NaviChatCsatRatingWidget>(dc.document.data) as NaviChatCsatRatingWidget
)
} else if (dc.document.data[NAVI_CHAT_WIDGET_NAME] == NaviChatControllerWidget.WIDGET_NAME) {
messageOperation.processControllerWidget(
convertMapToJson<NaviChatControllerWidget>(dc.document.data) as NaviChatControllerWidget
)
} else {
messageOperation.addNewMessage(
transformFirestoreToDbModel(
dc.document.data
)
)
} else {
messageOperation.showFeedbackFragment(
convertMapToJson<NaviChatCsatRatingWidget>(dc.document.data) as NaviChatCsatRatingWidget
)
}
}
DocumentChange.Type.MODIFIED -> {}

View File

@@ -25,7 +25,7 @@ import com.navi.chat.utils.DATABASE_NAME
entities = [
NaviChatMessageDatabaseModel::class
],
version = 1,
version = 2,
exportSchema = false
)
@TypeConverters(

View File

@@ -6,12 +6,22 @@
*/
package com.navi.chat.db.migration
import android.database.sqlite.SQLiteException
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import timber.log.Timber
object ChatDatabaseMigration {
val MIGRATION_FROM_VERSION_1_TO_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {}
override fun migrate(database: SupportSQLiteDatabase) {
try {
database.execSQL("ALTER TABLE `navi_chat_message` ADD `senderId` TEXT")
database.execSQL("ALTER TABLE `navi_chat_message` ADD `senderType` TEXT")
Timber.i("Successful to migrate from database version 1 to version 2")
} catch (e: SQLiteException) {
Timber.e(e, "SQLiteException in migrate from database version 1 to version 2")
}
}
}
}

View File

@@ -42,5 +42,9 @@ data class NaviChatMessageDatabaseModel(
@SerializedName("naviChatMessageItemWidgetList")
val naviChatMessageItemWidgetList: List<NaviChatMessageItemWidget>? = null,
@SerializedName("isOptionSelected")
val isOptionSelected: Boolean = false
val isOptionSelected: Boolean = false,
@SerializedName("senderId")
val senderId: String? = null,
@SerializedName("senderType")
val senderType: String? = null
) : Serializable

View File

@@ -9,6 +9,7 @@ package com.navi.chat.db.utils
import com.google.firebase.Timestamp
import com.google.gson.Gson
import com.navi.chat.db.models.NaviChatMessageDatabaseModel
import com.navi.chat.utils.USER_SENDER_TYPE
import com.navi.naviwidgets.models.GenericWidgetDataInfo
import com.navi.naviwidgets.models.NaviBaseAdapterModel
import com.navi.naviwidgets.models.NaviChatWidget
@@ -27,7 +28,9 @@ fun transformDbToServerModel(naviChatMessageDatabaseModel: NaviChatMessageDataba
senderName = naviChatMessageDatabaseModel.senderName
),
shouldDisplayInChatHistory = naviChatMessageDatabaseModel.shouldDisplayInChatHistory,
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0))
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0)),
senderType = naviChatMessageDatabaseModel.senderType,
senderId = naviChatMessageDatabaseModel.senderId
)
}
NaviChatMessageWidget.WIDGET_NAME -> {
@@ -40,7 +43,9 @@ fun transformDbToServerModel(naviChatMessageDatabaseModel: NaviChatMessageDataba
metaData = naviChatMessageDatabaseModel.metaData
),
shouldDisplayInChatHistory = naviChatMessageDatabaseModel.shouldDisplayInChatHistory,
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0))
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0)),
senderType = naviChatMessageDatabaseModel.senderType,
senderId = naviChatMessageDatabaseModel.senderId
)
}
NaviChatMessageWithActionItemListWidget.WIDGET_NAME -> {
@@ -56,7 +61,9 @@ fun transformDbToServerModel(naviChatMessageDatabaseModel: NaviChatMessageDataba
),
shouldDisplayInChatHistory = naviChatMessageDatabaseModel.shouldDisplayInChatHistory,
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0)),
isOptionSelected = naviChatMessageDatabaseModel.isOptionSelected
isOptionSelected = naviChatMessageDatabaseModel.isOptionSelected,
senderType = naviChatMessageDatabaseModel.senderType,
senderId = naviChatMessageDatabaseModel.senderId
)
}
NaviChatMessageWithItemListWidget.WIDGET_NAME -> {
@@ -72,7 +79,9 @@ fun transformDbToServerModel(naviChatMessageDatabaseModel: NaviChatMessageDataba
metaData = naviChatMessageDatabaseModel.metaData
),
shouldDisplayInChatHistory = naviChatMessageDatabaseModel.shouldDisplayInChatHistory,
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0))
rt_created_at = Timestamp(Date(naviChatMessageDatabaseModel.timeStamp ?: 0)),
senderType = naviChatMessageDatabaseModel.senderType,
senderId = naviChatMessageDatabaseModel.senderId
)
}
else -> {
@@ -97,7 +106,9 @@ fun transformServerToDbModel(naviChatWidget: NaviChatWidget): NaviChatMessageDat
metaData = naviChatWidget.metaData(),
senderName = naviChatWidget.senderName(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
is NaviChatMessageWidget -> {
@@ -108,7 +119,9 @@ fun transformServerToDbModel(naviChatWidget: NaviChatWidget): NaviChatMessageDat
senderName = naviChatWidget.senderName(),
metaData = naviChatWidget.metaData(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
is NaviChatMessageWithActionItemListWidget -> {
@@ -120,7 +133,9 @@ fun transformServerToDbModel(naviChatWidget: NaviChatWidget): NaviChatMessageDat
naviChatActionMessageItemWidgetList = naviChatWidget.messageItems(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
isOptionSelected = naviChatWidget.isOptionSelected
isOptionSelected = naviChatWidget.isOptionSelected,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
is NaviChatMessageWithItemListWidget -> {
@@ -132,7 +147,9 @@ fun transformServerToDbModel(naviChatWidget: NaviChatWidget): NaviChatMessageDat
title = naviChatWidget.title(),
naviChatMessageItemWidgetList = naviChatWidget.messageItems(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
else -> {
@@ -167,7 +184,9 @@ fun transformFirestoreToDbModel(data: Map<String, Any>): NaviChatMessageDatabase
message = naviChatWidget.message(),
metaData = naviChatWidget.metaData(),
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
senderName = naviChatWidget.senderName()
senderName = naviChatWidget.senderName(),
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
NaviChatConversationStatusWidget.WIDGET_NAME -> {
@@ -180,7 +199,9 @@ fun transformFirestoreToDbModel(data: Map<String, Any>): NaviChatMessageDatabase
metaData = naviChatWidget.metaData(),
senderName = naviChatWidget.senderName(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
NaviChatMessageWithActionItemListWidget.WIDGET_NAME -> {
@@ -194,7 +215,9 @@ fun transformFirestoreToDbModel(data: Map<String, Any>): NaviChatMessageDatabase
naviChatActionMessageItemWidgetList = naviChatWidget.messageItems(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
isOptionSelected = naviChatWidget.isOptionSelected
isOptionSelected = naviChatWidget.isOptionSelected,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
NaviChatMessageWithItemListWidget.WIDGET_NAME -> {
@@ -208,7 +231,9 @@ fun transformFirestoreToDbModel(data: Map<String, Any>): NaviChatMessageDatabase
title = naviChatWidget.title(),
naviChatMessageItemWidgetList = naviChatWidget.messageItems(),
shouldDisplayInChatHistory = naviChatWidget.shouldDisplayInChatHistory,
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time
timeStamp = naviChatWidget.rt_created_at?.toDate()?.time,
senderType = naviChatWidget.senderType,
senderId = naviChatWidget.senderId
)
}
else -> {
@@ -226,8 +251,11 @@ fun formPlainTextNewMessage(
metaData: NaviChatMetaData,
message: String,
senderName: String,
senderId: String
) =
NaviChatMessageWidget(
senderId = senderId,
senderType = USER_SENDER_TYPE,
widgetData = NaviChatWidgetData(
message = message,
metaData = metaData,
@@ -240,7 +268,8 @@ fun getDisplayableMessages(listOfChatMessages: List<NaviChatWidget>): List<NaviC
for (chatWidget in listOfChatMessages) {
if (chatWidget.shouldDisplayInChatHistory &&
chatWidget.widgetNameForBaseAdapter != NaviChatCsatRatingWidget.WIDGET_NAME &&
chatWidget.widgetNameForBaseAdapter != NaviChatCsatUserResponse.WIDGET_NAME
chatWidget.widgetNameForBaseAdapter != NaviChatCsatUserResponse.WIDGET_NAME &&
chatWidget.widgetNameForBaseAdapter != NaviChatControllerWidget.WIDGET_NAME
) {
listOfDisplayableMessages.add(chatWidget)
}

View File

@@ -15,4 +15,5 @@ data class NaviChatSystemLocalData(
val source: String,
val sourceId: String,
val currentUserName: String,
val externalCustomerId: String
) : Serializable, Parcelable

View File

@@ -14,5 +14,7 @@ data class NaviChatInitiateResponse(
@SerializedName("read_path")
val readPath: String? = null,
@SerializedName("write_path")
val writePath: String? = null
val writePath: String? = null,
@SerializedName("show_textbox")
val showFreeText: Boolean? = null
)

View File

@@ -7,9 +7,11 @@
package com.navi.chat.provider
import com.navi.chat.db.models.NaviChatMessageDatabaseModel
import com.navi.naviwidgets.models.response.NaviChatControllerWidget
import com.navi.naviwidgets.models.response.NaviChatCsatRatingWidget
interface MessageOperation {
fun addNewMessage(model: NaviChatMessageDatabaseModel)
fun showFeedbackFragment(naviChatCsatRatingWidget: NaviChatCsatRatingWidget)
fun processControllerWidget(naviChatControllerWidget: NaviChatControllerWidget)
}

View File

@@ -11,6 +11,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
@@ -36,10 +37,7 @@ import com.navi.chat.paging.diffutil.getChatDiffUtil
import com.navi.chat.provider.ChatDataProvider
import com.navi.chat.provider.MessageOperation
import com.navi.chat.provider.firestore.FireStoreDataProvider
import com.navi.chat.utils.FIRESTORE
import com.navi.chat.utils.GENERIC_CHAT_API_ERROR
import com.navi.chat.utils.NAVI_CHAT_SYSTEM_LOCAL_DATA
import com.navi.chat.utils.ToolbarInteraction
import com.navi.chat.utils.*
import com.navi.chat.viewmodels.NaviChatSharedViewModel
import com.navi.chat.viewmodels.NaviChatViewModel
import com.navi.common.constants.EMPTY
@@ -49,8 +47,10 @@ import com.navi.naviwidgets.actions.ChatActionItemClickAction
import com.navi.naviwidgets.adapters.BasePagingRVAdapter
import com.navi.naviwidgets.callbacks.WidgetCallback
import com.navi.naviwidgets.models.NaviBaseAdapterModel
import com.navi.naviwidgets.models.response.NaviChatControllerWidget
import com.navi.naviwidgets.models.response.NaviChatCsatRatingWidget
import com.navi.naviwidgets.models.response.NaviChatLoaderWidget
import com.navi.naviwidgets.models.response.NaviChatMetaData
import com.navi.naviwidgets.utils.NAVI_CHAT_MESSAGE_WITH_ACTION_ITEM_SELECTED
import com.navi.naviwidgets.viewholder.NaviChatViewHolderFactoryImpl
import dagger.hilt.android.EntryPointAccessors
@@ -124,7 +124,6 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
fetchHistoryMessages()
}
override fun onResume() {
super.onResume()
if (isAppInBackground) {
@@ -162,7 +161,8 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
chatPagingRVAdapter = BasePagingRVAdapter(
widgetCallback = this@NaviChatFragment,
holderFactory = NaviChatViewHolderFactoryImpl(
naviChatSystemLocalData?.currentUserName ?: EMPTY
senderId = naviChatSystemLocalData?.externalCustomerId ?: EMPTY,
senderType = USER_SENDER_TYPE
),
diffUtil = getChatDiffUtil(),
loadingWidget = NaviChatLoaderWidget()
@@ -208,6 +208,27 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
}
})
}
ivSendFreeText.setOnClickListener {
val freeText = binding.etFreeText.text.toString()
if (freeText != EMPTY) {
writeUserMessageToFirestore(
message = freeText,
metaData = NaviChatMetaData()
)
binding.etFreeText.text = null
}
}
etFreeText.setOnClickListener {
scrollChatToLatestMessageReceived()
}
etFreeText.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
scrollChatToLatestMessageReceived()
}
}
}
}
@@ -239,7 +260,13 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
}
naviChatViewModel.naviChatInitiateResponse.observeNonNull(viewLifecycleOwner) { naviChatInitiateResponse ->
hideLoader()
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
delay(RECYCLER_VIEW_BOOT_DELAY)
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
hideLoader()
}
}
initChat(
FireStoreDataProviderModel(
chatProviderName = NaviChatSystemDataHelper.providerName().orEmpty(),
@@ -248,6 +275,7 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
)
)
binding.rvChat.visibility = VISIBLE
binding.clFreeText.isVisible = (naviChatInitiateResponse.showFreeText == true)
}
naviChatSharedViewModel.ratingMetaData.observeNonNull(viewLifecycleOwner) { metadata ->
@@ -294,17 +322,32 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
}
}
private fun writeUserMessageToFirestore(
message: String,
metaData: NaviChatMetaData
) {
if (::chatDataProvider.isInitialized) {
chatDataProvider.writeMessage(
formPlainTextNewMessage(
metaData = metaData,
message = message,
senderName = naviChatSystemLocalData?.currentUserName ?: EMPTY,
senderId = naviChatSystemLocalData?.externalCustomerId ?: EMPTY
)
)
}
}
@ExperimentalPagingApi
private fun scrollChatToLatestMessageReceived() {
if (naviChatViewModel.getIsScrollReachedEnd().not() ||
naviChatViewModel.getFirstCompletelyVisibleMessagePosition() == 0
) {
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
linearLayoutManager.smoothScrollToPosition(
binding.rvChat,
null,
0
)
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
delay(200)
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
binding.rvChat.smoothScrollToPosition(0)
}
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
delay(DELAY_TO_SCROLL)
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
@@ -324,15 +367,10 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
override fun onClick(naviClickAction: NaviClickAction) {
when (naviClickAction) {
is ChatActionItemClickAction -> {
if (::chatDataProvider.isInitialized) {
chatDataProvider.writeMessage(
formPlainTextNewMessage(
metaData = naviClickAction.metaData,
message = naviClickAction.message,
senderName = naviChatSystemLocalData?.currentUserName ?: EMPTY
)
)
}
writeUserMessageToFirestore(
message = naviClickAction.message,
metaData = naviClickAction.metaData
)
}
else -> {
Timber.e("Action $naviClickAction is not handled")
@@ -379,10 +417,15 @@ class NaviChatFragment : ChatBaseFragment(), WidgetCallback, MessageOperation, T
}
}
override fun processControllerWidget(naviChatControllerWidget: NaviChatControllerWidget) {
binding.clFreeText.isVisible = true
}
override val screenName: String = TAG
companion object {
const val TAG = "NaviChatFragment"
private const val DELAY_TO_SCROLL = 100L
private const val DELAY_TO_SCROLL = 1000L
private const val RECYCLER_VIEW_BOOT_DELAY = 3000L
}
}

View File

@@ -11,4 +11,5 @@ const val DATABASE_NAME = "navi-chat.db"
const val GENERIC_CHAT_API_ERROR = "GENERIC_CHAT_API_ERROR"
const val NAVI_CHAT_SYSTEM_LOCAL_DATA = "NAVI_CHAT_SYSTEM_LOCAL_DATA"
const val DEFAULT_SOURCE_ID_FOR_PL = "DEFAULT_PL"
const val USER_SENDER_TYPE = "APP_USER"

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M0,7.272L5.438,12.711L16,4L7.289,14.562L12.728,20L20,0L0,7.272Z"
android:fillColor="#FF3333"/>
</vector>

View File

@@ -24,11 +24,65 @@
android:id="@+id/rvChat"
android:layout_width="match_parent"
android:layout_height="@dimen/layout_dp_0"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@id/viewSeparator"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/nctLayout" />
<View
android:id="@+id/viewSeparator"
android:layout_width="match_parent"
android:layout_height="@dimen/layout_dp_1"
android:background="@color/divider_color_light_grey"
app:layout_constraintBottom_toTopOf="@id/clFreeText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rvChat" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clFreeText"
android:layout_width="match_parent"
android:layout_height="@dimen/layout_dp_56"
android:background="@color/white"
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/viewSeparator">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/etFreeText"
android:layout_width="@dimen/layout_dp_0"
android:layout_height="@dimen/layout_dp_56"
android:background="@null"
android:cursorVisible="false"
android:gravity="center_vertical"
android:hint="@string/type_here"
android:imeOptions="actionDone"
android:letterSpacing="0.02"
android:paddingStart="@dimen/layout_dp_16"
android:paddingEnd="@dimen/layout_dp_16"
android:textColor="@color/title_color_two"
android:textSize="@dimen/font_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/ivSendFreeText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ivSendFreeText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/layout_dp_16"
android:paddingEnd="@dimen/layout_dp_16"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/etFreeText"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_send_message" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -2,15 +2,16 @@ package com.navi.common.dialog
import android.os.Bundle
import android.view.View
import androidx.annotation.StyleRes
import com.navi.analytics.utils.FULL_SCREEN_LOADER
import com.navi.common.R
import com.navi.common.base.dialog.BaseDialogFragment
import com.navi.common.databinding.NaviLoaderBinding
class NaviLoader :
class NaviLoader(@StyleRes style: Int = R.style.DialogFragmentStyle) :
BaseDialogFragment<NaviLoaderBinding>(
R.layout.navi_loader,
R.style.DialogFragmentStyle
style
) {
override val screenName
@@ -30,8 +31,11 @@ class NaviLoader :
companion object {
private const val MESSAGE = "MESSAGE"
fun getInstance(title: String?): NaviLoader {
return NaviLoader().apply {
fun getInstance(
title: String?,
@StyleRes styleId: Int = R.style.DialogFragmentStyle
): NaviLoader {
return NaviLoader(style = styleId).apply {
arguments = Bundle().apply {
putString(MESSAGE, title)
}

View File

@@ -185,6 +185,13 @@
<item name="android:windowTranslucentStatus">true</item>
</style>
<style name="ChatDialogFragmentStyle" parent="AppTheme.NoActionBar.FullScreen">
<item name="android:windowFullscreen">true</item>
<item name="android:windowAnimationStyle">@style/fadeInFadeOutAnimation</item>
<item name="android:windowBackground">@android:color/white</item>
<item name="android:windowTranslucentStatus">false</item>
</style>
<style name="BlueColorButtonFontStyle">
<item name="android:fontFamily">@font/navi_bold</item>
<item name="android:textColor">@color/white</item>

View File

@@ -0,0 +1,14 @@
/*
*
* *
* * * Copyright © 2022 by Navi Technologies Private Limited
* * * All rights reserved. Strictly confidential
* *
*
*/
package com.navi.naviwidgets.models
enum class NaviChatControllerEnum {
ENABLE_FREE_TEXT
}

View File

@@ -7,12 +7,12 @@
package com.navi.naviwidgets.models
import com.google.firebase.Timestamp
import android.os.Parcelable
import com.google.firebase.Timestamp
import com.google.gson.annotations.SerializedName
import com.navi.naviwidgets.models.response.WidgetError
import java.io.Serializable
import kotlinx.android.parcel.Parcelize
import java.io.Serializable
interface NaviBaseAdapterModel: Serializable {
var widgetNameForBaseAdapter: String?
@@ -32,6 +32,8 @@ interface NaviChatWidget : NaviBaseAdapterModel, Serializable {
val messageId: String?
val shouldDisplayInChatHistory: Boolean
var rt_created_at: Timestamp?
val senderId: String?
val senderType: String?
}
open class GenericWidgetDataInfo(

View File

@@ -35,7 +35,13 @@ data class NaviChatActionMessageItemWidget(
@SerializedName(NAVI_CHAT_SHOULD_DISPLAY_IN_CHAT_HISTORY)
override val shouldDisplayInChatHistory: Boolean = true,
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, NaviChatActionMessageItemWidgetInfo, Serializable {
companion object {

View File

@@ -0,0 +1,54 @@
/*
*
* *
* * * Copyright © 2022 by Navi Technologies Private Limited
* * * All rights reserved. Strictly confidential
* *
*
*/
package com.navi.naviwidgets.models.response
import com.google.firebase.Timestamp
import com.google.firebase.firestore.PropertyName
import com.google.firebase.firestore.ServerTimestamp
import com.google.gson.annotations.SerializedName
import com.navi.naviwidgets.models.NaviChatWidget
import com.navi.naviwidgets.utils.*
import java.io.Serializable
data class NaviChatControllerWidget(
@get:PropertyName(NAVI_CHAT_MESSAGE_ID)
@SerializedName(NAVI_CHAT_MESSAGE_ID)
override val messageId: String? = null,
@set:PropertyName(NAVI_CHAT_WIDGET_NAME)
@get:PropertyName(NAVI_CHAT_WIDGET_NAME)
@SerializedName(NAVI_CHAT_WIDGET_NAME)
override var widgetNameForBaseAdapter: String? = WIDGET_NAME,
@get:PropertyName(NAVI_CHAT_WIDGET_DATA)
@SerializedName(NAVI_CHAT_WIDGET_DATA)
val widgetData: NaviChatControllerWidgetData? = null,
@get:PropertyName(NAVI_CHAT_SHOULD_DISPLAY_IN_CHAT_HISTORY)
@SerializedName(NAVI_CHAT_SHOULD_DISPLAY_IN_CHAT_HISTORY)
override val shouldDisplayInChatHistory: Boolean = true,
@ServerTimestamp
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, Serializable {
companion object {
const val WIDGET_NAME = "CHAT_CONTROLLER_WIDGET"
}
}
data class NaviChatControllerWidgetData(
@SerializedName(NAVI_CHAT_MESSAGE)
@get:PropertyName(NAVI_CHAT_MESSAGE)
val message: String? = null,
) : Serializable

View File

@@ -31,7 +31,13 @@ data class NaviChatConversationStatusWidget(
override val shouldDisplayInChatHistory: Boolean = true,
@ServerTimestamp
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, NaviChatConversationStatusWidgetInfo, Serializable {
companion object {

View File

@@ -33,6 +33,12 @@ data class NaviChatCsatRatingWidget(
override val shouldDisplayInChatHistory: Boolean = true,
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, Serializable, Parcelable, NaviChatCsatRatingWidgetInfo {
companion object {

View File

@@ -31,6 +31,12 @@ data class NaviChatCsatUserResponse(
@ServerTimestamp
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, Serializable {
companion object {

View File

@@ -7,12 +7,10 @@
package com.navi.naviwidgets.models.response
import com.google.firebase.Timestamp
import com.google.firebase.firestore.PropertyName
import com.google.gson.annotations.SerializedName
import com.navi.naviwidgets.models.NaviChatWidget
import com.navi.naviwidgets.utils.NAVI_CHAT_MESSAGE_ID
import com.navi.naviwidgets.utils.NAVI_CHAT_RT_CREATED_AT
import com.navi.naviwidgets.utils.NAVI_CHAT_SHOULD_DISPLAY_IN_CHAT_HISTORY
import com.navi.naviwidgets.utils.NAVI_CHAT_WIDGET_NAME
import com.navi.naviwidgets.utils.*
import java.io.Serializable
data class NaviChatLoaderWidget(
@@ -23,7 +21,13 @@ data class NaviChatLoaderWidget(
@SerializedName(NAVI_CHAT_SHOULD_DISPLAY_IN_CHAT_HISTORY)
override val shouldDisplayInChatHistory: Boolean = true,
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, Serializable {
companion object {
const val WIDGET_NAME = "CHAT_LOADER"

View File

@@ -33,6 +33,12 @@ data class NaviChatMessageItemWidget(
override val shouldDisplayInChatHistory: Boolean = true,
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, NaviChatMessageItemInfo, Serializable {
companion object {

View File

@@ -32,6 +32,12 @@ data class NaviChatMessageWidget(
@ServerTimestamp
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, NaviChatWidgetInfo, Serializable {
companion object {

View File

@@ -36,6 +36,12 @@ data class NaviChatMessageWithActionItemListWidget(
@set:PropertyName(NAVI_CHAT_IS_OPTION_SELECTED)
@SerializedName(NAVI_CHAT_IS_OPTION_SELECTED)
var isOptionSelected: Boolean = false,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, NaviChatMessageWithActionItemListWidgetInfo, Serializable {
companion object {

View File

@@ -32,6 +32,12 @@ data class NaviChatMessageWithItemListWidget(
@ServerTimestamp
@SerializedName(NAVI_CHAT_RT_CREATED_AT)
override var rt_created_at: Timestamp? = null,
@get:PropertyName(NAVI_CHAT_SENDER_ID)
@SerializedName(NAVI_CHAT_SENDER_ID)
override val senderId: String? = null,
@get:PropertyName(NAVI_CHAT_SENDER_TYPE)
@SerializedName(NAVI_CHAT_SENDER_TYPE)
override val senderType: String? = null
) : NaviChatWidget, NaviChatMessageWithItemListWidgetInfo, Serializable {
companion object {

View File

@@ -50,4 +50,6 @@ const val NAVI_CHAT_RESPONSE_VALUE = "response_value"
const val NAVI_CHAT_MESSAGE_DATA = "message_data"
const val NAVI_CHAT_TITLE = "title"
const val NAVI_CHAT_ITEMS = "items"
const val NAVI_CHAT_IS_OPTION_SELECTED = "is_option_selected"
const val NAVI_CHAT_IS_OPTION_SELECTED = "is_option_selected"
const val NAVI_CHAT_SENDER_ID = "sender_id"
const val NAVI_CHAT_SENDER_TYPE = "sender_type"

View File

@@ -13,8 +13,10 @@ import com.navi.naviwidgets.models.NaviBaseAdapterModel
import com.navi.naviwidgets.models.response.*
@Suppress("UNCHECKED_CAST")
class NaviChatViewHolderFactoryImpl<T : NaviBaseAdapterModel>(private val currentUserName: String) :
ViewHolderTypeFactory<T> {
class NaviChatViewHolderFactoryImpl<T : NaviBaseAdapterModel>(
private val senderId: String,
private val senderType: String
) : ViewHolderTypeFactory<T> {
companion object {
private val NAVI_CHAT_RECEIVED_MESSAGE_WIDGET = R.layout.layout_navi_chat_received_message
private val NAVI_CHAT_SENT_MESSAGE_WIDGET = R.layout.layout_navi_chat_sent_message
@@ -31,7 +33,7 @@ class NaviChatViewHolderFactoryImpl<T : NaviBaseAdapterModel>(private val curren
}
override fun type(item: NaviBaseAdapterModel): Int = when (item) {
is NaviChatMessageWidget -> if (currentUserName == item.senderName()) {
is NaviChatMessageWidget -> if (senderId == item.senderId && senderType == item.senderType) {
NAVI_CHAT_SENT_MESSAGE_WIDGET
} else {
NAVI_CHAT_RECEIVED_MESSAGE_WIDGET

View File

@@ -95,7 +95,7 @@ class NaviChatMessageWithActionItemListWidgetLayout @JvmOverloads constructor(
}
},
factory = NaviChatViewHolderFactoryImpl(EMPTY)
factory = NaviChatViewHolderFactoryImpl(EMPTY, EMPTY)
)
fun update(

View File

@@ -75,7 +75,7 @@ class NaviChatMessageWithItemListWidgetLayout @JvmOverloads constructor(
}
},
factory = NaviChatViewHolderFactoryImpl(EMPTY)
factory = NaviChatViewHolderFactoryImpl(EMPTY, EMPTY)
)
fun update(