made chat more user frendly
This commit is contained in:
@@ -10,11 +10,18 @@ import android.os.Bundle;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -22,6 +29,7 @@ import androidx.core.view.GravityCompat;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.example.petstoremobile.R;
|
import com.example.petstoremobile.R;
|
||||||
import com.example.petstoremobile.adapters.ChatAdapter;
|
import com.example.petstoremobile.adapters.ChatAdapter;
|
||||||
@@ -45,7 +53,8 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
@@ -65,10 +74,12 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
private FragmentChatBinding binding;
|
private FragmentChatBinding binding;
|
||||||
private ChatListViewModel viewModel;
|
private ChatListViewModel viewModel;
|
||||||
|
|
||||||
private ChatAdapter chatAdapter;
|
private ChatAdapter activeChatAdapter;
|
||||||
|
private ChatAdapter closedChatAdapter;
|
||||||
private MessageAdapter messageAdapter;
|
private MessageAdapter messageAdapter;
|
||||||
|
|
||||||
private final List<Chat> chatList = new ArrayList<>();
|
private final List<Chat> activeChatList = new ArrayList<>();
|
||||||
|
private final List<Chat> closedChatList = new ArrayList<>();
|
||||||
private final List<Message> messageList = new ArrayList<>();
|
private final List<Message> messageList = new ArrayList<>();
|
||||||
private Uri pendingAttachmentUri;
|
private Uri pendingAttachmentUri;
|
||||||
|
|
||||||
@@ -82,7 +93,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
viewModel = new ViewModelProvider(this).get(ChatListViewModel.class);
|
viewModel = new ViewModelProvider(requireActivity()).get(ChatListViewModel.class);
|
||||||
attachmentLauncher = registerForActivityResult(
|
attachmentLauncher = registerForActivityResult(
|
||||||
new ActivityResultContracts.StartActivityForResult(),
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
result -> {
|
result -> {
|
||||||
@@ -117,6 +128,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
binding.btnAttach.setOnClickListener(v -> selectAttachment());
|
binding.btnAttach.setOnClickListener(v -> selectAttachment());
|
||||||
binding.btnRemoveAttachment.setOnClickListener(v -> removeAttachment());
|
binding.btnRemoveAttachment.setOnClickListener(v -> removeAttachment());
|
||||||
|
|
||||||
|
setupDrawerToggles();
|
||||||
setupRecyclerViews();
|
setupRecyclerViews();
|
||||||
observeViewModel();
|
observeViewModel();
|
||||||
loadInitialData();
|
loadInitialData();
|
||||||
@@ -124,10 +136,36 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setupDrawerToggles() {
|
||||||
|
binding.headerActiveChats.setOnClickListener(v -> {
|
||||||
|
if (binding.rvActiveChats.getVisibility() == View.VISIBLE) {
|
||||||
|
binding.rvActiveChats.setVisibility(View.GONE);
|
||||||
|
binding.ivActiveChevron.setImageResource(android.R.drawable.arrow_down_float);
|
||||||
|
} else {
|
||||||
|
binding.rvActiveChats.setVisibility(View.VISIBLE);
|
||||||
|
binding.ivActiveChevron.setImageResource(android.R.drawable.arrow_up_float);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.headerClosedChats.setOnClickListener(v -> {
|
||||||
|
if (binding.rvClosedChats.getVisibility() == View.VISIBLE) {
|
||||||
|
binding.rvClosedChats.setVisibility(View.GONE);
|
||||||
|
binding.ivClosedChevron.setImageResource(android.R.drawable.arrow_down_float);
|
||||||
|
} else {
|
||||||
|
binding.rvClosedChats.setVisibility(View.VISIBLE);
|
||||||
|
binding.ivClosedChevron.setImageResource(android.R.drawable.arrow_up_float);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void setupRecyclerViews() {
|
private void setupRecyclerViews() {
|
||||||
chatAdapter = new ChatAdapter(chatList, this);
|
activeChatAdapter = new ChatAdapter(activeChatList, this);
|
||||||
binding.rvChatList.setLayoutManager(new LinearLayoutManager(getContext()));
|
binding.rvActiveChats.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
binding.rvChatList.setAdapter(chatAdapter);
|
binding.rvActiveChats.setAdapter(activeChatAdapter);
|
||||||
|
|
||||||
|
closedChatAdapter = new ChatAdapter(closedChatList, this);
|
||||||
|
binding.rvClosedChats.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.rvClosedChats.setAdapter(closedChatAdapter);
|
||||||
|
|
||||||
messageAdapter = new MessageAdapter(messageList, null);
|
messageAdapter = new MessageAdapter(messageList, null);
|
||||||
messageAdapter.setBaseUrl(baseUrl);
|
messageAdapter.setBaseUrl(baseUrl);
|
||||||
@@ -144,7 +182,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
lm.setStackFromEnd(true);
|
lm.setStackFromEnd(true);
|
||||||
binding.rvMessages.setLayoutManager(lm);
|
binding.rvMessages.setLayoutManager(lm);
|
||||||
binding.rvMessages.setAdapter(messageAdapter);
|
binding.rvMessages.setAdapter(messageAdapter);
|
||||||
setConversationActive(false);
|
setConversationActive(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFullScreenImage(Message message) {
|
private void showFullScreenImage(Message message) {
|
||||||
@@ -226,19 +264,18 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void observeViewModel() {
|
private void observeViewModel() {
|
||||||
viewModel.getChatList().observe(getViewLifecycleOwner(), list -> {
|
viewModel.getActiveChats().observe(getViewLifecycleOwner(), list -> {
|
||||||
chatList.clear();
|
activeChatList.clear();
|
||||||
chatList.addAll(list);
|
activeChatList.addAll(list);
|
||||||
chatAdapter.notifyDataSetChanged();
|
activeChatAdapter.notifyDataSetChanged();
|
||||||
|
updateTitleAndStateIfActive(list);
|
||||||
|
});
|
||||||
|
|
||||||
if (activeConversationId != null) {
|
viewModel.getClosedChats().observe(getViewLifecycleOwner(), list -> {
|
||||||
for (Chat chat : list) {
|
closedChatList.clear();
|
||||||
if (chat.getChatId().equals(String.valueOf(activeConversationId))) {
|
closedChatList.addAll(list);
|
||||||
binding.tvChatTitle.setText(chat.getCustomerName());
|
closedChatAdapter.notifyDataSetChanged();
|
||||||
break;
|
updateTitleAndStateIfActive(list);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
viewModel.getMessageList().observe(getViewLifecycleOwner(), list -> {
|
viewModel.getMessageList().observe(getViewLifecycleOwner(), list -> {
|
||||||
@@ -253,6 +290,18 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateTitleAndStateIfActive(List<Chat> list) {
|
||||||
|
if (activeConversationId != null) {
|
||||||
|
for (Chat chat : list) {
|
||||||
|
if (chat.getChatId().equals(String.valueOf(activeConversationId))) {
|
||||||
|
binding.tvChatTitle.setText(chat.getCustomerName());
|
||||||
|
setConversationActive(true, chat.getStatus());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadInitialData() {
|
private void loadInitialData() {
|
||||||
String token = tokenManager.getToken();
|
String token = tokenManager.getToken();
|
||||||
Long currentUserId = tokenManager.getUserId();
|
Long currentUserId = tokenManager.getUserId();
|
||||||
@@ -274,21 +323,29 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
} else if (getActivity() != null && getActivity().getIntent().hasExtra("conversation_id")) {
|
} else if (getActivity() != null && getActivity().getIntent().hasExtra("conversation_id")) {
|
||||||
activeConversationId = getActivity().getIntent().getLongExtra("conversation_id", -1);
|
activeConversationId = getActivity().getIntent().getLongExtra("conversation_id", -1);
|
||||||
getActivity().getIntent().removeExtra("conversation_id");
|
getActivity().getIntent().removeExtra("conversation_id");
|
||||||
|
} else {
|
||||||
|
// Restore last active conversation if any
|
||||||
|
activeConversationId = viewModel.getLastActiveConversationId();
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.loadCustomers();
|
viewModel.loadCustomers();
|
||||||
|
|
||||||
|
//
|
||||||
if (activeConversationId != null) {
|
if (activeConversationId != null) {
|
||||||
setConversationActive(true);
|
// Re-subscribe and load history if there is an active conversation ID
|
||||||
if (stompChatManager != null) stompChatManager.subscribeToConversation(activeConversationId);
|
if (stompChatManager != null) stompChatManager.subscribeToConversation(activeConversationId);
|
||||||
viewModel.loadMessageHistory(activeConversationId);
|
viewModel.loadMessageHistory(activeConversationId);
|
||||||
|
} else {
|
||||||
|
setConversationActive(false, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChatClick(Chat chat) {
|
public void onChatClick(Chat chat) {
|
||||||
activeConversationId = Long.parseLong(chat.getChatId());
|
activeConversationId = Long.parseLong(chat.getChatId());
|
||||||
setConversationActive(true);
|
viewModel.setLastActiveConversationId(activeConversationId);
|
||||||
|
|
||||||
|
setConversationActive(true, chat.getStatus());
|
||||||
binding.tvChatTitle.setText(chat.getCustomerName());
|
binding.tvChatTitle.setText(chat.getCustomerName());
|
||||||
binding.chatDrawerLayout.closeDrawer(GravityCompat.START);
|
binding.chatDrawerLayout.closeDrawer(GravityCompat.START);
|
||||||
|
|
||||||
@@ -377,8 +434,6 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
viewModel.updateConversationLocally(new ConversationDTO(dto.getConversationId(), 0L, 0L, dto.getContent(), ""));
|
viewModel.updateConversationLocally(new ConversationDTO(dto.getConversationId(), 0L, 0L, dto.getContent(), ""));
|
||||||
// Re-load coversations to get correct names if needed or just let local update handle it
|
|
||||||
viewModel.loadConversations();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +442,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
requireActivity().runOnUiThread(() -> {
|
requireActivity().runOnUiThread(() -> {
|
||||||
viewModel.updateConversationLocally(dto);
|
viewModel.updateConversationLocally(dto);
|
||||||
if (activeConversationId != null && activeConversationId.equals(dto.getId())) {
|
if (activeConversationId != null && activeConversationId.equals(dto.getId())) {
|
||||||
setConversationActive(true);
|
setConversationActive(true, dto.getStatus());
|
||||||
binding.tvChatTitle.setText(viewModel.getCustomerName(dto.getCustomerId()));
|
binding.tvChatTitle.setText(viewModel.getCustomerName(dto.getCustomerId()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -424,8 +479,10 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setConversationActive(boolean active) {
|
private void setConversationActive(boolean active, String status) {
|
||||||
UIUtils.setViewsEnabled(active, binding.btnSend, binding.etMessage, binding.btnAttach);
|
boolean isClosed = "CLOSED".equalsIgnoreCase(status);
|
||||||
|
UIUtils.setViewsEnabled(active && !isClosed, binding.btnSend, binding.etMessage, binding.btnAttach);
|
||||||
|
|
||||||
if (!active) {
|
if (!active) {
|
||||||
activeConversationId = null;
|
activeConversationId = null;
|
||||||
ChatNotificationService.activeConversationIdInUi = null;
|
ChatNotificationService.activeConversationIdInUi = null;
|
||||||
@@ -437,7 +494,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
binding.etMessage.setText("");
|
binding.etMessage.setText("");
|
||||||
binding.etMessage.setHint("Select a chat to start messaging");
|
binding.etMessage.setHint("Select a chat to start messaging");
|
||||||
} else {
|
} else {
|
||||||
binding.etMessage.setHint("Type a message...");
|
binding.etMessage.setHint(isClosed ? "This chat is closed" : "Type a message...");
|
||||||
ChatNotificationService.activeConversationIdInUi = activeConversationId;
|
ChatNotificationService.activeConversationIdInUi = activeConversationId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,4 +506,4 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
|||||||
ChatNotificationService.activeConversationIdInUi = null;
|
ChatNotificationService.activeConversationIdInUi = null;
|
||||||
if (stompChatManager != null) stompChatManager.disconnect();
|
if (stompChatManager != null) stompChatManager.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,15 @@ public class Chat {
|
|||||||
private String lastMessage;
|
private String lastMessage;
|
||||||
private Long customerId;
|
private Long customerId;
|
||||||
private Long staffId;
|
private Long staffId;
|
||||||
|
private String status;
|
||||||
|
|
||||||
public Chat(String chatId, String customerName, String lastMessage, Long customerId, Long staffId) {
|
public Chat(String chatId, String customerName, String lastMessage, Long customerId, Long staffId, String status) {
|
||||||
this.chatId = chatId;
|
this.chatId = chatId;
|
||||||
this.customerName = customerName;
|
this.customerName = customerName;
|
||||||
this.lastMessage = lastMessage;
|
this.lastMessage = lastMessage;
|
||||||
this.customerId = customerId;
|
this.customerId = customerId;
|
||||||
this.staffId = staffId;
|
this.staffId = staffId;
|
||||||
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getChatId() {
|
public String getChatId() {
|
||||||
@@ -34,4 +36,8 @@ public class Chat {
|
|||||||
public Long getStaffId() {
|
public Long getStaffId() {
|
||||||
return staffId;
|
return staffId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -32,10 +33,13 @@ public class ChatListViewModel extends ViewModel {
|
|||||||
private final ChatRepository chatRepository;
|
private final ChatRepository chatRepository;
|
||||||
private final CustomerRepository customerRepository;
|
private final CustomerRepository customerRepository;
|
||||||
|
|
||||||
private final MutableLiveData<List<Chat>> chatList = new MutableLiveData<>(new ArrayList<>());
|
private final MutableLiveData<List<Chat>> activeChats = new MutableLiveData<>(new ArrayList<>());
|
||||||
|
private final MutableLiveData<List<Chat>> closedChats = new MutableLiveData<>(new ArrayList<>());
|
||||||
private final MutableLiveData<List<Message>> messageList = new MutableLiveData<>(new ArrayList<>());
|
private final MutableLiveData<List<Message>> messageList = new MutableLiveData<>(new ArrayList<>());
|
||||||
private final Map<Long, String> customerNames = new HashMap<>();
|
private final Map<Long, String> customerNames = new HashMap<>();
|
||||||
private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);
|
private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);
|
||||||
|
|
||||||
|
private Long lastActiveConversationId = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ChatListViewModel(ChatRepository chatRepository, CustomerRepository customerRepository) {
|
public ChatListViewModel(ChatRepository chatRepository, CustomerRepository customerRepository) {
|
||||||
@@ -43,10 +47,19 @@ public class ChatListViewModel extends ViewModel {
|
|||||||
this.customerRepository = customerRepository;
|
this.customerRepository = customerRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Chat>> getChatList() { return chatList; }
|
public LiveData<List<Chat>> getActiveChats() { return activeChats; }
|
||||||
|
public LiveData<List<Chat>> getClosedChats() { return closedChats; }
|
||||||
public LiveData<List<Message>> getMessageList() { return messageList; }
|
public LiveData<List<Message>> getMessageList() { return messageList; }
|
||||||
public LiveData<Boolean> getIsLoading() { return isLoading; }
|
public LiveData<Boolean> getIsLoading() { return isLoading; }
|
||||||
|
|
||||||
|
public Long getLastActiveConversationId() {
|
||||||
|
return lastActiveConversationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastActiveConversationId(Long conversationId) {
|
||||||
|
this.lastActiveConversationId = conversationId;
|
||||||
|
}
|
||||||
|
|
||||||
public void loadCustomers() {
|
public void loadCustomers() {
|
||||||
customerRepository.getAllCustomers(0, 100).observeForever(resource -> {
|
customerRepository.getAllCustomers(0, 100).observeForever(resource -> {
|
||||||
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
@@ -62,12 +75,19 @@ public class ChatListViewModel extends ViewModel {
|
|||||||
isLoading.setValue(true);
|
isLoading.setValue(true);
|
||||||
chatRepository.getAllConversations().observeForever(resource -> {
|
chatRepository.getAllConversations().observeForever(resource -> {
|
||||||
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
|
||||||
List<Chat> chats = new ArrayList<>();
|
List<Chat> active = new ArrayList<>();
|
||||||
|
List<Chat> closed = new ArrayList<>();
|
||||||
for (ConversationDTO dto : resource.data) {
|
for (ConversationDTO dto : resource.data) {
|
||||||
String name = customerNames.getOrDefault(dto.getCustomerId(), "Customer #" + dto.getCustomerId());
|
String name = customerNames.getOrDefault(dto.getCustomerId(), "Customer #" + dto.getCustomerId());
|
||||||
chats.add(new Chat(String.valueOf(dto.getId()), name, dto.getLastMessage(), dto.getCustomerId(), dto.getStaffId()));
|
Chat chat = new Chat(String.valueOf(dto.getId()), name, dto.getLastMessage(), dto.getCustomerId(), dto.getStaffId(), dto.getStatus());
|
||||||
|
if ("CLOSED".equalsIgnoreCase(dto.getStatus())) {
|
||||||
|
closed.add(chat);
|
||||||
|
} else {
|
||||||
|
active.add(chat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chatList.setValue(chats);
|
activeChats.setValue(active);
|
||||||
|
closedChats.setValue(closed);
|
||||||
isLoading.setValue(false);
|
isLoading.setValue(false);
|
||||||
} else if (resource != null && resource.status == Resource.Status.ERROR) {
|
} else if (resource != null && resource.status == Resource.Status.ERROR) {
|
||||||
isLoading.setValue(false);
|
isLoading.setValue(false);
|
||||||
@@ -106,21 +126,24 @@ public class ChatListViewModel extends ViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateConversationLocally(ConversationDTO dto) {
|
public void updateConversationLocally(ConversationDTO dto) {
|
||||||
List<Chat> current = new ArrayList<>(chatList.getValue());
|
updateList(activeChats, dto);
|
||||||
boolean updated = false;
|
updateList(closedChats, dto);
|
||||||
String name = customerNames.getOrDefault(dto.getCustomerId(), "Customer #" + dto.getCustomerId());
|
|
||||||
|
|
||||||
|
loadConversations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateList(MutableLiveData<List<Chat>> liveData, ConversationDTO dto) {
|
||||||
|
List<Chat> current = new ArrayList<>(liveData.getValue());
|
||||||
|
String name = customerNames.getOrDefault(dto.getCustomerId(), "Customer #" + dto.getCustomerId());
|
||||||
|
boolean updated = false;
|
||||||
for (int i = 0; i < current.size(); i++) {
|
for (int i = 0; i < current.size(); i++) {
|
||||||
if (current.get(i).getChatId().equals(String.valueOf(dto.getId()))) {
|
if (current.get(i).getChatId().equals(String.valueOf(dto.getId()))) {
|
||||||
current.set(i, new Chat(String.valueOf(dto.getId()), name, dto.getLastMessage(), dto.getCustomerId(), dto.getStaffId()));
|
current.set(i, new Chat(String.valueOf(dto.getId()), name, dto.getLastMessage(), dto.getCustomerId(), dto.getStaffId(), dto.getStatus()));
|
||||||
updated = true;
|
updated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!updated) {
|
if (updated) liveData.setValue(current);
|
||||||
current.add(0, new Chat(String.valueOf(dto.getId()), name, dto.getLastMessage(), dto.getCustomerId(), dto.getStaffId()));
|
|
||||||
}
|
|
||||||
chatList.setValue(current);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message dtoToModel(MessageDTO dto) {
|
private Message dtoToModel(MessageDTO dto) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.drawerlayout.widget.DrawerLayout
|
<androidx.drawerlayout.widget.DrawerLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/chatDrawerLayout"
|
android:id="@+id/chatDrawerLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
@@ -125,29 +126,101 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.core.widget.NestedScrollView
|
||||||
android:id="@+id/chatListDrawer"
|
android:id="@+id/chatListDrawer"
|
||||||
android:layout_width="260dp"
|
android:layout_width="260dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:orientation="vertical"
|
android:background="@color/primary_dark">
|
||||||
android:background="@color/primary_dark"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Active Chats"
|
android:orientation="vertical"
|
||||||
android:textColor="@color/white"
|
android:paddingTop="24dp">
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<LinearLayout
|
||||||
android:id="@+id/rvChatList"
|
android:id="@+id/headerActiveChats"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
</LinearLayout>
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="ACTIVE CHATS"
|
||||||
|
android:textColor="@color/text_light"
|
||||||
|
android:textSize="11sp"
|
||||||
|
android:letterSpacing="0.15"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivActiveChevron"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:src="@android:drawable/arrow_up_float"
|
||||||
|
app:tint="@color/text_light"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvActiveChats"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/headerClosedChats"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="CLOSED CHATS"
|
||||||
|
android:textColor="@color/text_light"
|
||||||
|
android:textSize="11sp"
|
||||||
|
android:letterSpacing="0.15"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivClosedChevron"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:src="@android:drawable/arrow_down_float"
|
||||||
|
app:tint="@color/text_light"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvClosedChats"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
</androidx.drawerlayout.widget.DrawerLayout>
|
||||||
Reference in New Issue
Block a user