fix open private chats
This commit is contained in:
@@ -2,7 +2,9 @@ package org.to.telegramfinalproject.Client;
|
|||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.to.telegramfinalproject.Database.PrivateChatDatabase;
|
||||||
import org.to.telegramfinalproject.Models.ChatEntry;
|
import org.to.telegramfinalproject.Models.ChatEntry;
|
||||||
|
import org.to.telegramfinalproject.Models.ContactEntry;
|
||||||
import org.to.telegramfinalproject.Models.SearchRequestModel;
|
import org.to.telegramfinalproject.Models.SearchRequestModel;
|
||||||
import org.to.telegramfinalproject.Models.SearchResultModel;
|
import org.to.telegramfinalproject.Models.SearchResultModel;
|
||||||
|
|
||||||
@@ -443,7 +445,8 @@ public class ActionHandler {
|
|||||||
|
|
||||||
JSONArray chatListJson = Session.currentUser.getJSONArray("chat_list");
|
JSONArray chatListJson = Session.currentUser.getJSONArray("chat_list");
|
||||||
JSONArray Archived = Session.currentUser.getJSONArray("archived_chat_list");
|
JSONArray Archived = Session.currentUser.getJSONArray("archived_chat_list");
|
||||||
JSONArray Active = Session.currentUser.getJSONArray("active_chat_lis");
|
JSONArray Active = Session.currentUser.getJSONArray("active_chat_list");
|
||||||
|
JSONArray contactList = Session.currentUser.getJSONArray("contact_list");
|
||||||
List<ChatEntry> chatList = new ArrayList<>();
|
List<ChatEntry> chatList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
@@ -459,9 +462,13 @@ public class ActionHandler {
|
|||||||
chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time")),
|
chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time")),
|
||||||
chat.optBoolean("is_owner", false),
|
chat.optBoolean("is_owner", false),
|
||||||
chat.optBoolean("is_admin", false)
|
chat.optBoolean("is_admin", false)
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (chat.has("other_user_id")) {
|
||||||
|
entry.setOtherUserId(UUID.fromString(chat.getString("other_user_id")));
|
||||||
|
}
|
||||||
|
|
||||||
chatList.add(entry);
|
chatList.add(entry);
|
||||||
|
|
||||||
@@ -481,6 +488,9 @@ public class ActionHandler {
|
|||||||
chat.optBoolean("is_owner", false),
|
chat.optBoolean("is_owner", false),
|
||||||
chat.optBoolean("is_admin", false)
|
chat.optBoolean("is_admin", false)
|
||||||
);
|
);
|
||||||
|
if (chat.has("other_user_id")) {
|
||||||
|
entry.setOtherUserId(UUID.fromString(chat.getString("other_user_id"))); // 👈 اضافه کردن برای private chat
|
||||||
|
}
|
||||||
archivedChats.add(entry);
|
archivedChats.add(entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -499,11 +509,28 @@ public class ActionHandler {
|
|||||||
chat.optBoolean("is_owner", false),
|
chat.optBoolean("is_owner", false),
|
||||||
chat.optBoolean("is_admin", false)
|
chat.optBoolean("is_admin", false)
|
||||||
);
|
);
|
||||||
|
if (chat.has("other_user_id")) {
|
||||||
|
entry.setOtherUserId(UUID.fromString(chat.getString("other_user_id"))); // 👈 اضافه کردن برای private chat
|
||||||
|
}
|
||||||
|
|
||||||
activeChats.add(entry);
|
activeChats.add(entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session.contactEntries.clear();
|
||||||
|
for (Object obj : contactList) {
|
||||||
|
JSONObject c = (JSONObject) obj;
|
||||||
|
|
||||||
|
ContactEntry entry = new ContactEntry(
|
||||||
|
UUID.fromString(c.getString("contact_id")),
|
||||||
|
c.getString("user_id"),
|
||||||
|
c.getString("profile_name"),
|
||||||
|
c.optString("image_url", ""),
|
||||||
|
c.optBoolean("is_blocked", false)
|
||||||
|
);
|
||||||
|
Session.contactEntries.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -751,7 +778,8 @@ public class ActionHandler {
|
|||||||
System.out.println("2. Search");
|
System.out.println("2. Search");
|
||||||
System.out.println("3. Create Channel");
|
System.out.println("3. Create Channel");
|
||||||
System.out.println("4. Create group");
|
System.out.println("4. Create group");
|
||||||
System.out.println("5. Logout");
|
System.out.println("5. View contacts");
|
||||||
|
System.out.println("6. Logout");
|
||||||
System.out.print("Choose an option: ");
|
System.out.print("Choose an option: ");
|
||||||
String choice = scanner.nextLine();
|
String choice = scanner.nextLine();
|
||||||
|
|
||||||
@@ -764,7 +792,8 @@ public class ActionHandler {
|
|||||||
case "2" -> search();
|
case "2" -> search();
|
||||||
case "3" -> createChannel();
|
case "3" -> createChannel();
|
||||||
case "4" -> createGroup();
|
case "4" -> createGroup();
|
||||||
case "5" -> {
|
case "5" -> showContactList();
|
||||||
|
case "6" -> {
|
||||||
logout();
|
logout();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -773,6 +802,109 @@ public class ActionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showContactList() {
|
||||||
|
List<ContactEntry> contacts = Session.contactEntries;
|
||||||
|
if (contacts.isEmpty()) {
|
||||||
|
System.out.println("📭 You have no contacts.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("👥 Your Contacts:");
|
||||||
|
for (int i = 0; i < contacts.size(); i++) {
|
||||||
|
System.out.println((i + 1) + ". " + contacts.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print("Select a contact (0 to go back): ");
|
||||||
|
int choice = scanner.nextInt();
|
||||||
|
scanner.nextLine();
|
||||||
|
|
||||||
|
if (choice == 0) return;
|
||||||
|
if (choice < 1 || choice > contacts.size()) {
|
||||||
|
System.out.println("❌ Invalid choice.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactEntry selected = contacts.get(choice - 1);
|
||||||
|
System.out.println("\n📇 What do you want to do with " + selected.getProfileName() + "?");
|
||||||
|
System.out.println("1. View Profile");
|
||||||
|
System.out.println("2. Send Message");
|
||||||
|
System.out.print("Enter your choice: ");
|
||||||
|
int action = scanner.nextInt();
|
||||||
|
scanner.nextLine();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 1 -> viewProfile(selected.getContactId());
|
||||||
|
case 2 -> startPrivateChat(selected);
|
||||||
|
default -> System.out.println("❌ Invalid option.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void viewProfile(UUID targetId) {
|
||||||
|
JSONObject req = new JSONObject();
|
||||||
|
req.put("action", "view_profile");
|
||||||
|
req.put("target_id", targetId.toString());
|
||||||
|
|
||||||
|
JSONObject res = sendWithResponse(req);
|
||||||
|
if (res == null || !res.getString("status").equals("success")) {
|
||||||
|
System.out.println("❌ Failed to fetch profile.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject data = res.getJSONObject("data");
|
||||||
|
String profileName = data.getString("profile_name");
|
||||||
|
String userId = data.getString("user_id");
|
||||||
|
String bio = data.optString("bio", "(no bio)");
|
||||||
|
String imageUrl = data.optString("image_url", "(no image)");
|
||||||
|
boolean isOnline = data.getBoolean("is_online");
|
||||||
|
String lastSeen = data.getString("last_seen");
|
||||||
|
|
||||||
|
System.out.println("\n📄 Profile Info:");
|
||||||
|
System.out.println("Name: " + profileName);
|
||||||
|
System.out.println("User ID: " + userId);
|
||||||
|
System.out.println("Bio: " + bio);
|
||||||
|
System.out.println("Image: " + imageUrl);
|
||||||
|
System.out.println("Status: " + (isOnline ? "🟢 Online" : "🔘 Last seen at " + lastSeen));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void startPrivateChat(ContactEntry contact) {
|
||||||
|
UUID myId = UUID.fromString(Session.currentUser.getString("internal_uuid"));
|
||||||
|
UUID contactId = contact.getContactId();
|
||||||
|
|
||||||
|
JSONObject req = new JSONObject();
|
||||||
|
req.put("action", "get_or_create_private_chat");
|
||||||
|
req.put("user1", myId.toString());
|
||||||
|
req.put("user2", contactId.toString());
|
||||||
|
|
||||||
|
JSONObject res = sendWithResponse(req);
|
||||||
|
if (res == null || !res.getString("status").equals("success")) {
|
||||||
|
System.out.println("❌ Failed to create or fetch private chat.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject data = res.getJSONObject("data");
|
||||||
|
UUID chatId = UUID.fromString(data.getString("chat_id"));
|
||||||
|
|
||||||
|
ChatEntry entry = new ChatEntry(
|
||||||
|
chatId,
|
||||||
|
contact.getUserId(),
|
||||||
|
contact.getProfileName(),
|
||||||
|
contact.getImageUrl(),
|
||||||
|
"private",
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
entry.setOtherUserId(contactId);
|
||||||
|
|
||||||
|
Session.chatList.add(0, entry); // اضافه به اول لیست
|
||||||
|
System.out.println("✅ Chat with " + contact.getProfileName() + " started.");
|
||||||
|
|
||||||
|
openChat(entry); // 👈 مستقیم وارد چت شو (اختیاری)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// public void showChatListAndSelect() {
|
// public void showChatListAndSelect() {
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -878,10 +1010,54 @@ public class ActionHandler {
|
|||||||
|
|
||||||
|
|
||||||
private void openChat(ChatEntry chat) {
|
private void openChat(ChatEntry chat) {
|
||||||
|
|
||||||
|
//for private chats only
|
||||||
|
if (chat.getType().equalsIgnoreCase("private")) {
|
||||||
|
JSONObject reqTarget = new JSONObject();
|
||||||
|
reqTarget.put("action", "get_private_chat_target");
|
||||||
|
reqTarget.put("chat_id", chat.getId());
|
||||||
|
|
||||||
|
JSONObject resTarget = sendWithResponse(reqTarget);
|
||||||
|
if (resTarget == null || !resTarget.getString("status").equals("success")) {
|
||||||
|
System.out.println("❌ Failed to fetch target user for private chat.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String otherUserId = resTarget.getJSONObject("data").getString("target_id");
|
||||||
|
chat.setOtherUserId(UUID.fromString(otherUserId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JSONObject req = new JSONObject();
|
JSONObject req = new JSONObject();
|
||||||
req.put("action", "get_messages");
|
req.put("action", "get_messages");
|
||||||
req.put("receiver_id", chat.getId());
|
req.put("receiver_id",chat.getId());
|
||||||
req.put("receiver_type", chat.getType());
|
req.put("receiver_type", chat.getType());
|
||||||
|
// String type = chat.getType();
|
||||||
|
// UUID chatId = chat.getId();
|
||||||
|
// if (type.equals("private")) {
|
||||||
|
// UUID myId = UUID.fromString(Session.currentUser.getString("internal_uuid"));
|
||||||
|
// UUID otherUserId = chat.getId();
|
||||||
|
//
|
||||||
|
// JSONObject getChatIdReq = new JSONObject();
|
||||||
|
// getChatIdReq.put("action", "get_or_create_private_chat");
|
||||||
|
// getChatIdReq.put("user1", myId.toString());
|
||||||
|
// getChatIdReq.put("user2", otherUserId.toString());
|
||||||
|
//
|
||||||
|
// JSONObject chatIdRes = sendWithResponse(getChatIdReq);
|
||||||
|
// if (chatIdRes == null || !chatIdRes.getString("status").equals("success")) {
|
||||||
|
// System.out.println("❌ Failed to fetch private chat ID.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Session.currentPrivateChatUserId = otherUserId;
|
||||||
|
// chatId = UUID.fromString(chatIdRes.getJSONObject("data").getString("chat_id"));
|
||||||
|
// chat.setId(String.valueOf(chatId));
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JSONObject res = sendWithResponse(req);
|
JSONObject res = sendWithResponse(req);
|
||||||
if (res == null || !res.getString("status").equals("success")) {
|
if (res == null || !res.getString("status").equals("success")) {
|
||||||
@@ -904,6 +1080,15 @@ public class ActionHandler {
|
|||||||
}
|
}
|
||||||
System.out.println("─────────────────────────────────────────────");
|
System.out.println("─────────────────────────────────────────────");
|
||||||
|
|
||||||
|
if (chat.getType().equals("private") && chat.getOtherUserId() == null) {
|
||||||
|
for (ContactEntry contact : Session.contactEntries) {
|
||||||
|
if (contact.getContactId().equals(chat.getId())) {
|
||||||
|
chat.setOtherUserId(contact.getContactId());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean stayInChat = true;
|
boolean stayInChat = true;
|
||||||
|
|
||||||
|
|
||||||
@@ -957,7 +1142,7 @@ public class ActionHandler {
|
|||||||
|
|
||||||
JSONObject req = new JSONObject();
|
JSONObject req = new JSONObject();
|
||||||
req.put("action", "view_profile");
|
req.put("action", "view_profile");
|
||||||
req.put("target_id", chat.getId()); // internal UUID
|
req.put("target_id", chat.getOtherUserId()); // internal UUID
|
||||||
|
|
||||||
JSONObject res = sendWithResponse(req);
|
JSONObject res = sendWithResponse(req);
|
||||||
|
|
||||||
@@ -1000,7 +1185,7 @@ public class ActionHandler {
|
|||||||
case "5" -> {
|
case "5" -> {
|
||||||
JSONObject reqProfile = new JSONObject();
|
JSONObject reqProfile = new JSONObject();
|
||||||
reqProfile.put("action", "view_profile");
|
reqProfile.put("action", "view_profile");
|
||||||
reqProfile.put("target_id", chat.getId());
|
reqProfile.put("target_id", chat.getOtherUserId());
|
||||||
|
|
||||||
JSONObject resProfile = sendWithResponse(reqProfile);
|
JSONObject resProfile = sendWithResponse(reqProfile);
|
||||||
|
|
||||||
@@ -2445,6 +2630,9 @@ public class ActionHandler {
|
|||||||
System.err.println("❌ Invalid request: missing action.");
|
System.err.println("❌ Invalid request: missing action.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
System.out.println("📤 Sending request to server: " + request.toString(2));
|
||||||
|
System.out.println("📤 [sendWithResponse] Action: " + request.optString("action", "unknown") + ", Full: " + request.toString(2));
|
||||||
|
|
||||||
|
|
||||||
String requestId = UUID.randomUUID().toString();
|
String requestId = UUID.randomUUID().toString();
|
||||||
request.put("request_id", requestId);
|
request.put("request_id", requestId);
|
||||||
@@ -2888,6 +3076,72 @@ public class ActionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public void sendMessage(UUID receiverId, String receiverType) {
|
||||||
|
// Scanner scanner = new Scanner(System.in);
|
||||||
|
//
|
||||||
|
// System.out.print("Enter your message: ");
|
||||||
|
// String content = scanner.nextLine();
|
||||||
|
//
|
||||||
|
// System.out.print("Enter message type (TEXT / IMAGE / VIDEO / FILE): ");
|
||||||
|
// String messageType = scanner.nextLine();
|
||||||
|
// Set<String> allowedTypes = Set.of("TEXT", "IMAGE", "VIDEO", "FILE");
|
||||||
|
// while (!allowedTypes.contains(messageType.toUpperCase())) {
|
||||||
|
// System.out.println("❌ Invalid message type. Try again (TEXT / IMAGE / VIDEO / FILE): ");
|
||||||
|
// messageType = scanner.nextLine();
|
||||||
|
// }
|
||||||
|
// messageType = messageType.toUpperCase();
|
||||||
|
//
|
||||||
|
// JSONArray attachmentsArray = new JSONArray();
|
||||||
|
//
|
||||||
|
// System.out.print("Do you want to attach files? (yes/no): ");
|
||||||
|
// if (scanner.nextLine().equalsIgnoreCase("yes")) {
|
||||||
|
// while (true) {
|
||||||
|
// System.out.print("File URL: ");
|
||||||
|
// String fileUrl = scanner.nextLine();
|
||||||
|
//
|
||||||
|
// System.out.print("File Type (IMAGE / VIDEO / FILE): ");
|
||||||
|
// String fileType = scanner.nextLine();
|
||||||
|
//
|
||||||
|
// JSONObject fileJson = new JSONObject();
|
||||||
|
// fileJson.put("file_url", fileUrl);
|
||||||
|
// fileJson.put("file_type", fileType);
|
||||||
|
// attachmentsArray.put(fileJson);
|
||||||
|
//
|
||||||
|
// System.out.print("Add another file? (yes/no): ");
|
||||||
|
// if (!scanner.nextLine().equalsIgnoreCase("yes")) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// JSONObject messageJson = new JSONObject();
|
||||||
|
// messageJson.put("action", "send_message");
|
||||||
|
// messageJson.put("receiver_type", receiverType);
|
||||||
|
// messageJson.put("content", content);
|
||||||
|
// messageJson.put("message_type", messageType);
|
||||||
|
// if (receiverType.equals("private")) {
|
||||||
|
// messageJson.put("receiver_user_id", receiverId.toString());
|
||||||
|
// } else {
|
||||||
|
// messageJson.put("receiver_id", receiverId.toString());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!attachmentsArray.isEmpty()) {
|
||||||
|
// messageJson.put("attachments", attachmentsArray);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// JSONObject response = sendWithResponse(messageJson);
|
||||||
|
// if (response != null && response.getString("status").equals("success")) {
|
||||||
|
// System.out.println("✅ Message sent successfully! ID: " + response.getJSONObject("data").getString("message_id"));
|
||||||
|
// } else {
|
||||||
|
// System.out.println("❌ Failed to send message: " + (response != null ? response.getString("message") : "no response"));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void sendMessage(UUID receiverId, String receiverType) {
|
public void sendMessage(UUID receiverId, String receiverType) {
|
||||||
Scanner scanner = new Scanner(System.in);
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
|
||||||
@@ -2895,40 +3149,53 @@ public class ActionHandler {
|
|||||||
String content = scanner.nextLine();
|
String content = scanner.nextLine();
|
||||||
|
|
||||||
System.out.print("Enter message type (TEXT / IMAGE / VIDEO / FILE): ");
|
System.out.print("Enter message type (TEXT / IMAGE / VIDEO / FILE): ");
|
||||||
String messageType = scanner.nextLine();
|
String messageType = scanner.nextLine().toUpperCase();
|
||||||
Set<String> allowedTypes = Set.of("TEXT", "IMAGE", "VIDEO", "FILE");
|
Set<String> allowedTypes = Set.of("TEXT", "IMAGE", "VIDEO", "FILE");
|
||||||
while (!allowedTypes.contains(messageType.toUpperCase())) {
|
while (!allowedTypes.contains(messageType)) {
|
||||||
System.out.println("❌ Invalid message type. Try again (TEXT / IMAGE / VIDEO / FILE): ");
|
System.out.print("❌ Invalid type. Try again (TEXT / IMAGE / VIDEO / FILE): ");
|
||||||
messageType = scanner.nextLine();
|
messageType = scanner.nextLine().toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray attachmentsArray = new JSONArray();
|
JSONArray attachmentsArray = new JSONArray();
|
||||||
|
|
||||||
System.out.print("Do you want to attach files? (yes/no): ");
|
System.out.print("Do you want to attach files? (yes/no): ");
|
||||||
if (scanner.nextLine().equalsIgnoreCase("yes")) {
|
if (scanner.nextLine().equalsIgnoreCase("yes")) {
|
||||||
while (true) {
|
while (true) {
|
||||||
System.out.print("File URL: ");
|
System.out.print("File URL: ");
|
||||||
String fileUrl = scanner.nextLine();
|
String fileUrl = scanner.nextLine();
|
||||||
|
|
||||||
System.out.print("File Type (IMAGE / VIDEO / FILE): ");
|
System.out.print("File Type (IMAGE / VIDEO / FILE): ");
|
||||||
String fileType = scanner.nextLine();
|
String fileType = scanner.nextLine();
|
||||||
|
|
||||||
JSONObject fileJson = new JSONObject();
|
JSONObject fileJson = new JSONObject();
|
||||||
fileJson.put("file_url", fileUrl);
|
fileJson.put("file_url", fileUrl);
|
||||||
fileJson.put("file_type", fileType);
|
fileJson.put("file_type", fileType.toUpperCase());
|
||||||
attachmentsArray.put(fileJson);
|
attachmentsArray.put(fileJson);
|
||||||
|
|
||||||
System.out.print("Add another file? (yes/no): ");
|
System.out.print("Add another file? (yes/no): ");
|
||||||
if (!scanner.nextLine().equalsIgnoreCase("yes")) {
|
if (!scanner.nextLine().equalsIgnoreCase("yes")) break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------ GET receiver_id if private ------------------------
|
||||||
|
UUID actualReceiverId = receiverId;
|
||||||
|
if (receiverType.equals("private")) {
|
||||||
|
JSONObject req = new JSONObject();
|
||||||
|
req.put("action", "get_or_create_private_chat");
|
||||||
|
req.put("user1", Session.currentPrivateChatUserId.toString());
|
||||||
|
req.put("user2", receiverId.toString());
|
||||||
|
|
||||||
|
JSONObject chatResponse = sendWithResponse(req);
|
||||||
|
if (chatResponse == null || !chatResponse.getString("status").equals("success")) {
|
||||||
|
System.out.println("❌ Failed to fetch private chat ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
actualReceiverId = UUID.fromString(chatResponse.getJSONObject("data").getString("chat_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------ SEND MESSAGE ------------------------
|
||||||
JSONObject messageJson = new JSONObject();
|
JSONObject messageJson = new JSONObject();
|
||||||
messageJson.put("action", "send_message");
|
messageJson.put("action", "send_message");
|
||||||
messageJson.put("receiver_id", receiverId.toString());
|
|
||||||
messageJson.put("receiver_type", receiverType);
|
messageJson.put("receiver_type", receiverType);
|
||||||
|
messageJson.put("receiver_id", actualReceiverId.toString());
|
||||||
messageJson.put("content", content);
|
messageJson.put("content", content);
|
||||||
messageJson.put("message_type", messageType);
|
messageJson.put("message_type", messageType);
|
||||||
|
|
||||||
@@ -2938,11 +3205,10 @@ public class ActionHandler {
|
|||||||
|
|
||||||
JSONObject response = sendWithResponse(messageJson);
|
JSONObject response = sendWithResponse(messageJson);
|
||||||
if (response != null && response.getString("status").equals("success")) {
|
if (response != null && response.getString("status").equals("success")) {
|
||||||
System.out.println("✅ Message sent successfully! ID: " + response.getJSONObject("data").getString("message_id"));
|
System.out.println("✅ Message sent! ID: " + response.getJSONObject("data").getString("message_id"));
|
||||||
} else {
|
} else {
|
||||||
System.out.println("❌ Failed to send message: " + (response != null ? response.getString("message") : "no response"));
|
System.out.println("❌ Failed to send message: " + (response != null ? response.getString("message") : "No response"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.to.telegramfinalproject.Client;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Models.ChatEntry;
|
import org.to.telegramfinalproject.Models.ChatEntry;
|
||||||
|
import org.to.telegramfinalproject.Models.ContactEntry;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -16,7 +17,7 @@ public class Session {
|
|||||||
public static List<ChatEntry> chatList = new ArrayList<>();
|
public static List<ChatEntry> chatList = new ArrayList<>();
|
||||||
public static List<ChatEntry> archivedChats = new ArrayList<>();
|
public static List<ChatEntry> archivedChats = new ArrayList<>();
|
||||||
public static List<ChatEntry> activeChats = new ArrayList<>();
|
public static List<ChatEntry> activeChats = new ArrayList<>();
|
||||||
|
public static UUID currentPrivateChatUserId = null;
|
||||||
public static volatile boolean forceRefreshChatList = false;
|
public static volatile boolean forceRefreshChatList = false;
|
||||||
public static volatile boolean backToChatList = false;
|
public static volatile boolean backToChatList = false;
|
||||||
public static boolean inChatListMenu = false;
|
public static boolean inChatListMenu = false;
|
||||||
@@ -25,7 +26,7 @@ public class Session {
|
|||||||
public static volatile boolean refreshCurrentChatMenu = false;
|
public static volatile boolean refreshCurrentChatMenu = false;
|
||||||
public static String currentChatId = null;
|
public static String currentChatId = null;
|
||||||
public static ChatEntry currentChatEntry = null;
|
public static ChatEntry currentChatEntry = null;
|
||||||
|
public static List<ContactEntry> contactEntries = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -401,4 +401,42 @@ public class MessageDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Message> getMessagesForPrivateChat(UUID user1, UUID user2) {
|
||||||
|
UUID chatId = PrivateChatDatabase.findChatIdByUsers(user1, user2);
|
||||||
|
if (chatId == null) return new ArrayList<>();
|
||||||
|
return findByReceiver("private", chatId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Message> findByReceiver(String receiverType, UUID receiverId) {
|
||||||
|
List<Message> messages = new ArrayList<>();
|
||||||
|
String sql = "SELECT * FROM messages WHERE receiver_type = ? AND receiver_id = ? ORDER BY send_at";
|
||||||
|
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
ps.setString(1, receiverType);
|
||||||
|
ps.setObject(2, receiverId);
|
||||||
|
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
UUID messageId = (UUID) rs.getObject("message_id");
|
||||||
|
UUID senderId = (UUID) rs.getObject("sender_id");
|
||||||
|
UUID recId = (UUID) rs.getObject("receiver_id");
|
||||||
|
String type = rs.getString("receiver_type");
|
||||||
|
String content = rs.getString("content");
|
||||||
|
String messageType = rs.getString("message_type");
|
||||||
|
LocalDateTime sendAt = rs.getTimestamp("send_at").toLocalDateTime();
|
||||||
|
|
||||||
|
Message message = new Message(messageId, senderId, recId, type, content, messageType, sendAt);
|
||||||
|
messages.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.to.telegramfinalproject.Database;
|
package org.to.telegramfinalproject.Database;
|
||||||
|
|
||||||
|
import org.to.telegramfinalproject.Models.PrivateChat;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -13,15 +16,15 @@ public class PrivateChatDatabase {
|
|||||||
|
|
||||||
|
|
||||||
public static List<UUID> getMembers(UUID privateChatId) {
|
public static List<UUID> getMembers(UUID privateChatId) {
|
||||||
String sql = "SELECT user1, user2 FROM private_chats WHERE chat_id = ?";
|
String sql = "SELECT user1_id, user2_id FROM private_chat WHERE chat_id = ?";
|
||||||
try (Connection conn = ConnectionDb.connect();
|
try (Connection conn = ConnectionDb.connect();
|
||||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
ps.setObject(1, privateChatId);
|
ps.setObject(1, privateChatId);
|
||||||
ResultSet rs = ps.executeQuery();
|
ResultSet rs = ps.executeQuery();
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
UUID user1 = (UUID) rs.getObject("user1");
|
UUID user1 = (UUID) rs.getObject("user1_id");
|
||||||
UUID user2 = (UUID) rs.getObject("user2");
|
UUID user2 = (UUID) rs.getObject("user2_id");
|
||||||
return Arrays.asList(user1, user2);
|
return new ArrayList<>(Arrays.asList(user1, user2));
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -29,4 +32,105 @@ public class PrivateChatDatabase {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID findChatIdByUsers(UUID user1, UUID user2) {
|
||||||
|
UUID u1 = user1.compareTo(user2) < 0 ? user1 : user2;
|
||||||
|
UUID u2 = user1.compareTo(user2) < 0 ? user2 : user1;
|
||||||
|
|
||||||
|
String sql = "SELECT chat_id FROM private_chat WHERE user1_id = ? AND user2_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
ps.setObject(1, u1);
|
||||||
|
ps.setObject(2, u2);
|
||||||
|
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return (UUID) rs.getObject("chat_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID getOrCreateChat(UUID user1, UUID user2) {
|
||||||
|
UUID u1 = user1.compareTo(user2) < 0 ? user1 : user2;
|
||||||
|
UUID u2 = user1.compareTo(user2) < 0 ? user2 : user1;
|
||||||
|
|
||||||
|
String select = "SELECT chat_id FROM private_chat WHERE user1_id = ? AND user2_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(select)) {
|
||||||
|
ps.setObject(1, u1);
|
||||||
|
ps.setObject(2, u2);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return UUID.fromString(rs.getString("chat_id"));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID newChatId = UUID.randomUUID();
|
||||||
|
String insert = "INSERT INTO private_chat(chat_id, user1_id, user2_id) VALUES (?, ?, ?)";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(insert)) {
|
||||||
|
ps.setObject(1, newChatId);
|
||||||
|
ps.setObject(2, u1);
|
||||||
|
ps.setObject(3, u2);
|
||||||
|
ps.executeUpdate();
|
||||||
|
return newChatId;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<PrivateChat> findChatsOfUser(UUID userId) {
|
||||||
|
List<PrivateChat> chats = new ArrayList<>();
|
||||||
|
String sql = "SELECT * FROM private_chat WHERE user1_id = ? OR user2_id = ?";
|
||||||
|
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
ps.setObject(1, userId);
|
||||||
|
ps.setObject(2, userId);
|
||||||
|
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
UUID chatId = (UUID) rs.getObject("chat_id");
|
||||||
|
UUID user1 = (UUID) rs.getObject("user1_id");
|
||||||
|
UUID user2 = (UUID) rs.getObject("user2_id");
|
||||||
|
|
||||||
|
chats.add(new PrivateChat(chatId, user1, user2));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return chats;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static UUID getOtherUserInChat(UUID chatId, UUID currentUserId) {
|
||||||
|
String sql = "SELECT user1_id, user2_id FROM private_chat WHERE chat_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
|
ps.setObject(1, chatId);
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
UUID user1 = (UUID) rs.getObject("user1_id");
|
||||||
|
UUID user2 = (UUID) rs.getObject("user2_id");
|
||||||
|
return currentUserId.equals(user1) ? user2 : user1;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class ChatEntry {
|
|||||||
private String type;
|
private String type;
|
||||||
private LocalDateTime lastMessageTime;
|
private LocalDateTime lastMessageTime;
|
||||||
private boolean archived = false;
|
private boolean archived = false;
|
||||||
|
private UUID otherUser;
|
||||||
|
|
||||||
|
|
||||||
private boolean isOwner = false;
|
private boolean isOwner = false;
|
||||||
@@ -133,4 +134,10 @@ public class ChatEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOtherUserId(UUID otherId) {this.otherUser = otherId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getOtherUserId(){
|
||||||
|
return otherUser;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.to.telegramfinalproject.Models;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ContactEntry {
|
||||||
|
private UUID contactId; // internal UUID
|
||||||
|
private String userId; // public ID
|
||||||
|
private String profileName;
|
||||||
|
private String imageUrl;
|
||||||
|
private boolean isBlocked;
|
||||||
|
|
||||||
|
public ContactEntry(UUID contactId, String userId, String profileName, String imageUrl, boolean isBlocked) {
|
||||||
|
this.contactId = contactId;
|
||||||
|
this.userId = userId;
|
||||||
|
this.profileName = profileName;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
this.isBlocked = isBlocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getContactId() {
|
||||||
|
return contactId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProfileName() {
|
||||||
|
return profileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImageUrl() {
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlocked() {
|
||||||
|
return isBlocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return profileName + " (" + userId + ")" + (isBlocked ? " [Blocked]" : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ public class PrivateChat {
|
|||||||
private UUID user2_id;
|
private UUID user2_id;
|
||||||
private LocalDateTime created_at;
|
private LocalDateTime created_at;
|
||||||
|
|
||||||
public PrivateChat(UUID chat_id, UUID user1_id, UUID user2_id, LocalDateTime created_at){
|
public PrivateChat(UUID chat_id, UUID user1_id, UUID user2_id){
|
||||||
this.chat_id = chat_id;
|
this.chat_id = chat_id;
|
||||||
this.user1_id =user1_id;
|
this.user1_id =user1_id;
|
||||||
this.user2_id =user2_id;
|
this.user2_id =user2_id;
|
||||||
|
|||||||
@@ -103,38 +103,84 @@ public class ClientHandler implements Runnable {
|
|||||||
List<ChatEntry> activeChatList = new ArrayList<>();
|
List<ChatEntry> activeChatList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
JSONArray contactList = new JSONArray();
|
||||||
for (Contact contact : contacts) {
|
for (Contact contact : contacts) {
|
||||||
User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
||||||
if (target == null) continue;
|
if (target == null) continue;
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
|
|
||||||
|
|
||||||
// chatList.add(new ChatEntry(
|
JSONObject c = new JSONObject();
|
||||||
// target.getInternal_uuid(), // internal UUID
|
c.put("user_id", contact.getUser_id().toString());
|
||||||
// target.getUser_id(), // public display ID
|
c.put("contact_id", contact.getContact_id().toString());
|
||||||
|
c.put("is_blocked", contact.getIs_blocked());
|
||||||
|
|
||||||
|
c.put("profile_name", target.getProfile_name());
|
||||||
|
c.put("image_url", target.getImage_url());
|
||||||
|
|
||||||
|
contactList.put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// for (Contact contact : contacts) {
|
||||||
|
// User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
||||||
|
// if (target == null) continue;
|
||||||
|
// LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
|
||||||
|
//
|
||||||
|
//// chatList.add(new ChatEntry(
|
||||||
|
//// target.getInternal_uuid(), // internal UUID
|
||||||
|
//// target.getUser_id(), // public display ID
|
||||||
|
//// target.getProfile_name(),
|
||||||
|
//// target.getImage_url(),
|
||||||
|
//// "private",
|
||||||
|
//// last,
|
||||||
|
//// false,
|
||||||
|
//// false
|
||||||
|
//// ));
|
||||||
|
//
|
||||||
|
// UUID targetId = target.getInternal_uuid();
|
||||||
|
//
|
||||||
|
// ChatEntry entry = new ChatEntry(
|
||||||
|
// targetId,
|
||||||
|
// target.getUser_id(),
|
||||||
// target.getProfile_name(),
|
// target.getProfile_name(),
|
||||||
// target.getImage_url(),
|
// target.getImage_url(),
|
||||||
// "private",
|
// "private",
|
||||||
// last,
|
// last,
|
||||||
// false,
|
// false,
|
||||||
// false
|
// false
|
||||||
// ));
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
UUID targetId = target.getInternal_uuid();
|
|
||||||
|
|
||||||
|
List<PrivateChat> privateChats = PrivateChatDatabase.findChatsOfUser(currentUser.getInternal_uuid());
|
||||||
|
for (PrivateChat chat : privateChats) {
|
||||||
|
UUID otherId = chat.getUser1_id().equals(currentUser.getInternal_uuid()) ?
|
||||||
|
chat.getUser2_id() : chat.getUser1_id();
|
||||||
|
|
||||||
|
User otherUser = userDatabase.findByInternalUUID(otherId);
|
||||||
|
if (otherUser == null) continue;
|
||||||
|
|
||||||
|
LocalDateTime lastMessageTime = MessageDatabase.getLastMessageTimeBetween(
|
||||||
|
currentUser.getInternal_uuid(), otherId, "private"
|
||||||
|
);
|
||||||
|
|
||||||
ChatEntry entry = new ChatEntry(
|
ChatEntry entry = new ChatEntry(
|
||||||
targetId,
|
chat.getChat_id(), // 🔹 real private chat_id
|
||||||
target.getUser_id(),
|
otherUser.getUser_id(), // نمایش عمومی طرف مقابل
|
||||||
target.getProfile_name(),
|
otherUser.getProfile_name(),
|
||||||
target.getImage_url(),
|
otherUser.getImage_url(),
|
||||||
"private",
|
"private",
|
||||||
last,
|
lastMessageTime,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
entry.setOtherUserId(otherId);
|
||||||
|
|
||||||
|
if (archivedChatIds.contains(chat.getChat_id())) {
|
||||||
|
|
||||||
if (archivedChatIds.contains(targetId)) {
|
|
||||||
archivedChatList.add(entry);
|
archivedChatList.add(entry);
|
||||||
chatList.add(entry);
|
chatList.add(entry);
|
||||||
} else {
|
} else {
|
||||||
@@ -144,6 +190,7 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (Group group : groups) {
|
for (Group group : groups) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
||||||
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), user.getInternal_uuid());
|
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), user.getInternal_uuid());
|
||||||
@@ -240,7 +287,8 @@ public class ClientHandler implements Runnable {
|
|||||||
JSONObject userData = JsonUtil.userToJson(user);
|
JSONObject userData = JsonUtil.userToJson(user);
|
||||||
userData.put("chat_list", JsonUtil.chatListToJson(chatList));
|
userData.put("chat_list", JsonUtil.chatListToJson(chatList));
|
||||||
userData.put("archived_chat_list", JsonUtil.chatListToJson(archivedChatList));
|
userData.put("archived_chat_list", JsonUtil.chatListToJson(archivedChatList));
|
||||||
userData.put("active_chat_lis", JsonUtil.chatListToJson(activeChatList));
|
userData.put("active_chat_list", JsonUtil.chatListToJson(activeChatList));
|
||||||
|
userData.put("contact_list", contactList);
|
||||||
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
|
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -605,33 +653,86 @@ public class ClientHandler implements Runnable {
|
|||||||
List<Contact> contacts = ContactDatabase.getContacts(currentUser.getInternal_uuid());
|
List<Contact> contacts = ContactDatabase.getContacts(currentUser.getInternal_uuid());
|
||||||
List<Group> groups = GroupDatabase.getGroupsByUser(currentUser.getInternal_uuid());
|
List<Group> groups = GroupDatabase.getGroupsByUser(currentUser.getInternal_uuid());
|
||||||
List<Channel> channels = ChannelDatabase.getChannelsByUser(currentUser.getInternal_uuid());
|
List<Channel> channels = ChannelDatabase.getChannelsByUser(currentUser.getInternal_uuid());
|
||||||
|
List<UUID> archivedChatIds = ArchivedChatDatabase.getArchivedChats(currentUser.getInternal_uuid());
|
||||||
List<ChatEntry> chatList = new ArrayList<>();
|
List<ChatEntry> chatList = new ArrayList<>();
|
||||||
|
List<ChatEntry> archivedChatList = new ArrayList<>();
|
||||||
|
List<ChatEntry> activeChatList = new ArrayList<>();
|
||||||
|
|
||||||
for (Contact contact : contacts) {
|
|
||||||
User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
|
||||||
if (target == null) continue;
|
|
||||||
|
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(currentUser.getInternal_uuid(), target.getInternal_uuid(), "private");
|
|
||||||
|
|
||||||
chatList.add(new ChatEntry(
|
|
||||||
target.getInternal_uuid(),
|
|
||||||
target.getUser_id(),
|
|
||||||
target.getProfile_name(),
|
// for (Contact contact : contacts) {
|
||||||
target.getImage_url(),
|
// User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
||||||
|
// if (target == null) continue;
|
||||||
|
//
|
||||||
|
// LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(currentUser.getInternal_uuid(), target.getInternal_uuid(), "private");
|
||||||
|
//
|
||||||
|
// chatList.add(new ChatEntry(
|
||||||
|
// target.getInternal_uuid(),
|
||||||
|
// target.getUser_id(),
|
||||||
|
// target.getProfile_name(),
|
||||||
|
// target.getImage_url(),
|
||||||
|
// "private",
|
||||||
|
// last,
|
||||||
|
// false,
|
||||||
|
// false
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
List<PrivateChat> privateChats = PrivateChatDatabase.findChatsOfUser(currentUser.getInternal_uuid());
|
||||||
|
for (PrivateChat chat : privateChats) {
|
||||||
|
UUID otherId = chat.getUser1_id().equals(currentUser.getInternal_uuid()) ?
|
||||||
|
chat.getUser2_id() : chat.getUser1_id();
|
||||||
|
|
||||||
|
User otherUser = userDatabase.findByInternalUUID(otherId);
|
||||||
|
if (otherUser == null) continue;
|
||||||
|
|
||||||
|
LocalDateTime lastMessageTime = MessageDatabase.getLastMessageTimeBetween(
|
||||||
|
currentUser.getInternal_uuid(), otherId, "private"
|
||||||
|
);
|
||||||
|
|
||||||
|
ChatEntry entry = new ChatEntry(
|
||||||
|
chat.getChat_id(), // 🔹 real private chat_id
|
||||||
|
otherUser.getUser_id(), // نمایش عمومی طرف مقابل
|
||||||
|
otherUser.getProfile_name(),
|
||||||
|
otherUser.getImage_url(),
|
||||||
"private",
|
"private",
|
||||||
last,
|
lastMessageTime,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
));
|
);
|
||||||
|
entry.setOtherUserId(otherId);
|
||||||
|
|
||||||
|
if (archivedChatIds.contains(chat.getChat_id())) {
|
||||||
|
archivedChatList.add(entry);
|
||||||
|
chatList.add(entry);
|
||||||
|
} else {
|
||||||
|
activeChatList.add(entry);
|
||||||
|
chatList.add(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (Group group : groups) {
|
for (Group group : groups) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
||||||
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), currentUser.getInternal_uuid());
|
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), currentUser.getInternal_uuid());
|
||||||
boolean isAdmin = GroupDatabase.isAdmin(group.getInternal_uuid(), currentUser.getInternal_uuid());
|
boolean isAdmin = GroupDatabase.isAdmin(group.getInternal_uuid(), currentUser.getInternal_uuid());
|
||||||
|
|
||||||
chatList.add(new ChatEntry(
|
// chatList.add(new ChatEntry(
|
||||||
|
// group.getInternal_uuid(),
|
||||||
|
// group.getGroup_id(),
|
||||||
|
// group.getGroup_name(),
|
||||||
|
// group.getImage_url(),
|
||||||
|
// "group",
|
||||||
|
// last,
|
||||||
|
// isOwner,
|
||||||
|
// isAdmin
|
||||||
|
// ));
|
||||||
|
|
||||||
|
ChatEntry entry = new ChatEntry(
|
||||||
group.getInternal_uuid(),
|
group.getInternal_uuid(),
|
||||||
group.getGroup_id(),
|
group.getGroup_id(),
|
||||||
group.getGroup_name(),
|
group.getGroup_name(),
|
||||||
@@ -640,7 +741,17 @@ public class ClientHandler implements Runnable {
|
|||||||
last,
|
last,
|
||||||
isOwner,
|
isOwner,
|
||||||
isAdmin
|
isAdmin
|
||||||
));
|
);
|
||||||
|
|
||||||
|
if (archivedChatIds.contains(group.getInternal_uuid())) {
|
||||||
|
archivedChatList.add(entry);
|
||||||
|
chatList.add(entry);
|
||||||
|
} else {
|
||||||
|
activeChatList.add(entry);
|
||||||
|
chatList.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Channel channel : channels) {
|
for (Channel channel : channels) {
|
||||||
@@ -648,7 +759,18 @@ public class ClientHandler implements Runnable {
|
|||||||
boolean isOwner = ChannelDatabase.isOwner(channel.getInternal_uuid(), currentUser.getInternal_uuid());
|
boolean isOwner = ChannelDatabase.isOwner(channel.getInternal_uuid(), currentUser.getInternal_uuid());
|
||||||
boolean isAdmin = ChannelDatabase.isAdmin(channel.getInternal_uuid(), currentUser.getInternal_uuid());
|
boolean isAdmin = ChannelDatabase.isAdmin(channel.getInternal_uuid(), currentUser.getInternal_uuid());
|
||||||
|
|
||||||
chatList.add(new ChatEntry(
|
// chatList.add(new ChatEntry(
|
||||||
|
// channel.getInternal_uuid(),
|
||||||
|
// channel.getChannel_id(),
|
||||||
|
// channel.getChannel_name(),
|
||||||
|
// channel.getImage_url(),
|
||||||
|
// "channel",
|
||||||
|
// last,
|
||||||
|
// isOwner,
|
||||||
|
// isAdmin
|
||||||
|
// ));
|
||||||
|
|
||||||
|
ChatEntry entry = new ChatEntry(
|
||||||
channel.getInternal_uuid(),
|
channel.getInternal_uuid(),
|
||||||
channel.getChannel_id(),
|
channel.getChannel_id(),
|
||||||
channel.getChannel_name(),
|
channel.getChannel_name(),
|
||||||
@@ -657,17 +779,39 @@ public class ClientHandler implements Runnable {
|
|||||||
last,
|
last,
|
||||||
isOwner,
|
isOwner,
|
||||||
isAdmin
|
isAdmin
|
||||||
));
|
);
|
||||||
|
|
||||||
|
if (archivedChatIds.contains(channel.getInternal_uuid())) {
|
||||||
|
archivedChatList.add(entry);
|
||||||
|
chatList.add(entry);
|
||||||
|
} else {
|
||||||
|
activeChatList.add(entry);
|
||||||
|
chatList.add(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeChatList.sort((a, b) -> {
|
||||||
|
if (a.getLastMessageTime() == null) return 1;
|
||||||
|
if (b.getLastMessageTime() == null) return -1;
|
||||||
|
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
||||||
|
});
|
||||||
|
|
||||||
|
archivedChatList.sort((a, b) -> {
|
||||||
|
if (a.getLastMessageTime() == null) return 1;
|
||||||
|
if (b.getLastMessageTime() == null) return -1;
|
||||||
|
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
chatList.sort((a, b) -> {
|
chatList.sort((a, b) -> {
|
||||||
if (a.getLastMessageTime() == null) return 1;
|
if (a.getLastMessageTime() == null) return 1;
|
||||||
if (b.getLastMessageTime() == null) return -1;
|
if (b.getLastMessageTime() == null) return -1;
|
||||||
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
||||||
});
|
});
|
||||||
|
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("chat_list", JsonUtil.chatListToJson(chatList));
|
data.put("chat_list", JsonUtil.chatListToJson(chatList));
|
||||||
|
data.put("archived_chat_list", JsonUtil.chatListToJson(archivedChatList));
|
||||||
|
data.put("active_chat_list", JsonUtil.chatListToJson(activeChatList));
|
||||||
response = new ResponseModel("success", "Chat list updated.", data);
|
response = new ResponseModel("success", "Chat list updated.", data);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1116,13 +1260,16 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
switch (receiverType) {
|
switch (receiverType) {
|
||||||
case "private" -> {
|
case "private" -> {
|
||||||
User otherUser = new userDatabase().findByInternalUUID(UUID.fromString(receiverId));
|
List<UUID> members = PrivateChatDatabase.getMembers(UUID.fromString(receiverId));
|
||||||
if (otherUser == null) {
|
if (members.size() != 2) {
|
||||||
response = new ResponseModel("error", "User not found.");
|
response = new ResponseModel("error", "Invalid private chat.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
messages = MessageDatabase.privateChatHistory(currentUser.getInternal_uuid(), otherUser.getInternal_uuid());
|
|
||||||
|
UUID otherUserId = members.get(0).equals(currentUser.getInternal_uuid()) ? members.get(1) : members.get(0);
|
||||||
|
messages = MessageDatabase.privateChatHistory(currentUser.getInternal_uuid(), otherUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
case "group" -> {
|
case "group" -> {
|
||||||
Group group = GroupDatabase.findByInternalUUID(UUID.fromString(receiverId));
|
Group group = GroupDatabase.findByInternalUUID(UUID.fromString(receiverId));
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
@@ -1836,6 +1983,45 @@ public class ClientHandler implements Runnable {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case "get_or_create_private_chat": {
|
||||||
|
if (currentUser == null) {
|
||||||
|
response = new ResponseModel("error", "Unauthorized. Please login first.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
UUID user1 = UUID.fromString(requestJson.getString("user1"));
|
||||||
|
UUID user2 = UUID.fromString(requestJson.getString("user2"));
|
||||||
|
|
||||||
|
UUID chatId = PrivateChatDatabase.getOrCreateChat(user1, user2);
|
||||||
|
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("chat_id", chatId.toString());
|
||||||
|
response = new ResponseModel("success", "Private chat ID retrieved.", data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
response = new ResponseModel("error", "Invalid data or internal error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "get_private_chat_target": {
|
||||||
|
UUID chatId = UUID.fromString(requestJson.getString("chat_id"));
|
||||||
|
userId = currentUser.getInternal_uuid();
|
||||||
|
|
||||||
|
UUID targetId = PrivateChatDatabase.getOtherUserInChat(chatId, userId);
|
||||||
|
if (targetId == null) {
|
||||||
|
response = new ResponseModel("error", "Could not find other user.");
|
||||||
|
} else {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("target_id", targetId.toString());
|
||||||
|
response = new ResponseModel("success", "Target fetched.", data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1904,8 +2090,15 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
UUID messageId = UUID.randomUUID();
|
UUID messageId = UUID.randomUUID();
|
||||||
UUID senderId = currentUser.getInternal_uuid();
|
UUID senderId = currentUser.getInternal_uuid();
|
||||||
UUID receiverId = UUID.fromString(json.getString("receiver_id"));
|
|
||||||
String receiverType = json.getString("receiver_type");
|
String receiverType = json.getString("receiver_type");
|
||||||
|
UUID receiverId;
|
||||||
|
|
||||||
|
if (receiverType.equals("private")) {
|
||||||
|
UUID receiverUserId = UUID.fromString(json.getString("receiver_user_id"));
|
||||||
|
receiverId = PrivateChatDatabase.getOrCreateChat(senderId, receiverUserId);
|
||||||
|
} else {
|
||||||
|
receiverId = UUID.fromString(json.getString("receiver_id")); // group یا channel
|
||||||
|
}
|
||||||
String content = json.optString("content", "");
|
String content = json.optString("content", "");
|
||||||
String messageType = json.optString("message_type", "TEXT");
|
String messageType = json.optString("message_type", "TEXT");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user