diff --git a/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java b/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java index dc1e335..5c4bba8 100644 --- a/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java +++ b/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java @@ -231,9 +231,17 @@ public class ActionHandler { 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"); + + // ❗ چک کن که chat_list وجود داره + if (!data.has("chat_list") || data.isNull("chat_list")) { + System.out.println("❌ chat_list not found in response data."); + return; + } + JSONArray chatListJson = data.getJSONArray("chat_list"); List chatList = new ArrayList<>(); @@ -255,9 +263,9 @@ public class ActionHandler { } Session.chatList = chatList; - System.out.println("✅ Chat list updated."); + System.out.println("✅ Chat list updated. Total: " + chatList.size()); } else { - System.out.println("⚠️ Response has no chat list data."); + System.out.println("⚠️ Response has no data object."); } } else { if (response.has("message") && !response.isNull("message")) { @@ -273,7 +281,6 @@ public class ActionHandler { } - public void createGroup() { System.out.print("Enter group ID: "); String groupId = scanner.nextLine(); @@ -622,11 +629,6 @@ public class ActionHandler { return; } -// if (Session.forceRefreshChatList) { -// System.out.println("🔁 Refresh triggered by real-time event."); -// requestChatList(); // با sendWithResponse جواب می‌گیری -// Session.forceRefreshChatList = false; -// } @@ -869,7 +871,6 @@ public class ActionHandler { case "9" -> { if (isOwner) { transferOwnershipAndLeave(chat.getId()); - refreshChatList(); } else { leaveChat(chat.getId(), "group"); refreshChatList(); @@ -1003,7 +1004,6 @@ public class ActionHandler { case "9" -> { if (isOwner) { transferChannelOwnershipAndLeave(chat.getId()); - refreshChatList(); return false; } else { System.out.println("❌ You don't have permission."); @@ -2139,32 +2139,7 @@ public class ActionHandler { } -// public static void handleChatListResponse(JSONObject response) { -// if (response.getString("status").equals("success")) { -// JSONArray chats = response.getJSONArray("data"); -// -// Session.chatList.clear(); -// -// for (int i = 0; i < chats.length(); i++) { -// JSONObject chatJson = chats.getJSONObject(i); -// -// UUID internalId = UUID.fromString(chatJson.getString("internal_id")); -// String displayId = chatJson.getString("id"); -// String name = chatJson.getString("name"); -// String imageUrl = chatJson.optString("image_url", ""); -// String type = chatJson.getString("type"); -// LocalDateTime lastMessageTime = LocalDateTime.parse(chatJson.getString("last_message_time")); -// -// ChatEntry chat = new ChatEntry(internalId, displayId, name, imageUrl, type, lastMessageTime); -// Session.chatList.add(chat); -// } -// -// System.out.println("\n✅ Updated Chat List:"); -// displayChatList(); -// } else { -// System.out.println("⚠️ Failed to fetch chat list: " + response.getString("message")); -// } -// } + public static void displayChatList() { if (Session.chatList == null || Session.chatList.isEmpty()) { diff --git a/src/main/java/org/to/telegramfinalproject/Client/IncomingMessageListener.java b/src/main/java/org/to/telegramfinalproject/Client/IncomingMessageListener.java index 588c9be..c10c83d 100644 --- a/src/main/java/org/to/telegramfinalproject/Client/IncomingMessageListener.java +++ b/src/main/java/org/to/telegramfinalproject/Client/IncomingMessageListener.java @@ -40,7 +40,6 @@ public class IncomingMessageListener implements Runnable { TelegramClient.responseQueue.put(response); } - // ⚠️ بسیار مهم: دیگر بررسی action انجام نده continue; } @@ -112,11 +111,11 @@ public class IncomingMessageListener implements Runnable { ActionHandler.requestChatInfo(chatId, chatType); } - case "became_admin", "removed_admin" -> { - System.out.println("🧩 Detected admin role change. Calling handler..."); + case "became_admin", "removed_admin", "ownership_transferred" -> { + System.out.println("🧩 Detected admin/owner role change. Calling handler..."); new Thread(() -> { try { - handleAdminRoleChanged(msg); // ✅ صدا زدن در ترد جداگانه + handleAdminRoleChanged(msg); //new thread } catch (IOException e) { e.printStackTrace(); } @@ -124,27 +123,7 @@ public class IncomingMessageListener implements Runnable { } -// case "get_chat_info" -> { -// JSONObject chatData = msg.getJSONObject("data"); -// UUID chatUUID = UUID.fromString(chatData.getString("internal_id")); // -// Optional entry = Session.chatList.stream() -// .filter(e -> e.getId().equals(chatUUID)) -// .findFirst(); -// -// entry.ifPresent(chat -> { -// chat.setAdmin(chatData.optBoolean("is_admin", false)); -// chat.setOwner(chatData.optBoolean("is_owner", false)); -// -// if (Session.currentChatId != null && Session.currentChatId.equals(chat.getId())) { -// Session.currentChatEntry = chat; -// Session.refreshCurrentChatMenu = true; -// -// } -// -// System.out.println("✅ Chat info updated → admin: " + chat.isAdmin() + ", owner: " + chat.isOwner()); -// }); -// } @@ -166,7 +145,7 @@ public class IncomingMessageListener implements Runnable { System.out.println("\n🔄 Your admin status changed. Updating chat info..."); try { - // 1. دریافت chat info + // 1. get chat info JSONObject chatInfoReq = new JSONObject(); chatInfoReq.put("action", "get_chat_info"); chatInfoReq.put("receiver_id", chatId); @@ -196,7 +175,7 @@ public class IncomingMessageListener implements Runnable { Session.currentChatEntry = chat; }); - // 2. گرفتن permission + // 2. get permission JSONObject permissionReq = new JSONObject(); if (chatType.equalsIgnoreCase("group")) { permissionReq.put("action", "get_group_permissions"); @@ -210,10 +189,9 @@ public class IncomingMessageListener implements Runnable { JSONObject perm = permissionResp.getJSONObject("data"); entry.ifPresent(chat -> chat.setPermissions(perm)); - // 3. ست کردن currentChatId + // 3. set currentChatId Session.currentChatId = chatUUID.toString(); // ❗ باید قبل از بررسی شرط‌ها باشه - // 🔄 بررسی شرایط و آپدیت منو System.out.println("🧪 Checking refresh conditions..."); System.out.println("🔹 inChatMenu: " + Session.inChatMenu); System.out.println("🔹 currentChatId: " + Session.currentChatId); diff --git a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java index 7254d16..0decb6e 100644 --- a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java +++ b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java @@ -1143,10 +1143,16 @@ public class ClientHandler implements Runnable { //RealTime if (success) { List members = GroupDatabase.getMemberUUIDs(groupId); + + // 1. ارسال ownership_transferred فقط به owner جدید + RealTimeEventDispatcher.sendOwnershipTransferred("group", groupId, groupId.toString(), List.of(newOwner.getInternal_uuid())); + + // 2. ارسال update_group_or_channel برای همه اعضا RealTimeEventDispatcher.sendGroupOrChannelUpdate("group", groupId, groupId.toString(), "", "", members); } + response = success ? new ResponseModel("success", "Ownership transferred.") : new ResponseModel("error", "Failed to transfer ownership."); @@ -1558,9 +1564,15 @@ public class ClientHandler implements Runnable { //RealTime if (success) { List subscribers = ChannelDatabase.getChannelSubscriberUUIDs(channelId); + + // 1. ارسال ownership_transferred فقط به owner جدید + RealTimeEventDispatcher.sendOwnershipTransferred("channel", channelId, channelId.toString(), List.of(newOwner.getInternal_uuid())); + + // 2. ارسال update_group_or_channel برای بروزرسانی UI تمام افراد RealTimeEventDispatcher.sendGroupOrChannelUpdate("channel", channelId, channelId.toString(), "", "", subscribers); } + response = success ? new ResponseModel("success", "Ownership transferred successfully.") @@ -1586,7 +1598,7 @@ public class ClientHandler implements Runnable { if (requestJson.has("request_id")) { String requestId = requestJson.getString("request_id"); response.setRequestId(requestId); - responseJson.put("request_id", requestId); // ✅ بدون این، کلاینت قفل میشه + responseJson.put("request_id", requestId); } out.println(responseJson.toString()); diff --git a/src/main/java/org/to/telegramfinalproject/Server/RealTimeEventDispatcher.java b/src/main/java/org/to/telegramfinalproject/Server/RealTimeEventDispatcher.java index be934b2..3c96120 100644 --- a/src/main/java/org/to/telegramfinalproject/Server/RealTimeEventDispatcher.java +++ b/src/main/java/org/to/telegramfinalproject/Server/RealTimeEventDispatcher.java @@ -264,7 +264,7 @@ public class RealTimeEventDispatcher { public static void notifyBecameAdmin(String type, UUID chatId, String chatName, String imageUrl, UUID userId) { JSONObject data = new JSONObject(); - data.put("chat_type", type); // group یا channel + data.put("chat_type", type); // group or channel data.put("chat_id", chatId.toString()); data.put("chat_name", chatName); data.put("image_url", imageUrl); @@ -291,4 +291,18 @@ public class RealTimeEventDispatcher { sendToUser(userId, event); } + + public static void sendOwnershipTransferred(String type, UUID chatId, String chatName, List affectedUsers) { + JSONObject data = new JSONObject(); + data.put("chat_type", type); // "group" or "channel" + data.put("chat_id", chatId.toString()); + data.put("chat_name", chatName); + + JSONObject event = new JSONObject(); + event.put("action", "ownership_transferred"); + event.put("data", data); + + broadcastToUsers(affectedUsers, event); + } + }