mirror of
https://github.com/shaulascr/ecommerce_serang.git
synced 2025-08-10 09:22:21 +00:00
fixed chat (hide attach + adjust attach product)
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
package com.alya.ecommerce_serang.data.api.response.chat
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import java.io.File
|
||||
|
||||
data class ChatHistoryResponse(
|
||||
|
||||
@ -15,7 +14,7 @@ data class ChatHistoryResponse(
|
||||
data class ChatItem(
|
||||
|
||||
@field:SerializedName("attachment")
|
||||
val attachment: File? = null,
|
||||
val attachment: String? = null,
|
||||
|
||||
@field:SerializedName("product_id")
|
||||
val productId: Int,
|
||||
|
@ -14,7 +14,7 @@ data class SendChatResponse(
|
||||
data class ChatLine(
|
||||
|
||||
@field:SerializedName("attachment")
|
||||
val attachment: String,
|
||||
val attachment: String? = null,
|
||||
|
||||
@field:SerializedName("product_id")
|
||||
val productId: Int,
|
||||
|
@ -14,7 +14,7 @@ data class UpdateChatResponse(
|
||||
data class Address(
|
||||
|
||||
@field:SerializedName("attachment")
|
||||
val attachment: Any,
|
||||
val attachment: String? = null,
|
||||
|
||||
@field:SerializedName("product_id")
|
||||
val productId: Int,
|
||||
|
@ -223,12 +223,13 @@ interface ApiService {
|
||||
@Part chatimg: MultipartBody.Part?
|
||||
): Response<SendChatResponse>
|
||||
|
||||
|
||||
@PUT("chatstatus")
|
||||
suspend fun updateChatStatus(
|
||||
@Body request: UpdateChatRequest
|
||||
): Response<UpdateChatResponse>
|
||||
|
||||
@GET("chatdetail/{chatRoomId}")
|
||||
@GET("chat/{chatRoomId}")
|
||||
suspend fun getChatDetail(
|
||||
@Path("chatRoomId") chatRoomId: Int
|
||||
): Response<ChatHistoryResponse>
|
||||
|
@ -0,0 +1,131 @@
|
||||
package com.alya.ecommerce_serang.data.repository
|
||||
|
||||
import android.util.Log
|
||||
import com.alya.ecommerce_serang.data.api.dto.UpdateChatRequest
|
||||
import com.alya.ecommerce_serang.data.api.dto.UserProfile
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.ChatHistoryResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.SendChatResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.UpdateChatResponse
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class ChatRepository @Inject constructor(
|
||||
private val apiService: ApiService
|
||||
) {
|
||||
private val TAG = "ChatRepository"
|
||||
|
||||
suspend fun fetchUserProfile(): Result<UserProfile?> {
|
||||
return try {
|
||||
val response = apiService.getUserProfile()
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.user?.let {
|
||||
Result.Success(it) // ✅ Returning only UserProfile
|
||||
} ?: Result.Error(Exception("User data not found"))
|
||||
} else {
|
||||
Result.Error(Exception("Error fetching profile: ${response.code()}"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun sendChatMessage(
|
||||
storeId: Int,
|
||||
message: String,
|
||||
productId: Int,
|
||||
imageFile: File? = null
|
||||
): Result<SendChatResponse> {
|
||||
return try {
|
||||
// Create request bodies for text fields
|
||||
val storeIdBody = RequestBody.create("text/plain".toMediaTypeOrNull(), storeId.toString())
|
||||
val messageBody = RequestBody.create("text/plain".toMediaTypeOrNull(), message)
|
||||
val productIdBody = RequestBody.create("text/plain".toMediaTypeOrNull(), productId.toString())
|
||||
|
||||
// Create multipart body for the image file
|
||||
val imageMultipart = if (imageFile != null && imageFile.exists()) {
|
||||
// Log detailed file information
|
||||
Log.d(TAG, "Image file: ${imageFile.absolutePath}")
|
||||
Log.d(TAG, "Image file size: ${imageFile.length()} bytes")
|
||||
Log.d(TAG, "Image file exists: ${imageFile.exists()}")
|
||||
Log.d(TAG, "Image file can read: ${imageFile.canRead()}")
|
||||
|
||||
val requestFile = RequestBody.create("image/*".toMediaTypeOrNull(), imageFile)
|
||||
MultipartBody.Part.createFormData("chatimg", imageFile.name, requestFile)
|
||||
} else {
|
||||
// Pass null when no image is provided
|
||||
null
|
||||
}
|
||||
|
||||
// Log request info
|
||||
Log.d(TAG, "Sending message to store ID: $storeId, product ID: $productId")
|
||||
Log.d(TAG, "Message content: $message")
|
||||
Log.d(TAG, "Has image: ${imageFile != null && imageFile.exists()}")
|
||||
|
||||
// Make the API call
|
||||
val response = apiService.sendChatLine(
|
||||
storeId = storeIdBody,
|
||||
message = messageBody,
|
||||
productId = productIdBody,
|
||||
chatimg = imageMultipart
|
||||
)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.let {
|
||||
Result.Success(it)
|
||||
} ?: Result.Error(Exception("Send chat response is empty"))
|
||||
} else {
|
||||
val errorBody = response.errorBody()?.string() ?: "Unknown error"
|
||||
Log.e(TAG, "HTTP Error: ${response.code()}, Body: $errorBody")
|
||||
Result.Error(Exception("API Error: ${response.code()} - $errorBody"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Exception sending message", e)
|
||||
e.printStackTrace()
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateMessageStatus(
|
||||
messageId: Int,
|
||||
status: String
|
||||
): Result<UpdateChatResponse> {
|
||||
return try {
|
||||
val requestBody = UpdateChatRequest(
|
||||
id = messageId,
|
||||
status = status
|
||||
)
|
||||
|
||||
val response = apiService.updateChatStatus(requestBody)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.let {
|
||||
Result.Success(it)
|
||||
} ?: Result.Error(Exception("Update status response is empty"))
|
||||
} else {
|
||||
Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getChatHistory(chatRoomId: Int): Result<ChatHistoryResponse> {
|
||||
return try {
|
||||
val response = apiService.getChatDetail(chatRoomId)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.let {
|
||||
Result.Success(it)
|
||||
} ?: Result.Error(Exception("Chat history response is empty"))
|
||||
} else {
|
||||
Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,19 +3,10 @@ package com.alya.ecommerce_serang.data.repository
|
||||
import com.alya.ecommerce_serang.data.api.dto.LoginRequest
|
||||
import com.alya.ecommerce_serang.data.api.dto.OtpRequest
|
||||
import com.alya.ecommerce_serang.data.api.dto.RegisterRequest
|
||||
import com.alya.ecommerce_serang.data.api.dto.UpdateChatRequest
|
||||
import com.alya.ecommerce_serang.data.api.dto.UserProfile
|
||||
import com.alya.ecommerce_serang.data.api.response.auth.LoginResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.auth.OtpResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.ChatHistoryResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.SendChatResponse
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.UpdateChatResponse
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import java.io.File
|
||||
|
||||
class UserRepository(private val apiService: ApiService) {
|
||||
|
||||
@ -65,100 +56,101 @@ class UserRepository(private val apiService: ApiService) {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun sendChatMessage(
|
||||
storeId: Int,
|
||||
message: String,
|
||||
productId: Int,
|
||||
imageFile: File? = null
|
||||
): Result<SendChatResponse> {
|
||||
return try {
|
||||
// Create request bodies for text fields
|
||||
val storeIdBody = storeId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val messageBody = message.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val productIdBody = productId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
|
||||
// Create multipart body for the image file
|
||||
val imageMultipart = if (imageFile != null && imageFile.exists()) {
|
||||
val requestFile = imageFile.asRequestBody("image/*".toMediaTypeOrNull())
|
||||
MultipartBody.Part.createFormData("chatimg", imageFile.name, requestFile)
|
||||
} else {
|
||||
// Create an empty part if no image is provided
|
||||
val emptyRequest = "".toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
MultipartBody.Part.createFormData("chatimg", "", emptyRequest)
|
||||
}
|
||||
|
||||
// Make the API call
|
||||
val response = apiService.sendChatLine(
|
||||
storeId = storeIdBody,
|
||||
message = messageBody,
|
||||
productId = productIdBody,
|
||||
chatimg = imageMultipart
|
||||
)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.let {
|
||||
Result.Success(it)
|
||||
} ?: Result.Error(Exception("Send chat response is empty"))
|
||||
} else {
|
||||
Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the status of a message (sent, delivered, read)
|
||||
*
|
||||
* @param messageId The ID of the message to update
|
||||
* @param status The new status to set
|
||||
* @return Result containing the updated message details or error
|
||||
*/
|
||||
suspend fun updateMessageStatus(
|
||||
messageId: Int,
|
||||
status: String
|
||||
): Result<UpdateChatResponse> {
|
||||
return try {
|
||||
val requestBody = UpdateChatRequest(
|
||||
id = messageId,
|
||||
status = status
|
||||
)
|
||||
|
||||
val response = apiService.updateChatStatus(requestBody)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.let {
|
||||
Result.Success(it)
|
||||
} ?: Result.Error(Exception("Update status response is empty"))
|
||||
} else {
|
||||
Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chat history for a specific chat room
|
||||
*
|
||||
* @param chatRoomId The ID of the chat room
|
||||
* @return Result containing the list of chat messages or error
|
||||
*/
|
||||
suspend fun getChatHistory(chatRoomId: Int): Result<ChatHistoryResponse> {
|
||||
return try {
|
||||
val response = apiService.getChatDetail(chatRoomId)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
response.body()?.let {
|
||||
Result.Success(it)
|
||||
} ?: Result.Error(Exception("Chat history response is empty"))
|
||||
} else {
|
||||
Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Result.Error(e)
|
||||
}
|
||||
}
|
||||
// suspend fun sendChatMessage(
|
||||
// storeId: Int,
|
||||
// message: String,
|
||||
// productId: Int,
|
||||
// imageFile: File? = null
|
||||
// ): Result<SendChatResponse> {
|
||||
// return try {
|
||||
// // Create multipart request builder
|
||||
// val requestBodyBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)
|
||||
//
|
||||
// // Add text fields
|
||||
// requestBodyBuilder.addFormDataPart("store_id", storeId.toString())
|
||||
// requestBodyBuilder.addFormDataPart("message", message)
|
||||
// requestBodyBuilder.addFormDataPart("product_id", productId.toString())
|
||||
//
|
||||
// // Add image if it exists
|
||||
// if (imageFile != null && imageFile.exists()) {
|
||||
// val requestFile = imageFile.asRequestBody("image/*".toMediaTypeOrNull())
|
||||
// requestBodyBuilder.addFormDataPart("chatimg", imageFile.name, requestFile)
|
||||
// }
|
||||
//
|
||||
// // Build the final request body
|
||||
// val requestBody = requestBodyBuilder.build()
|
||||
//
|
||||
// // Make the API call using a custom endpoint that takes a plain MultipartBody
|
||||
// val response = apiService.sendChatLineWithBody(requestBody)
|
||||
//
|
||||
// if (response.isSuccessful) {
|
||||
// response.body()?.let {
|
||||
// Result.Success(it)
|
||||
// } ?: Result.Error(Exception("Send chat response is empty"))
|
||||
// } else {
|
||||
// val errorBody = response.errorBody()?.string() ?: "Unknown error"
|
||||
// Log.e("ChatRepository", "HTTP Error: ${response.code()}, Body: $errorBody")
|
||||
// Result.Error(Exception("API Error: ${response.code()} - $errorBody"))
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// Log.e("ChatRepository", "Exception sending message", e)
|
||||
// e.printStackTrace()
|
||||
// Result.Error(e)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Updates the status of a message (sent, delivered, read)
|
||||
// *
|
||||
// * @param messageId The ID of the message to update
|
||||
// * @param status The new status to set
|
||||
// * @return Result containing the updated message details or error
|
||||
// */
|
||||
// suspend fun updateMessageStatus(
|
||||
// messageId: Int,
|
||||
// status: String
|
||||
// ): Result<UpdateChatResponse> {
|
||||
// return try {
|
||||
// val requestBody = UpdateChatRequest(
|
||||
// id = messageId,
|
||||
// status = status
|
||||
// )
|
||||
//
|
||||
// val response = apiService.updateChatStatus(requestBody)
|
||||
//
|
||||
// if (response.isSuccessful) {
|
||||
// response.body()?.let {
|
||||
// Result.Success(it)
|
||||
// } ?: Result.Error(Exception("Update status response is empty"))
|
||||
// } else {
|
||||
// Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// Result.Error(e)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets the chat history for a specific chat room
|
||||
// *
|
||||
// * @param chatRoomId The ID of the chat room
|
||||
// * @return Result containing the list of chat messages or error
|
||||
// */
|
||||
// suspend fun getChatHistory(chatRoomId: Int): Result<ChatHistoryResponse> {
|
||||
// return try {
|
||||
// val response = apiService.getChatDetail(chatRoomId)
|
||||
//
|
||||
// if (response.isSuccessful) {
|
||||
// response.body()?.let {
|
||||
// Result.Success(it)
|
||||
// } ?: Result.Error(Exception("Chat history response is empty"))
|
||||
// } else {
|
||||
// Result.Error(Exception(response.errorBody()?.string() ?: "Unknown error"))
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// Result.Error(e)
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.alya.ecommerce_serang.di
|
||||
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||
import com.alya.ecommerce_serang.data.repository.ChatRepository
|
||||
import com.alya.ecommerce_serang.data.repository.UserRepository
|
||||
import com.alya.ecommerce_serang.ui.chat.SocketIOService
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
@ -16,7 +17,13 @@ object ChatModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideChatRepository(apiService: ApiService): UserRepository {
|
||||
fun provideChatRepository(apiService: ApiService): ChatRepository {
|
||||
return ChatRepository(apiService)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUserRepository(apiService: ApiService): UserRepository {
|
||||
return UserRepository(apiService)
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.alya.ecommerce_serang.BuildConfig.BASE_URL
|
||||
import com.alya.ecommerce_serang.R
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiService
|
||||
import com.alya.ecommerce_serang.databinding.ActivityChatBinding
|
||||
import com.alya.ecommerce_serang.ui.auth.LoginActivity
|
||||
import com.alya.ecommerce_serang.utils.Constants
|
||||
@ -47,6 +49,9 @@ class ChatActivity : AppCompatActivity() {
|
||||
@Inject
|
||||
lateinit var sessionManager: SessionManager
|
||||
|
||||
@Inject
|
||||
lateinit var apiService: ApiService
|
||||
|
||||
private lateinit var chatAdapter: ChatAdapter
|
||||
|
||||
private val viewModel: ChatViewModel by viewModels()
|
||||
@ -92,8 +97,10 @@ class ChatActivity : AppCompatActivity() {
|
||||
setContentView(binding.root)
|
||||
|
||||
sessionManager = SessionManager(this)
|
||||
apiService = ApiConfig.getApiService(sessionManager)
|
||||
|
||||
Log.d("ChatActivity", "Token in storage: '${sessionManager.getToken()}'")
|
||||
Log.d("ChatActivity", "User ID in storage: '${sessionManager.getUserId()}'")
|
||||
// Log.d("ChatActivity", "User ID in storage: '${sessionManager.getUserId()}'")
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
enableEdgeToEdge()
|
||||
@ -121,7 +128,6 @@ class ChatActivity : AppCompatActivity() {
|
||||
|
||||
|
||||
// Check if user is logged in
|
||||
val userId = sessionManager.getUserId()
|
||||
val token = sessionManager.getToken()
|
||||
|
||||
if (token.isEmpty()) {
|
||||
|
@ -76,7 +76,7 @@ class ChatAdapter : ListAdapter<ChatUiMessage, RecyclerView.ViewHolder>(ChatMess
|
||||
binding.imgStatus.setImageResource(statusIcon)
|
||||
|
||||
// Handle attachment if exists
|
||||
if (message.attachment.isNotEmpty()) {
|
||||
if (message.attachment?.isNotEmpty() == true) {
|
||||
binding.imgAttachment.visibility = View.VISIBLE
|
||||
Glide.with(binding.root.context)
|
||||
.load(BASE_URL + message.attachment)
|
||||
@ -101,7 +101,7 @@ class ChatAdapter : ListAdapter<ChatUiMessage, RecyclerView.ViewHolder>(ChatMess
|
||||
binding.tvTimestamp.text = message.time
|
||||
|
||||
// Handle attachment if exists
|
||||
if (message.attachment.isNotEmpty()) {
|
||||
if (message.attachment?.isNotEmpty() == true) {
|
||||
binding.imgAttachment.visibility = View.VISIBLE
|
||||
Glide.with(binding.root.context)
|
||||
.load(BASE_URL + message.attachment)
|
||||
|
@ -8,7 +8,7 @@ import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.alya.ecommerce_serang.data.api.retrofit.ApiConfig
|
||||
import com.alya.ecommerce_serang.data.repository.UserRepository
|
||||
import com.alya.ecommerce_serang.data.repository.ChatRepository
|
||||
import com.alya.ecommerce_serang.databinding.FragmentChatListBinding
|
||||
import com.alya.ecommerce_serang.utils.BaseViewModelFactory
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
@ -23,8 +23,8 @@ class ChatListFragment : Fragment() {
|
||||
private val viewModel: com.alya.ecommerce_serang.ui.chat.ChatViewModel by viewModels {
|
||||
BaseViewModelFactory {
|
||||
val apiService = ApiConfig.getApiService(sessionManager)
|
||||
val userRepository = UserRepository(apiService)
|
||||
ChatViewModel(userRepository, socketService, sessionManager)
|
||||
val chatRepository = ChatRepository(apiService)
|
||||
ChatViewModel(chatRepository, socketService, sessionManager)
|
||||
}
|
||||
}
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -7,8 +7,8 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.ChatItem
|
||||
import com.alya.ecommerce_serang.data.api.response.chat.ChatLine
|
||||
import com.alya.ecommerce_serang.data.repository.ChatRepository
|
||||
import com.alya.ecommerce_serang.data.repository.Result
|
||||
import com.alya.ecommerce_serang.data.repository.UserRepository
|
||||
import com.alya.ecommerce_serang.utils.Constants
|
||||
import com.alya.ecommerce_serang.utils.SessionManager
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@ -20,7 +20,7 @@ import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ChatViewModel @Inject constructor(
|
||||
private val chatRepository: UserRepository,
|
||||
private val chatRepository: ChatRepository,
|
||||
private val socketService: SocketIOService,
|
||||
private val sessionManager: SessionManager
|
||||
) : ViewModel() {
|
||||
@ -37,10 +37,9 @@ class ChatViewModel @Inject constructor(
|
||||
// Store and product parameters
|
||||
private var storeId: Int = 0
|
||||
private var productId: Int = 0
|
||||
private var currentUserId: Int? = 0
|
||||
private var currentUserId: Int? = null
|
||||
private var defaultUserId: Int = 0
|
||||
|
||||
|
||||
// Product details for display
|
||||
private var productName: String = ""
|
||||
private var productPrice: String = ""
|
||||
@ -52,7 +51,7 @@ class ChatViewModel @Inject constructor(
|
||||
private var selectedImageFile: File? = null
|
||||
|
||||
init {
|
||||
// Try to get current user ID from SessionManager
|
||||
// Try to get current user ID from the repository
|
||||
viewModelScope.launch {
|
||||
when (val result = chatRepository.fetchUserProfile()) {
|
||||
is Result.Success -> {
|
||||
@ -60,7 +59,7 @@ class ChatViewModel @Inject constructor(
|
||||
Log.e(TAG, "User ID: $currentUserId")
|
||||
|
||||
// Move the validation and subsequent logic inside the coroutine
|
||||
if (currentUserId == 0) {
|
||||
if (currentUserId == null || currentUserId == 0) {
|
||||
Log.e(TAG, "Error: User ID is not set or invalid")
|
||||
updateState { it.copy(error = "User authentication error. Please login again.") }
|
||||
} else {
|
||||
@ -188,7 +187,7 @@ class ChatViewModel @Inject constructor(
|
||||
/**
|
||||
* Loads chat history
|
||||
*/
|
||||
fun loadChatHistory(chatRoomId : Int) {
|
||||
fun loadChatHistory(chatRoomId: Int) {
|
||||
if (chatRoomId <= 0) {
|
||||
Log.e(TAG, "Cannot load chat history: Chat room ID is 0")
|
||||
return
|
||||
@ -198,7 +197,7 @@ class ChatViewModel @Inject constructor(
|
||||
updateState { it.copy(isLoading = true) }
|
||||
|
||||
when (val result = chatRepository.getChatHistory(chatRoomId)) {
|
||||
is com.alya.ecommerce_serang.data.repository.Result.Success -> {
|
||||
is Result.Success -> {
|
||||
val messages = result.data.chat.map { chatLine ->
|
||||
convertChatLineToUiMessageHistory(chatLine)
|
||||
}
|
||||
@ -218,7 +217,7 @@ class ChatViewModel @Inject constructor(
|
||||
.filter { it.senderId != currentUserId && it.status != Constants.STATUS_READ }
|
||||
.forEach { updateMessageStatus(it.id, Constants.STATUS_READ) }
|
||||
}
|
||||
is com.alya.ecommerce_serang.data.repository.Result.Error -> {
|
||||
is Result.Error -> {
|
||||
updateState {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
@ -238,7 +237,7 @@ class ChatViewModel @Inject constructor(
|
||||
* Sends a chat message
|
||||
*/
|
||||
fun sendMessage(message: String) {
|
||||
if (message.isBlank() && selectedImageFile == null) return
|
||||
if (message.isBlank()) return
|
||||
|
||||
if (storeId == 0 || productId == 0) {
|
||||
Log.e(TAG, "Cannot send message: Store ID or Product ID is 0")
|
||||
@ -255,7 +254,7 @@ class ChatViewModel @Inject constructor(
|
||||
productId = productId,
|
||||
imageFile = selectedImageFile
|
||||
)) {
|
||||
is com.alya.ecommerce_serang.data.repository.Result.Success -> {
|
||||
is Result.Success -> {
|
||||
// Add new message to the list
|
||||
val chatLine = result.data.chatLine
|
||||
val newMessage = convertChatLineToUiMessage(chatLine)
|
||||
@ -293,16 +292,22 @@ class ChatViewModel @Inject constructor(
|
||||
// Clear the image attachment
|
||||
selectedImageFile = null
|
||||
}
|
||||
is com.alya.ecommerce_serang.data.repository.Result.Error -> {
|
||||
is Result.Error -> {
|
||||
val errorMsg = if (result.exception.message.isNullOrEmpty() || result.exception.message == "{}") {
|
||||
"Failed to send message. Please try again."
|
||||
} else {
|
||||
result.exception.message
|
||||
}
|
||||
|
||||
updateState {
|
||||
it.copy(
|
||||
isSending = false,
|
||||
error = result.exception.message
|
||||
error = errorMsg
|
||||
)
|
||||
}
|
||||
Log.e(TAG, "Error sending message: ${result.exception.message}")
|
||||
}
|
||||
is com.alya.ecommerce_serang.data.repository.Result.Loading -> {
|
||||
is Result.Loading -> {
|
||||
updateState { it.copy(isSending = true) }
|
||||
}
|
||||
}
|
||||
@ -317,7 +322,7 @@ class ChatViewModel @Inject constructor(
|
||||
try {
|
||||
val result = chatRepository.updateMessageStatus(messageId, status)
|
||||
|
||||
if (result is com.alya.ecommerce_serang.data.repository.Result.Success) {
|
||||
if (result is Result.Success) {
|
||||
// Update local message status
|
||||
val currentMessages = _state.value?.messages ?: listOf()
|
||||
val updatedMessages = currentMessages.map { message ->
|
||||
@ -330,7 +335,7 @@ class ChatViewModel @Inject constructor(
|
||||
updateState { it.copy(messages = updatedMessages) }
|
||||
|
||||
Log.d(TAG, "Message status updated: $messageId -> $status")
|
||||
} else if (result is com.alya.ecommerce_serang.data.repository.Result.Error) {
|
||||
} else if (result is Result.Error) {
|
||||
Log.e(TAG, "Error updating message status: ${result.exception.message}")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@ -386,7 +391,7 @@ class ChatViewModel @Inject constructor(
|
||||
return ChatUiMessage(
|
||||
id = chatLine.id,
|
||||
message = chatLine.message,
|
||||
attachment = chatLine.attachment,
|
||||
attachment = chatLine.attachment ?: "", // Handle null attachment
|
||||
status = chatLine.status,
|
||||
time = formattedTime,
|
||||
isSentByMe = chatLine.senderId == currentUserId
|
||||
@ -408,7 +413,7 @@ class ChatViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
return ChatUiMessage(
|
||||
attachment = "",
|
||||
attachment = chatItem.attachment, // Handle null attachment
|
||||
id = chatItem.id,
|
||||
message = chatItem.message,
|
||||
status = chatItem.status,
|
||||
@ -451,7 +456,7 @@ data class ChatUiState(
|
||||
data class ChatUiMessage(
|
||||
val id: Int,
|
||||
val message: String,
|
||||
val attachment: String,
|
||||
val attachment: String?,
|
||||
val status: String,
|
||||
val time: String,
|
||||
val isSentByMe: Boolean
|
||||
|
Reference in New Issue
Block a user