Skip to content

Commit

Permalink
Code cleanup for app and SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
mrajatttt committed Oct 18, 2024
1 parent 33c5c86 commit d1cf16e
Show file tree
Hide file tree
Showing 46 changed files with 204 additions and 325 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ package com.amazon.connect.chat.androidchatexample
import com.amazonaws.regions.Regions

object Config {
data class ChatConfig(
val connectInstanceId: String,
val contactFlowId: String,
val startChatEndpoint: String,
val region: Regions,
val agentName: String,
val customerName: String
)

// List of available configurations
val configurations = emptyList<ChatConfig>()
val connectInstanceId: String = ""
val contactFlowId: String = ""
val startChatEndpoint: String = "https://<endpoint>.execute-api.<region>.amazonaws.com/Prod/"
val region: Regions = Regions.US_WEST_2
val agentName = "AGENT"
val customerName = "CUSTOMER"
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ import com.amazon.connect.chat.androidchatexample.utils.FileUtils.previewFileFro
import com.amazon.connect.chat.androidchatexample.viewmodel.ChatViewModel
import com.amazon.connect.chat.androidchatexample.views.AttachmentTextView
import com.amazon.connect.chat.androidchatexample.views.ChatMessageView
import com.amazon.connect.chat.androidchatexample.views.ConfigPicker
import com.amazon.connect.chat.sdk.model.ContentType
import com.amazon.connect.chat.sdk.model.Message
import com.amazon.connect.chat.sdk.model.MessageDirection
Expand Down Expand Up @@ -241,7 +240,6 @@ fun ChatScreen(activity: Activity, viewModel: ChatViewModel = hiltViewModel()) {
Column {
ParticipantTokenSection(activity, viewModel)
Spacer(modifier = Modifier.height(16.dp))
ConfigPicker(viewModel) // Include the configuration picker here
}
// ParticipantTokenSection(activity, viewModel)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.amazon.connect.chat.androidchatexample.di

import android.content.Context
import android.content.SharedPreferences
import com.amazon.connect.chat.sdk.network.WebSocketManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -20,18 +19,4 @@ object AppModule {
return context.getSharedPreferences("ConnectChat", Context.MODE_PRIVATE)
}

// // Provide the Context dependency
// @Provides
// @Singleton
// fun provideContext(@ApplicationContext appContext: Context): Context {
// return appContext
// }
//
// @Provides
// @Singleton
// fun provideWebSocketManager(
// context: Context,
// ): WebSocketManager {
// return WebSocketManager(context, {})
// }
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.amazon.connect.chat.androidchatexample.viewmodel

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
Expand All @@ -15,12 +14,10 @@ import com.amazon.connect.chat.androidchatexample.Config
import com.amazon.connect.chat.androidchatexample.models.ParticipantDetails
import com.amazon.connect.chat.androidchatexample.models.StartChatRequest
import com.amazon.connect.chat.androidchatexample.models.StartChatResponse
import com.amazon.connect.chat.androidchatexample.network.ChatConfigProvider
import com.amazon.connect.chat.androidchatexample.network.Resource
import com.amazon.connect.chat.androidchatexample.repository.ChatRepository
import com.amazon.connect.chat.androidchatexample.utils.CommonUtils
import com.amazon.connect.chat.sdk.ChatSession
import com.amazon.connect.chat.sdk.ChatSessionProvider
import com.amazon.connect.chat.sdk.model.ChatDetails
import com.amazon.connect.chat.sdk.model.ContentType
import com.amazon.connect.chat.sdk.model.Event
Expand All @@ -31,85 +28,82 @@ import com.amazon.connect.chat.sdk.model.TranscriptItem
import com.amazonaws.services.connectparticipant.model.ScanDirection
import com.amazonaws.services.connectparticipant.model.SortKey
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.launch
import java.net.URL
import javax.inject.Inject

@HiltViewModel
class ChatViewModel @Inject constructor(
private val chatSession: ChatSession, // Injected ChatSession
private val chatRepository: ChatRepository,
private val sharedPreferences: SharedPreferences,
private val chatConfigProvider: ChatConfigProvider
private val chatSession: ChatSession, // Injected ChatSession instance
private val chatRepository: ChatRepository, // Chat repository for API calls
private val sharedPreferences: SharedPreferences // Shared preferences for storing participant token
) : ViewModel() {

// If you are not using Hilt, you can initialize ChatSession like this
// private val chatSession = ChatSessionProvider.getChatSession(context)
// private val chatSession = ChatSessionProvider.getChatSession(context)

// Configuration instance for chat settings
private val chatConfiguration = Config

// LiveData for tracking loading state
private val _isLoading = MutableLiveData(false)
val isLoading: MutableLiveData<Boolean> = _isLoading

// LiveData for tracking chat session activity state
private val _isChatActive = MutableLiveData(false)
val isChatActive: MutableLiveData<Boolean> = _isChatActive

// LiveData to hold the URI of the selected file for attachment
private val _selectedFileUri = MutableLiveData(Uri.EMPTY)
val selectedFileUri: MutableLiveData<Uri> = _selectedFileUri

// State to store chat transcript items (messages and events)
var messages = mutableStateListOf<TranscriptItem>()
private set

// LiveData for handling error messages
private val _errorMessage = MutableLiveData<String?>()
val errorMessage: LiveData<String?> = _errorMessage

// LiveData to hold participant token from shared preferences
private val _liveParticipantToken = MutableLiveData<String?>(sharedPreferences.getString("participantToken", null))
val liveParticipantToken: LiveData<String?> = _liveParticipantToken

// LiveData to track the selected configuration
private val _selectedConfigIndex = MutableLiveData(0)
val selectedConfigIndex: LiveData<Int> = _selectedConfigIndex

// Update configurations based on the selected index
val chatConfiguration: Config.ChatConfig
get() = Config.configurations[_selectedConfigIndex.value ?: 0]

fun setSelectedConfig(index: Int) {
_selectedConfigIndex.value = index
clearParticipantToken()
chatConfigProvider.updateConfig(index) // Update the current configuration
}


// Property to get or set participant token in shared preferences
private var participantToken: String?
get() = liveParticipantToken.value
set(value) {
sharedPreferences.edit().putString("participantToken", value).apply()
_liveParticipantToken.value = value // Reflect the new value in LiveData
_liveParticipantToken.value = value // Update LiveData with new token
}

// Clear participant token from shared preferences
fun clearParticipantToken() {
sharedPreferences.edit().remove("participantToken").apply()
_liveParticipantToken.value = null
}

// Initialize ViewModel (add additional initialization logic if needed)
init {

// Initialization logic can be added here if necessary
}

// Configure the chat session with global settings
private suspend fun configureChatSession() {
val globalConfig = GlobalConfig(region = chatConfiguration.region)
chatSession.configure(globalConfig)
setupChatHandlers(chatSession)
}

// Setup event handlers for the chat session
private suspend fun setupChatHandlers(chatSession: ChatSession) {
chatSession.onConnectionEstablished = {
Log.d("ChatViewModel", "Connection established.")
_isChatActive.value = true
}

chatSession.onMessageReceived = { transcriptItem ->
// Handle received websocket message
// Handle received websocket message if needed
}

chatSession.onTranscriptUpdated = { transcriptList ->
Expand Down Expand Up @@ -143,24 +137,25 @@ class ChatViewModel @Inject constructor(
}
}

// Initiate chat either by starting a new session or reconnecting using an existing token
fun initiateChat() {
viewModelScope.launch {

configureChatSession()
configureChatSession() // Configure chat session first

_isLoading.value = true
messages = mutableStateListOf() // Clear existing messages
if (participantToken != null) {
participantToken?.let {
val chatDetails = ChatDetails(participantToken = it)
createParticipantConnection(chatDetails)
}
} else {
startChat() // Start a fresh chat if no tokens are present

// Check if participant token exists for reconnecting
participantToken?.let {
val chatDetails = ChatDetails(participantToken = it)
createParticipantConnection(chatDetails)
} ?: run {
startChat() // Start a fresh chat if no token is found
}
}
}

// Start a new chat session by sending a StartChatRequest to the repository
private fun startChat() {
viewModelScope.launch {
_isLoading.value = true
Expand Down Expand Up @@ -189,7 +184,7 @@ class ChatViewModel @Inject constructor(
}
}


// Handle the response after starting a chat session
private fun handleStartChatResponse(result: StartChatResponse.Data.StartChatResult) {
viewModelScope.launch {
val chatDetails = ChatDetails(
Expand All @@ -201,13 +196,14 @@ class ChatViewModel @Inject constructor(
}
}

// Create a connection to the participant chat session
private fun createParticipantConnection(chatDetails: ChatDetails) {
viewModelScope.launch {
_isLoading.value = true // Start loading
val result = chatSession.connect(chatDetails)
_isLoading.value = false // Stop loading
_isLoading.value = true // Set loading state
val result = chatSession.connect(chatDetails) // Attempt connection
_isLoading.value = false // Clear loading state

if (result.isSuccess) {
// Handle successful connection
Log.d("ChatViewModel", "Connection successful $result")
} else if (result.isFailure) {
Log.e("ChatViewModel", "Connection failed: ${result.exceptionOrNull()}")
Expand All @@ -216,21 +212,23 @@ class ChatViewModel @Inject constructor(
}
}

// Update the transcript when new messages or events are received
private fun onUpdateTranscript(transcriptList: List<TranscriptItem>) {
messages.clear()
viewModelScope.launch {
val tempTranscriptList = transcriptList.toList()
val updatedMessages = tempTranscriptList.map { transcriptItem ->
val updatedMessages = transcriptList.map { transcriptItem ->
// Customize events if needed
if (transcriptItem is Event) {
CommonUtils.customizeEvent(transcriptItem)
}
CommonUtils.getMessageDirection(transcriptItem)
CommonUtils.getMessageDirection(transcriptItem) // Customize message direction
transcriptItem
}
messages.addAll(updatedMessages)
}
}

// Send a text message through the chat session
fun sendMessage(text: String) {
viewModelScope.launch {
if (text.isNotEmpty()) {
Expand All @@ -245,6 +243,7 @@ class ChatViewModel @Inject constructor(
}
}

// Send an event through the chat session
fun sendEvent(content: String = "", contentType: ContentType) {
viewModelScope.launch {
val result = chatSession.sendEvent(contentType, content)
Expand All @@ -257,12 +256,13 @@ class ChatViewModel @Inject constructor(
}
}

// Send a read receipt for a message when it appears
suspend fun sendReadEventOnAppear(message: Message) {
chatSession.sendMessageReceipt(message, MessageReceiptType.MESSAGE_READ)
}


// Fetches transcripts
// Fetch the chat transcript
fun fetchTranscript(onCompletion: (Boolean) -> Unit) {
viewModelScope.launch {
chatSession.getTranscript(ScanDirection.BACKWARD, SortKey.DESCENDING, 30, null, messages?.get(0)?.id).onSuccess {
Expand All @@ -275,36 +275,39 @@ class ChatViewModel @Inject constructor(
}
}

fun endChat(){
// End the chat session and clear the participant token
fun endChat() {
clearParticipantToken()
viewModelScope.launch {
chatSession.disconnect()
chatSession.disconnect() // Disconnect from chat session
}
}

// Clear error messages
fun clearErrorMessage() {
_errorMessage.value = null
}

// Request code for selecting an attachment
private val PICK_ATTACHMENT = 2

// Open the file picker for selecting an attachment
fun openFile(activity: Activity) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
}

activity.startActivityForResult(intent, PICK_ATTACHMENT)
activity.startActivityForResult(intent, PICK_ATTACHMENT) // Start activity for result
}


// Upload a selected attachment to the chat session
fun uploadAttachment(fileUri: Uri) {
viewModelScope.launch {
chatSession.sendAttachment(fileUri)
}
}

// Download an attachment using its ID and file name
suspend fun downloadAttachment(attachmentId: String, fileName: String): Result<URL> {
return chatSession.downloadAttachment(attachmentId, fileName)
}
Expand Down
Loading

0 comments on commit d1cf16e

Please sign in to comment.