added close chat option to chat
This commit is contained in:
@@ -2,13 +2,14 @@ package com.example.petstoremobile.api;
|
||||
|
||||
import com.example.petstoremobile.dtos.ConversationDTO;
|
||||
import com.example.petstoremobile.dtos.MessageDTO;
|
||||
import com.example.petstoremobile.dtos.UpdateConversationStatusRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
|
||||
//api calls to get conversations
|
||||
@@ -20,4 +21,7 @@ public interface ChatApi {
|
||||
@GET("api/v1/chat/conversations/{conversationId}")
|
||||
Call<ConversationDTO> getConversationById(@Path("conversationId") Long conversationId);
|
||||
|
||||
@PUT("api/v1/chat/conversations/{conversationId}")
|
||||
Call<ConversationDTO> updateConversationStatus(@Path("conversationId") Long conversationId, @Body UpdateConversationStatusRequest request);
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import java.math.BigDecimal;
|
||||
public class CouponDTO {
|
||||
private Long couponId;
|
||||
private String couponCode;
|
||||
private String discountType; // FIXED, PERCENT
|
||||
private String discountType;
|
||||
private BigDecimal discountValue;
|
||||
private BigDecimal minOrderAmount;
|
||||
private Boolean active;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.petstoremobile.dtos;
|
||||
|
||||
public class UpdateConversationStatusRequest {
|
||||
private String status;
|
||||
|
||||
public UpdateConversationStatusRequest(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -127,6 +127,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
||||
|
||||
binding.btnAttach.setOnClickListener(v -> selectAttachment());
|
||||
binding.btnRemoveAttachment.setOnClickListener(v -> removeAttachment());
|
||||
binding.btnCloseChat.setOnClickListener(v -> closeChat());
|
||||
|
||||
setupDrawerToggles();
|
||||
setupRecyclerViews();
|
||||
@@ -356,6 +357,30 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
||||
viewModel.loadMessageHistory(activeConversationId);
|
||||
}
|
||||
|
||||
private void closeChat() {
|
||||
if (activeConversationId == null) return;
|
||||
|
||||
DialogUtils.showConfirmDialog(requireContext(), "Close Chat",
|
||||
"Are you sure you want to close this chat? This will notify the customer.", () -> {
|
||||
viewModel.sendMessage(activeConversationId, "The Chat has been closed").observe(getViewLifecycleOwner(), resource -> {
|
||||
if (resource != null && resource.status == Resource.Status.SUCCESS) {
|
||||
viewModel.addMessageLocally(resource.data);
|
||||
|
||||
viewModel.closeConversation(activeConversationId).observe(getViewLifecycleOwner(), statusResource -> {
|
||||
if (statusResource == null) return;
|
||||
setLoading(statusResource.status == Resource.Status.LOADING);
|
||||
if (statusResource.status == Resource.Status.SUCCESS) {
|
||||
viewModel.loadConversations();
|
||||
setConversationActive(true, "CLOSED");
|
||||
} else if (statusResource.status == Resource.Status.ERROR) {
|
||||
Toast.makeText(requireContext(), "Failed to close chat: " + statusResource.message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void sendMessage() {
|
||||
if (activeConversationId == null) return;
|
||||
String text = binding.etMessage.getText().toString().trim();
|
||||
@@ -489,6 +514,7 @@ public class ChatFragment extends Fragment implements ChatAdapter.OnChatClickLis
|
||||
private void setConversationActive(boolean active, String status) {
|
||||
boolean isClosed = "CLOSED".equalsIgnoreCase(status);
|
||||
UIUtils.setViewsEnabled(active && !isClosed, binding.btnSend, binding.etMessage, binding.btnAttach);
|
||||
binding.btnCloseChat.setVisibility(active && !isClosed ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (!active) {
|
||||
activeConversationId = null;
|
||||
|
||||
@@ -43,15 +43,13 @@ public class ListFragment extends Fragment {
|
||||
// Check user role and restrict access for STAFF
|
||||
String role = tokenManager.getRole();
|
||||
if ("STAFF".equalsIgnoreCase(role)) {
|
||||
binding.drawerSuppliers.setVisibility(View.GONE);
|
||||
binding.drawerInventory.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Only show for ADMIN
|
||||
if ("ADMIN".equalsIgnoreCase(role)) {
|
||||
binding.sectionAdmin.setVisibility(View.GONE);
|
||||
} else if ("ADMIN".equalsIgnoreCase(role)) {
|
||||
binding.sectionAdmin.setVisibility(View.VISIBLE);
|
||||
binding.drawerStaff.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.drawerStaff.setVisibility(View.GONE);
|
||||
// Default or other roles
|
||||
binding.sectionAdmin.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
//add Listeners to the drawer so user won't be able to interact with the innerContainer (the list fragments)
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.example.petstoremobile.dtos.CustomerDTO;
|
||||
import com.example.petstoremobile.dtos.MessageDTO;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.SendMessageRequest;
|
||||
import com.example.petstoremobile.dtos.UpdateConversationStatusRequest;
|
||||
import com.example.petstoremobile.utils.Resource;
|
||||
|
||||
import java.util.List;
|
||||
@@ -73,6 +74,13 @@ public class ChatRepository extends BaseRepository {
|
||||
return executeCall(messageApi.downloadAttachment(messageId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the status of a conversation (e.g., OPEN to CLOSED).
|
||||
*/
|
||||
public LiveData<Resource<ConversationDTO>> updateConversationStatus(Long conversationId, UpdateConversationStatusRequest request) {
|
||||
return executeCall(chatApi.updateConversationStatus(conversationId, request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a paginated list of customers.
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.example.petstoremobile.dtos.CustomerDTO;
|
||||
import com.example.petstoremobile.dtos.MessageDTO;
|
||||
import com.example.petstoremobile.dtos.PageResponse;
|
||||
import com.example.petstoremobile.dtos.SendMessageRequest;
|
||||
import com.example.petstoremobile.dtos.UpdateConversationStatusRequest;
|
||||
import com.example.petstoremobile.models.Chat;
|
||||
import com.example.petstoremobile.models.Message;
|
||||
import com.example.petstoremobile.repositories.ChatRepository;
|
||||
@@ -126,6 +127,10 @@ public class ChatListViewModel extends ViewModel {
|
||||
return chatRepository.downloadAttachment(messageId);
|
||||
}
|
||||
|
||||
public LiveData<Resource<ConversationDTO>> closeConversation(Long conversationId) {
|
||||
return chatRepository.updateConversationStatus(conversationId, new UpdateConversationStatusRequest("CLOSED"));
|
||||
}
|
||||
|
||||
public void addMessageLocally(MessageDTO dto) {
|
||||
List<Message> current = new ArrayList<>(messageList.getValue());
|
||||
current.add(dtoToModel(dto));
|
||||
|
||||
@@ -34,8 +34,9 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvChatTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Customer Chat"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
@@ -43,6 +44,16 @@
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCloseChat"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Close Chat"
|
||||
android:textSize="12sp"
|
||||
android:backgroundTint="@color/accent_coral"
|
||||
android:textColor="@color/white"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
@@ -83,10 +83,91 @@
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="24dp">
|
||||
|
||||
<!-- BUSINESS SECTION -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="MANAGE"
|
||||
android:text="BUSINESS"
|
||||
android:textColor="@color/text_light"
|
||||
android:textSize="11sp"
|
||||
android:letterSpacing="0.15"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerAnalytics"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Analytics"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerSale"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Sales"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerAppointments"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Appointments"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerServices"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Services"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- STORE SECTION -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="STORE"
|
||||
android:textColor="@color/text_light"
|
||||
android:textSize="11sp"
|
||||
android:letterSpacing="0.15"
|
||||
@@ -112,7 +193,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerServices"
|
||||
android:id="@+id/drawerAdoptions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
@@ -123,7 +204,59 @@
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Services"
|
||||
android:text="Adoptions"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerProducts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Products"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- ADMIN SECTION -->
|
||||
<LinearLayout
|
||||
android:id="@+id/sectionAdmin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ADMIN"
|
||||
android:textColor="@color/text_light"
|
||||
android:textSize="11sp"
|
||||
android:letterSpacing="0.15"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerInventory"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Inventory"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
@@ -145,160 +278,6 @@
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerAppointments"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Appointments"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerAdoptions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Adoptions"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerInventory"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Inventory"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerProducts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Products"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerSale"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Sale"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerAnalytics"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Analytics"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerStaff"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Staff Accounts"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerPurchaseOrderView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="PurchaseOrder"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerProductSupplier"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ProductSupplier"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerCoupons"
|
||||
android:layout_width="match_parent"
|
||||
@@ -316,6 +295,58 @@
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerPurchaseOrderView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Purchase Orders"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerProductSupplier"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Product Suppliers"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/drawerStaff"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackground">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Staff Accounts"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="15sp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
Reference in New Issue
Block a user