update contact list
This commit is contained in:
@@ -2959,7 +2959,7 @@ public class ActionHandler {
|
||||
}
|
||||
case "2" -> {
|
||||
addContact(chat.getId());
|
||||
refreshChatList();
|
||||
refreshContactList();
|
||||
}
|
||||
default -> System.out.println("Back...");
|
||||
}
|
||||
@@ -3213,6 +3213,59 @@ public class ActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshContactList() {
|
||||
JSONObject req = new JSONObject();
|
||||
req.put("action", "get_contact_list");
|
||||
req.put("user_id", Session.currentUser.getString("user_id"));
|
||||
out.println(req.toString());
|
||||
|
||||
try {
|
||||
JSONObject response = TelegramClient.responseQueue.take();
|
||||
|
||||
if (response != null && response.getString("status").equals("success")) {
|
||||
if (response.has("data") && !response.isNull("data")) {
|
||||
JSONObject data = response.getJSONObject("data");
|
||||
|
||||
if (!data.has("contact_list") || data.isNull("contact_list")) {
|
||||
System.out.println("❌ contact_list not found in response data.");
|
||||
return;
|
||||
}
|
||||
|
||||
JSONArray contactListJson = data.getJSONArray("contact_list");
|
||||
List<ContactEntry> contactList = new ArrayList<>();
|
||||
|
||||
for (Object obj : contactListJson) {
|
||||
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)
|
||||
);
|
||||
|
||||
contactList.add(entry);
|
||||
}
|
||||
|
||||
Session.contactEntries = contactList;
|
||||
System.out.println("✅ Contact list updated. Total: " + contactList.size());
|
||||
|
||||
} else {
|
||||
System.out.println("⚠️ Response has no data object.");
|
||||
}
|
||||
} else {
|
||||
if (response.has("message") && !response.isNull("message")) {
|
||||
System.out.println("❌ Failed to refresh contact list: " + response.getString("message"));
|
||||
} else {
|
||||
System.out.println("❌ Failed to refresh contact list.");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("❌ Error during refreshContactList: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -79,19 +79,19 @@ public class IncomingMessageListener implements Runnable {
|
||||
"update_group_or_channel", "chat_deleted",
|
||||
"blocked_by_user", "unblocked_by_user", "message_seen",
|
||||
"removed_from_group", "removed_from_channel",
|
||||
"became_admin", "removed_admin", "ownership_transferred","admin_permissions_updated" -> true;
|
||||
"became_admin", "removed_admin", "ownership_transferred","admin_permissions_updated","created_private_chat" -> true;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
void handleRealTimeEvent(JSONObject response) throws IOException {
|
||||
String action = response.getString("action");
|
||||
JSONObject msg = response.getJSONObject("data");
|
||||
JSONObject msg = response.has("data") ? response.getJSONObject("data") : new JSONObject();
|
||||
|
||||
|
||||
switch (action) {
|
||||
case "added_to_group", "added_to_channel",
|
||||
"removed_from_group", "removed_from_channel", "chat_deleted" -> {
|
||||
"removed_from_group", "removed_from_channel", "chat_deleted","created_private_chat" -> {
|
||||
System.out.println("🔄 Chat list changed. Updating...");
|
||||
Session.forceRefreshChatList = true;
|
||||
System.out.println("🧪 Calling requestChatList() after being added");
|
||||
@@ -135,10 +135,6 @@ public class IncomingMessageListener implements Runnable {
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
||||
default -> displayRealTimeMessage(action, msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ public class Session {
|
||||
public static String currentChatId = null;
|
||||
public static ChatEntry currentChatEntry = null;
|
||||
public static List<ContactEntry> contactEntries = new ArrayList<>();
|
||||
|
||||
|
||||
public static boolean inContactListMenu = false;
|
||||
|
||||
|
||||
public static String getUserUUID() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.Contact;
|
||||
import org.to.telegramfinalproject.Models.ContactEntry;
|
||||
import org.to.telegramfinalproject.Models.User;
|
||||
|
||||
import java.sql.*;
|
||||
@@ -268,5 +269,39 @@ public class ContactDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<ContactEntry> getContactEntries(UUID userId) {
|
||||
List<ContactEntry> entries = new ArrayList<>();
|
||||
|
||||
String sql = """
|
||||
SELECT c.contact_id, c.is_blocked, u.user_id, u.profile_name, u.image_url
|
||||
FROM contacts c
|
||||
JOIN users u ON c.contact_id = u.internal_uuid
|
||||
WHERE c.user_id = ?
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, userId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
UUID contactId = UUID.fromString(rs.getString("contact_id"));
|
||||
boolean isBlocked = rs.getBoolean("is_blocked");
|
||||
String userIdStr = rs.getString("user_id");
|
||||
String profileName = rs.getString("profile_name");
|
||||
String imageUrl = rs.getString("image_url");
|
||||
|
||||
ContactEntry entry = new ContactEntry(contactId, userIdStr, profileName, imageUrl, isBlocked);
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class MessageDatabase {
|
||||
}
|
||||
|
||||
public static void logDeletedMessagesFor(UUID chatId, UUID userId) {
|
||||
List<Message> messages = MessageDatabase.privateChatHistory(chatId);
|
||||
List<Message> messages = MessageDatabase.privateChatHistory(chatId, userId);
|
||||
for (Message message : messages) {
|
||||
if (!isMessageDeleted(message.getMessage_id(), userId)) {
|
||||
String sql = """
|
||||
@@ -306,18 +306,45 @@ public class MessageDatabase {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Message> privateChatHistory(UUID chatId) {
|
||||
// public static List<Message> privateChatHistory(UUID chatId) {
|
||||
// List<Message> result = new ArrayList<>();
|
||||
// String sql = """
|
||||
// SELECT * FROM messages
|
||||
// WHERE receiver_type = 'private'
|
||||
// AND receiver_id = ?
|
||||
// ORDER BY send_at
|
||||
// """;
|
||||
//
|
||||
// try (Connection conn = ConnectionDb.connect();
|
||||
// PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
// stmt.setObject(1, chatId);
|
||||
// ResultSet rs = stmt.executeQuery();
|
||||
// while (rs.next()) {
|
||||
// result.add(extractMessage(rs));
|
||||
// }
|
||||
// } catch (SQLException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public static List<Message> privateChatHistory(UUID chatId, UUID userId) {
|
||||
List<Message> result = new ArrayList<>();
|
||||
String sql = """
|
||||
SELECT * FROM messages
|
||||
WHERE receiver_type = 'private'
|
||||
AND receiver_id = ?
|
||||
AND receiver_id = ?
|
||||
AND is_deleted_globally = FALSE
|
||||
AND message_id NOT IN (
|
||||
SELECT message_id FROM deleted_messages WHERE user_id = ?
|
||||
)
|
||||
ORDER BY send_at
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setObject(1, chatId);
|
||||
stmt.setObject(2, userId);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
result.add(extractMessage(rs));
|
||||
@@ -331,11 +358,39 @@ public class MessageDatabase {
|
||||
|
||||
|
||||
|
||||
public static List<Message> groupChatHistory(UUID groupId) {
|
||||
|
||||
// public static List<Message> groupChatHistory(UUID groupId) {
|
||||
// List<Message> result = new ArrayList<>();
|
||||
// String sql = """
|
||||
// SELECT * FROM messages
|
||||
// WHERE receiver_type = 'group' AND receiver_id = ?
|
||||
// ORDER BY send_at
|
||||
// """;
|
||||
//
|
||||
// try (Connection conn = ConnectionDb.connect();
|
||||
// PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
// stmt.setObject(1, groupId);
|
||||
// ResultSet rs = stmt.executeQuery();
|
||||
// while (rs.next()) {
|
||||
// result.add(extractMessage(rs));
|
||||
// }
|
||||
// } catch (SQLException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
|
||||
public static List<Message> groupChatHistory(UUID groupId,UUID userId) {
|
||||
List<Message> result = new ArrayList<>();
|
||||
String sql = """
|
||||
SELECT * FROM messages
|
||||
WHERE receiver_type = 'group' AND receiver_id = ?
|
||||
WHERE receiver_type = 'group'
|
||||
AND receiver_id = ?
|
||||
AND is_deleted_globally = FALSE
|
||||
AND message_id NOT IN (
|
||||
SELECT message_id FROM deleted_messages WHERE user_id = ?
|
||||
)
|
||||
ORDER BY send_at
|
||||
""";
|
||||
|
||||
@@ -353,11 +408,39 @@ public class MessageDatabase {
|
||||
}
|
||||
|
||||
|
||||
public static List<Message> channelChatHistory(UUID channelId) {
|
||||
|
||||
// public static List<Message> channelChatHistory(UUID channelId) {
|
||||
// List<Message> result = new ArrayList<>();
|
||||
// String sql = """
|
||||
// SELECT * FROM messages
|
||||
// WHERE receiver_type = 'channel' AND receiver_id = ?
|
||||
// ORDER BY send_at
|
||||
// """;
|
||||
//
|
||||
// try (Connection conn = ConnectionDb.connect();
|
||||
// PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
// stmt.setObject(1, channelId);
|
||||
// ResultSet rs = stmt.executeQuery();
|
||||
// while (rs.next()) {
|
||||
// result.add(extractMessage(rs));
|
||||
// }
|
||||
// } catch (SQLException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
|
||||
public static List<Message> channelChatHistory(UUID channelId,UUID userId) {
|
||||
List<Message> result = new ArrayList<>();
|
||||
String sql = """
|
||||
SELECT * FROM messages
|
||||
WHERE receiver_type = 'channel' AND receiver_id = ?
|
||||
WHERE receiver_type = 'channel'
|
||||
AND receiver_id = ?
|
||||
AND is_deleted_globally = FALSE
|
||||
AND message_id NOT IN (
|
||||
SELECT message_id FROM deleted_messages WHERE user_id = ?
|
||||
)
|
||||
ORDER BY send_at
|
||||
""";
|
||||
|
||||
@@ -375,6 +458,7 @@ public class MessageDatabase {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<Message> searchMessagesInGroups(List<UUID> groupIds, String keyword) {
|
||||
List<Message> result = new ArrayList<>();
|
||||
if (groupIds.isEmpty()) return result;
|
||||
|
||||
@@ -251,7 +251,28 @@ public class PrivateChatDatabase {
|
||||
}
|
||||
|
||||
|
||||
public static UUID findChatBetween(UUID user1, UUID user2) {
|
||||
String sql = """
|
||||
SELECT chat_id FROM private_chat
|
||||
WHERE (user1_id = ? AND user2_id = ?) OR (user1_id = ? AND user2_id = ?)
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, user1);
|
||||
ps.setObject(2, user2);
|
||||
ps.setObject(3, user2);
|
||||
ps.setObject(4, user1);
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (rs.next()) {
|
||||
return (UUID) rs.getObject("chat_id");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,5 +40,4 @@ public class Contact {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ContactEntry {
|
||||
@@ -41,4 +43,16 @@ public class ContactEntry {
|
||||
public String toString() {
|
||||
return profileName + " (" + userId + ")" + (isBlocked ? " [Blocked]" : "");
|
||||
}
|
||||
|
||||
|
||||
public JSONObject toJson() {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("contact_id", contactId.toString());
|
||||
obj.put("user_id", userId);
|
||||
obj.put("profile_name", profileName);
|
||||
obj.put("image_url", imageUrl);
|
||||
obj.put("is_blocked", isBlocked);
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.to.telegramfinalproject.Models;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.to.telegramfinalproject.Database.userDatabase;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
@@ -9,20 +10,43 @@ import java.util.UUID;
|
||||
|
||||
public class JsonUtil {
|
||||
public static JSONArray contactListToJson(List<Contact> contacts) {
|
||||
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
|
||||
for (Contact contact : contacts) {
|
||||
UUID contactId = contact.getContact_id();
|
||||
User contactUser = userDatabase.findByInternalUUID(contactId);
|
||||
if (contactUser == null) continue;
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("user_id", contact.getUser_id().toString());
|
||||
obj.put("contact_id", contact.getContact_id().toString());
|
||||
obj.put("contact_id", contactId.toString()); // UUID
|
||||
obj.put("user_id", contactUser.getUser_id()); // public ID
|
||||
obj.put("profile_name", contactUser.getProfile_name());
|
||||
obj.put("image_url", contactUser.getImage_url());
|
||||
obj.put("is_blocked", contact.getIs_blocked());
|
||||
obj.put("added_at", contact.getAdd_at().toString());
|
||||
|
||||
array.put(obj);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static JSONArray contactEntryListToJson(List<ContactEntry> contactEntries) {
|
||||
JSONArray array = new JSONArray();
|
||||
|
||||
for (ContactEntry entry : contactEntries) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("contact_id", entry.getContactId().toString());
|
||||
obj.put("user_id", entry.getUserId());
|
||||
obj.put("profile_name", entry.getProfileName());
|
||||
obj.put("image_url", entry.getImageUrl());
|
||||
obj.put("is_blocked", entry.isBlocked());
|
||||
array.put(obj);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -486,6 +486,7 @@ public class ClientHandler implements Runnable {
|
||||
currentUser.getImage_url(),
|
||||
contactUUID
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
response = success
|
||||
@@ -1265,7 +1266,7 @@ public class ClientHandler implements Runnable {
|
||||
break;
|
||||
}
|
||||
|
||||
messages = MessageDatabase.privateChatHistory(chatId);
|
||||
messages = MessageDatabase.privateChatHistory(chatId, currentUser.getInternal_uuid());
|
||||
}
|
||||
|
||||
|
||||
@@ -1275,7 +1276,7 @@ public class ClientHandler implements Runnable {
|
||||
response = new ResponseModel("error", "Group not found.");
|
||||
break;
|
||||
}
|
||||
messages = MessageDatabase.groupChatHistory(group.getInternal_uuid());
|
||||
messages = MessageDatabase.groupChatHistory(group.getInternal_uuid(),currentUser.getInternal_uuid());
|
||||
}
|
||||
|
||||
|
||||
@@ -1285,7 +1286,7 @@ public class ClientHandler implements Runnable {
|
||||
response = new ResponseModel("error", "Channel not found.");
|
||||
break;
|
||||
}
|
||||
messages = MessageDatabase.channelChatHistory(channel.getInternal_uuid());
|
||||
messages = MessageDatabase.channelChatHistory(channel.getInternal_uuid(),currentUser.getInternal_uuid());
|
||||
}
|
||||
default -> {
|
||||
response = new ResponseModel("error", "Invalid receiver type.");
|
||||
@@ -1988,7 +1989,6 @@ public class ClientHandler implements Runnable {
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "get_or_create_private_chat": {
|
||||
if (currentUser == null) {
|
||||
response = new ResponseModel("error", "Unauthorized. Please login first.");
|
||||
@@ -1999,7 +1999,23 @@ public class ClientHandler implements Runnable {
|
||||
UUID user1 = UUID.fromString(requestJson.getString("user1"));
|
||||
UUID user2 = UUID.fromString(requestJson.getString("user2"));
|
||||
|
||||
UUID oldChat = PrivateChatDatabase.findChatBetween(user1, user2);
|
||||
UUID chatId = PrivateChatDatabase.getOrCreateChat(user1, user2);
|
||||
boolean isNew = oldChat == null;
|
||||
|
||||
if (isNew) {
|
||||
JSONObject chatPayload = new JSONObject();
|
||||
chatPayload.put("action", "created_private_chat");
|
||||
|
||||
JSONObject chatData = new JSONObject();
|
||||
chatData.put("chat_id", chatId.toString());
|
||||
chatData.put("chat_type", "private");
|
||||
chatData.put("last_message_time", LocalDateTime.now().toString());
|
||||
chatPayload.put("data", chatData);
|
||||
|
||||
RealTimeEventDispatcher.sendToUser(user1, chatPayload);
|
||||
RealTimeEventDispatcher.sendToUser(user2, chatPayload);
|
||||
}
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("chat_id", chatId.toString());
|
||||
@@ -2014,6 +2030,7 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
|
||||
|
||||
|
||||
case "get_private_chat_target": {
|
||||
UUID chatId = UUID.fromString(requestJson.getString("chat_id"));
|
||||
userId = currentUser.getInternal_uuid();
|
||||
@@ -2029,6 +2046,43 @@ public class ClientHandler implements Runnable {
|
||||
break;
|
||||
}
|
||||
|
||||
case "get_contact_list": {
|
||||
if (currentUser == null) {
|
||||
response = new ResponseModel("error", "Unauthorized. Please login first.");
|
||||
break;
|
||||
}
|
||||
|
||||
List<Contact> contacts = ContactDatabase.getContacts(currentUser.getInternal_uuid());
|
||||
List<ContactEntry> contactEntries = new ArrayList<>();
|
||||
|
||||
for (Contact contact : contacts) {
|
||||
UUID contactId = contact.getContact_id();
|
||||
User contactUser = userDatabase.findByInternalUUID(contactId);
|
||||
if (contactUser == null) continue;
|
||||
|
||||
ContactEntry entry = new ContactEntry(
|
||||
contactId,
|
||||
contactUser.getUser_id(),
|
||||
contactUser.getProfile_name(),
|
||||
contactUser.getImage_url(),
|
||||
contact.getIs_blocked()
|
||||
);
|
||||
|
||||
contactEntries.add(entry);
|
||||
}
|
||||
|
||||
// Optional: sort alphabetically
|
||||
contactEntries.sort(Comparator.comparing(ContactEntry::getProfileName, String.CASE_INSENSITIVE_ORDER));
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("contact_list", JsonUtil.contactEntryListToJson(contactEntries));
|
||||
|
||||
response = new ResponseModel("success", "Contact list refreshed", data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user