Merge pull request #7 from PartowRoshani/Real-Time-update
Real time update
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,38 @@
|
|||||||
package org.to.telegramfinalproject.Client;
|
package org.to.telegramfinalproject.Client;
|
||||||
|
|
||||||
public class EventProcessorThread extends Thread {
|
import org.json.JSONObject;
|
||||||
private final ActionHandler handler;
|
|
||||||
|
|
||||||
public EventProcessorThread(ActionHandler handler) {
|
import java.io.BufferedReader;
|
||||||
this.handler = handler;
|
|
||||||
setDaemon(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
//public class EventProcessorThread extends Thread {
|
||||||
public void run() {
|
// private final ActionHandler handler;
|
||||||
while (true) {
|
// private final BufferedReader in;
|
||||||
try {
|
//
|
||||||
Thread.sleep(2000);
|
// public EventProcessorThread(ActionHandler handler, BufferedReader in) {
|
||||||
handler.processIncomingEvents();
|
// this.handler = handler;
|
||||||
} catch (InterruptedException ignored) {}
|
// this.in = in;
|
||||||
}
|
// setDaemon(true);
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
|
// public void run() {
|
||||||
|
// try {
|
||||||
|
// System.out.println("👂 Real-Time Listener started.");
|
||||||
|
// String line;
|
||||||
|
// while ((line = in.readLine()) != null) {
|
||||||
|
// JSONObject json = new JSONObject(line);
|
||||||
|
// System.out.println("📥 Received raw line: " + line);
|
||||||
|
//
|
||||||
|
// if (json.has("action")) {
|
||||||
|
// // پیام real-time
|
||||||
|
// handler.processIncomingEvent(json);
|
||||||
|
// } else {
|
||||||
|
// // پیام پاسخ معمولی
|
||||||
|
// TelegramClient.responseQueue.put(json);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// System.err.println("❌ Error in EventProcessorThread: " + e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package org.to.telegramfinalproject.Client;
|
package org.to.telegramfinalproject.Client;
|
||||||
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.to.telegramfinalproject.Models.ChatEntry;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
|
||||||
public class IncomingMessageListener implements Runnable {
|
public class IncomingMessageListener implements Runnable {
|
||||||
private final BufferedReader in;
|
private final BufferedReader in;
|
||||||
@@ -19,25 +23,52 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
|
|
||||||
String line;
|
String line;
|
||||||
while ((line = in.readLine()) != null) {
|
while ((line = in.readLine()) != null) {
|
||||||
|
|
||||||
|
|
||||||
JSONObject response = new JSONObject(line);
|
JSONObject response = new JSONObject(line);
|
||||||
System.out.println("📥 Received raw line: " + line);
|
System.out.println("📥 Received raw line: " + line);
|
||||||
|
|
||||||
|
//if it has reqID answer
|
||||||
|
if (response.has("request_id")) {
|
||||||
|
String requestId = response.getString("request_id");
|
||||||
|
System.out.println("📬 Response with request_id: " + requestId);
|
||||||
|
System.out.println("📬 Full response: " + response.toString(2));
|
||||||
|
|
||||||
|
BlockingQueue<JSONObject> queue = TelegramClient.pendingResponses.get(requestId);
|
||||||
|
if (queue != null) {
|
||||||
|
queue.put(response);
|
||||||
|
} else {
|
||||||
|
System.out.println("⚠️ No pending queue for request_id = " + requestId + ". Putting in responseQueue...");
|
||||||
|
TelegramClient.responseQueue.put(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//if it has action check it
|
||||||
if (response.has("action")) {
|
if (response.has("action")) {
|
||||||
String action = response.getString("action");
|
String action = response.getString("action");
|
||||||
|
System.out.println("🎯 [Listener] Action received: " + response.toString(2));
|
||||||
|
System.out.println("🎯 Received action: " + action);
|
||||||
|
|
||||||
if (isRealTimeEvent(action)) {
|
if (isRealTimeEvent(action)) {
|
||||||
handleRealTimeEvent(response);
|
handleRealTimeEvent(response);
|
||||||
} else {
|
} else {
|
||||||
TelegramClient.responseQueue.put(response);
|
TelegramClient.responseQueue.put(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (response.has("status") && response.has("message")) {
|
} else if (response.has("status") && response.has("message")) {
|
||||||
TelegramClient.responseQueue.put(response);
|
TelegramClient.responseQueue.put(response); // general answer
|
||||||
} else {
|
} else {
|
||||||
TelegramClient.responseQueue.put(response);
|
TelegramClient.responseQueue.put(response); // fallback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("🔴 Listener stopped: " + e.getMessage());
|
System.out.println("🔴 [Listener] Crashed due to: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,15 +77,157 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
case "new_message", "message_edited", "message_deleted",
|
case "new_message", "message_edited", "message_deleted",
|
||||||
"user_status_changed", "added_to_group", "added_to_channel",
|
"user_status_changed", "added_to_group", "added_to_channel",
|
||||||
"update_group_or_channel", "chat_deleted",
|
"update_group_or_channel", "chat_deleted",
|
||||||
"blocked_by_user", "unblocked_by_user", "message_seen" -> true;
|
"blocked_by_user", "unblocked_by_user", "message_seen",
|
||||||
|
"removed_from_group", "removed_from_channel",
|
||||||
|
"became_admin", "removed_admin", "ownership_transferred","admin_permissions_updated" -> true;
|
||||||
default -> false;
|
default -> false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRealTimeEvent(JSONObject response) {
|
void handleRealTimeEvent(JSONObject response) throws IOException {
|
||||||
String action = response.getString("action");
|
String action = response.getString("action");
|
||||||
JSONObject msg = response.getJSONObject("data");
|
JSONObject msg = response.getJSONObject("data");
|
||||||
|
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "added_to_group", "added_to_channel",
|
||||||
|
"removed_from_group", "removed_from_channel", "chat_deleted" -> {
|
||||||
|
System.out.println("🔄 Chat list changed. Updating...");
|
||||||
|
Session.forceRefreshChatList = true;
|
||||||
|
System.out.println("🧪 Calling requestChatList() after being added");
|
||||||
|
|
||||||
|
String chatId = msg.getString("chat_id");
|
||||||
|
String chatType = msg.getString("chat_type");
|
||||||
|
ActionHandler.requestChatInfo(chatId, chatType);
|
||||||
|
|
||||||
|
if (action.equals("removed_from_group") || action.equals("removed_from_channel") || action.equals("chat_deleted")) {
|
||||||
|
System.out.println("🚫 You were removed from the chat or chat was deleted. Exiting...");
|
||||||
|
ActionHandler.forceExitChat = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "chat_updated" -> {
|
||||||
|
System.out.println("\n🔄 Group/Channel info updated.");
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
handleAdminRoleChanged(msg);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
case "became_admin", "removed_admin", "ownership_transferred","admin_permissions_updated" -> {
|
||||||
|
System.out.println("🧩 Detected admin/owner role change. Calling handler...");
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
handleAdminRoleChanged(msg); //new thread
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default -> displayRealTimeMessage(action, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print(">> ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleAdminRoleChanged(JSONObject data) throws IOException {
|
||||||
|
String chatType = data.getString("chat_type");
|
||||||
|
String chatId = data.optString("group_id", data.optString("channel_id", data.optString("chat_id", null)));
|
||||||
|
|
||||||
|
if (chatId == null) {
|
||||||
|
System.out.println("⚠️ No valid ID found in real-time data: " + data.toString(2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("\n🔄 Your admin status changed. Updating chat info...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. get chat info
|
||||||
|
JSONObject chatInfoReq = new JSONObject();
|
||||||
|
chatInfoReq.put("action", "get_chat_info");
|
||||||
|
chatInfoReq.put("receiver_id", chatId);
|
||||||
|
chatInfoReq.put("receiver_type", chatType);
|
||||||
|
System.out.println("📤 Sending get_chat_info: " + chatInfoReq);
|
||||||
|
JSONObject chatInfoResp = ActionHandler.sendWithResponse(chatInfoReq);
|
||||||
|
JSONObject chatData = chatInfoResp.getJSONObject("data");
|
||||||
|
|
||||||
|
UUID chatUUID = UUID.fromString(chatData.getString("internal_id"));
|
||||||
|
|
||||||
|
Optional<ChatEntry> entry = Session.chatList.stream()
|
||||||
|
.filter(e -> e.getId().equals(chatUUID))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
if (entry.isEmpty()) {
|
||||||
|
System.out.println("❌ Chat not found in session.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.ifPresent(chat -> {
|
||||||
|
chat.setAdmin(chatData.optBoolean("is_admin", false));
|
||||||
|
chat.setOwner(chatData.optBoolean("is_owner", false));
|
||||||
|
chat.setName(chatData.optString("name", ""));
|
||||||
|
chat.setDisplayId(chatData.optString("id", ""));
|
||||||
|
chat.setImageUrl(chatData.optString("image_url", ""));
|
||||||
|
chat.setType(chatData.optString("type", ""));
|
||||||
|
Session.currentChatEntry = chat;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. get permission
|
||||||
|
JSONObject permissionReq = new JSONObject();
|
||||||
|
if (chatType.equalsIgnoreCase("group")) {
|
||||||
|
permissionReq.put("action", "get_group_permissions");
|
||||||
|
permissionReq.put("group_id", chatId);
|
||||||
|
} else {
|
||||||
|
permissionReq.put("action", "get_channel_permissions");
|
||||||
|
permissionReq.put("channel_id", chatId);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject permissionResp = ActionHandler.sendWithResponse(permissionReq);
|
||||||
|
JSONObject perm = permissionResp.getJSONObject("data");
|
||||||
|
entry.ifPresent(chat -> chat.setPermissions(perm));
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
System.out.println("🔹 chatUUID: " + chatUUID);
|
||||||
|
|
||||||
|
if (Session.inChatMenu && Session.currentChatId != null && Session.currentChatId.equals(chatUUID.toString())) {
|
||||||
|
synchronized (Session.class) {
|
||||||
|
Session.refreshCurrentChatMenu = true;
|
||||||
|
}
|
||||||
|
System.out.println("✅ Admin status updated. Refreshing menu...");
|
||||||
|
} else {
|
||||||
|
System.out.println("❌ Refresh conditions not met.");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("❌ Exception while handling admin role change: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void displayRealTimeMessage(String action, JSONObject msg) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "new_message" -> {
|
case "new_message" -> {
|
||||||
System.out.println("\n🔔 New Message:");
|
System.out.println("\n🔔 New Message:");
|
||||||
@@ -62,60 +235,36 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
System.out.println("Time: " + msg.getString("time"));
|
System.out.println("Time: " + msg.getString("time"));
|
||||||
System.out.println("Content: " + msg.getString("content"));
|
System.out.println("Content: " + msg.getString("content"));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "message_edited" -> {
|
case "message_edited" -> {
|
||||||
System.out.println("\n✏️ Message Edited:");
|
System.out.println("\n✏️ Message Edited:");
|
||||||
System.out.println("ID: " + msg.getString("message_id"));
|
System.out.println("ID: " + msg.getString("message_id"));
|
||||||
System.out.println("New Content: " + msg.getString("new_content"));
|
System.out.println("New Content: " + msg.getString("new_content"));
|
||||||
System.out.println("Edit Time: " + msg.getString("edited_at"));
|
System.out.println("Edit Time: " + msg.getString("edited_at"));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "message_deleted" -> {
|
case "message_deleted" -> {
|
||||||
System.out.println("\n🗑️ Message Deleted:");
|
System.out.println("\n🗑️ Message Deleted:");
|
||||||
System.out.println("Message ID: " + msg.getString("message_id"));
|
System.out.println("Message ID: " + msg.getString("message_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "user_status_changed" -> {
|
case "user_status_changed" -> {
|
||||||
System.out.println("\n🔄 User Status Changed:");
|
System.out.println("\n🔄 User Status Changed:");
|
||||||
System.out.println("User: " + msg.getString("user_id"));
|
System.out.println("User: " + msg.getString("user_id"));
|
||||||
System.out.println("Status: " + msg.getString("status"));
|
System.out.println("Status: " + msg.getString("status"));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "added_to_group" -> {
|
|
||||||
System.out.println("\n👥 You were added to a group: " + msg.getString("chat_name"));
|
|
||||||
}
|
|
||||||
|
|
||||||
case "added_to_channel" -> {
|
|
||||||
System.out.println("\n📢 You were added to a channel: " + msg.getString("chat_name"));
|
|
||||||
}
|
|
||||||
|
|
||||||
case "update_group_or_channel" -> {
|
|
||||||
System.out.println("\n🔄 Group/Channel updated: " + msg.getString("new_name"));
|
|
||||||
}
|
|
||||||
|
|
||||||
case "chat_deleted" -> {
|
|
||||||
System.out.println("\n🗑️ Chat deleted: " + msg.getString("chat_id"));
|
|
||||||
}
|
|
||||||
|
|
||||||
case "blocked_by_user" -> {
|
case "blocked_by_user" -> {
|
||||||
System.out.println("\n⛔ You were blocked by user: " + msg.getString("blocker_id"));
|
System.out.println("\n⛔ You were blocked by user: " + msg.getString("blocker_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "unblocked_by_user" -> {
|
case "unblocked_by_user" -> {
|
||||||
System.out.println("\n✅ You were unblocked by user: " + msg.getString("unblocker_id"));
|
System.out.println("\n✅ You were unblocked by user: " + msg.getString("unblocker_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "message_seen" -> {
|
case "message_seen" -> {
|
||||||
System.out.println("\n👁️ Your message was seen:");
|
System.out.println("\n👁️ Your message was seen:");
|
||||||
System.out.println("Message ID: " + msg.getString("message_id"));
|
System.out.println("Message ID: " + msg.getString("message_id"));
|
||||||
System.out.println("Seen at: " + msg.getString("seen_at"));
|
System.out.println("Seen at: " + msg.getString("seen_at"));
|
||||||
}
|
}
|
||||||
|
|
||||||
default -> {
|
default -> {
|
||||||
System.out.println("\n❓ Unknown real-time action: " + action);
|
System.out.println("\n❓ Unknown real-time action: " + action);
|
||||||
|
System.out.println(msg.toString(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
package org.to.telegramfinalproject.Client;
|
package org.to.telegramfinalproject.Client;
|
||||||
|
|
||||||
|
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 java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
// method for save data from server response
|
// method for save data from server response
|
||||||
public class Session {
|
public class Session {
|
||||||
public static JSONObject currentUser;
|
public static JSONObject currentUser;
|
||||||
public static List<ChatEntry> chatList;
|
public static List<ChatEntry> chatList = new ArrayList<>();
|
||||||
|
public static volatile boolean forceRefreshChatList = false;
|
||||||
|
public static volatile boolean backToChatList = false;
|
||||||
|
public static boolean inChatListMenu = false;
|
||||||
|
public static String currentChatType = null;
|
||||||
|
public static volatile boolean inChatMenu = false;
|
||||||
|
public static volatile boolean refreshCurrentChatMenu = false;
|
||||||
|
public static String currentChatId = null;
|
||||||
|
public static ChatEntry currentChatEntry = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static String getUserUUID() {
|
public static String getUserUUID() {
|
||||||
if (currentUser.has("uuid")) return currentUser.getString("uuid");
|
if (currentUser.has("uuid")) return currentUser.getString("uuid");
|
||||||
@@ -18,4 +33,26 @@ public class Session {
|
|||||||
throw new RuntimeException("❌ No UUID found in currentUser!");
|
throw new RuntimeException("❌ No UUID found in currentUser!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void updateChatList(JSONArray chatArray) {
|
||||||
|
chatList.clear();
|
||||||
|
for (int i = 0; i < chatArray.length(); i++) {
|
||||||
|
JSONObject obj = chatArray.getJSONObject(i);
|
||||||
|
ChatEntry entry = new ChatEntry(
|
||||||
|
UUID.fromString(obj.getString("internal_id")),
|
||||||
|
obj.optString("id", ""), // displayId
|
||||||
|
obj.optString("name", ""), // name
|
||||||
|
obj.optString("image_url", ""),
|
||||||
|
obj.getString("type"),
|
||||||
|
null, // last message time (if needed, parse it)
|
||||||
|
obj.optBoolean("is_owner", false),
|
||||||
|
obj.optBoolean("is_admin", false)
|
||||||
|
);
|
||||||
|
entry.setPermissions(obj.optJSONObject("permissions")); // اگر permissions وجود داره
|
||||||
|
chatList.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static List<ChatEntry> getChatList() {
|
||||||
|
return chatList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,32 +7,44 @@ import java.io.IOException;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
public class TelegramClient {
|
public class TelegramClient {
|
||||||
private static final String SERVER_HOST = "localhost";
|
private static final String SERVER_HOST = "localhost";
|
||||||
private static final int SERVER_PORT = 8000;
|
private static final int SERVER_PORT = 8000;
|
||||||
private Socket socket;
|
private static Socket socket;
|
||||||
private BufferedReader in;
|
private BufferedReader in;
|
||||||
private PrintWriter out;
|
private PrintWriter out;
|
||||||
private final Scanner scanner;
|
private final Scanner scanner;
|
||||||
ActionHandler handler = null;
|
private ActionHandler handler;
|
||||||
public static BlockingQueue<JSONObject> responseQueue = new LinkedBlockingQueue<>();
|
public static BlockingQueue<JSONObject> responseQueue = new LinkedBlockingQueue<>();
|
||||||
|
public static UUID loggedInUserId = null;
|
||||||
|
public static final Map<String, BlockingQueue<JSONObject>> pendingResponses = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
private static TelegramClient instance;
|
||||||
|
|
||||||
public TelegramClient() {
|
public TelegramClient() {
|
||||||
this.scanner = new Scanner(System.in);
|
this.scanner = new Scanner(System.in);
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TelegramClient getInstance() {
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
try {
|
try {
|
||||||
this.socket = new Socket(SERVER_HOST, SERVER_PORT);
|
socket = new Socket(SERVER_HOST, SERVER_PORT);
|
||||||
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
this.out = new PrintWriter(this.socket.getOutputStream(), true);
|
out = new PrintWriter(socket.getOutputStream(), true);
|
||||||
System.out.println("✅ Connected to Telegram Server");
|
System.out.println("✅ Connected to Telegram Server");
|
||||||
this.handler = new ActionHandler(this.out, this.in, this.scanner);
|
handler = new ActionHandler(out, in, scanner);
|
||||||
|
|
||||||
Thread listenerThread = new Thread(new IncomingMessageListener(in));
|
Thread listenerThread = new Thread(new IncomingMessageListener(in));
|
||||||
listenerThread.setDaemon(true);
|
listenerThread.setDaemon(true);
|
||||||
@@ -45,7 +57,7 @@ public class TelegramClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showMainMenu() {
|
private void showMainMenu() throws IOException {
|
||||||
while (true) {
|
while (true) {
|
||||||
System.out.println("Main Menu:");
|
System.out.println("Main Menu:");
|
||||||
System.out.println("1. Register");
|
System.out.println("1. Register");
|
||||||
@@ -60,7 +72,13 @@ public class TelegramClient {
|
|||||||
handler.loginHandler();
|
handler.loginHandler();
|
||||||
if (Session.currentUser != null) {
|
if (Session.currentUser != null) {
|
||||||
System.out.println("✅ Login successful.");
|
System.out.println("✅ Login successful.");
|
||||||
|
new Thread(new ActionHandler.ChatStateMonitor(out)).start();
|
||||||
|
// new Thread(new ActionHandler.CurrentChatMenuRefresher(this.handler)).start();
|
||||||
|
|
||||||
|
|
||||||
UUID internalId = UUID.fromString(Session.currentUser.getString("internal_uuid"));
|
UUID internalId = UUID.fromString(Session.currentUser.getString("internal_uuid"));
|
||||||
|
loggedInUserId = internalId;
|
||||||
|
|
||||||
handler.userMenu(internalId);
|
handler.userMenu(internalId);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("❌ Login failed.");
|
System.out.println("❌ Login failed.");
|
||||||
@@ -75,7 +93,30 @@ public class TelegramClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void send(JSONObject req) {
|
||||||
|
try {
|
||||||
|
responseQueue.clear(); // optional: clear old responses
|
||||||
|
getInstance().out.println(req.toString());
|
||||||
|
System.out.println("📤 [SEND] " + req.toString(2));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("❌ Error sending request: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Socket getSocket() {
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new TelegramClient().start();
|
new TelegramClient().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PrintWriter getOut() {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ public class ChannelDatabase {
|
|||||||
|
|
||||||
|
|
||||||
public static boolean transferOwnership(UUID channelId, UUID newOwnerUUID) {
|
public static boolean transferOwnership(UUID channelId, UUID newOwnerUUID) {
|
||||||
String sql = """
|
String updateRoles = """
|
||||||
UPDATE channel_subscribers
|
UPDATE channel_subscribers
|
||||||
SET role = CASE
|
SET role = CASE
|
||||||
WHEN user_id = ? THEN 'owner'
|
WHEN user_id = ? THEN 'owner'
|
||||||
@@ -586,15 +586,64 @@ public class ChannelDatabase {
|
|||||||
WHERE channel_id = ?
|
WHERE channel_id = ?
|
||||||
""";
|
""";
|
||||||
|
|
||||||
|
String clearPermissions = """
|
||||||
|
UPDATE channel_subscribers
|
||||||
|
SET permissions = '{}'::jsonb
|
||||||
|
WHERE channel_id = ? AND user_id = ?
|
||||||
|
""";
|
||||||
|
|
||||||
|
try (Connection conn = ConnectionDb.connect()) {
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
try (PreparedStatement roleStmt = conn.prepareStatement(updateRoles);
|
||||||
|
PreparedStatement clearPermsStmt = conn.prepareStatement(clearPermissions)) {
|
||||||
|
|
||||||
|
roleStmt.setObject(1, newOwnerUUID);
|
||||||
|
roleStmt.setObject(2, channelId);
|
||||||
|
roleStmt.executeUpdate();
|
||||||
|
|
||||||
|
clearPermsStmt.setObject(1, channelId);
|
||||||
|
clearPermsStmt.setObject(2, newOwnerUUID);
|
||||||
|
clearPermsStmt.executeUpdate();
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
conn.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<UUID> getChannelSubscriberUUIDs(UUID channelId) {
|
||||||
|
List<UUID> subscriberIds = new ArrayList<>();
|
||||||
try (Connection conn = ConnectionDb.connect();
|
try (Connection conn = ConnectionDb.connect();
|
||||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
PreparedStatement stmt = conn.prepareStatement("SELECT user_id FROM channel_subscribers WHERE channel_id = ?")) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
subscriberIds.add(UUID.fromString(rs.getString("user_id")));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return subscriberIds;
|
||||||
|
}
|
||||||
|
|
||||||
stmt.setObject(1, newOwnerUUID);
|
public static boolean updateAdminPermissions(UUID channelId, UUID userId, JSONObject permissions) {
|
||||||
|
String sql = "UPDATE channel_subscribers SET permissions = ?::jsonb WHERE channel_id = ? AND user_id = ? AND role = 'admin'";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, permissions.toString());
|
||||||
stmt.setObject(2, channelId);
|
stmt.setObject(2, channelId);
|
||||||
|
stmt.setObject(3, userId);
|
||||||
stmt.executeUpdate();
|
return stmt.executeUpdate() > 0;
|
||||||
return true;
|
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import java.sql.SQLException;
|
|||||||
public class ConnectionDb {
|
public class ConnectionDb {
|
||||||
private static final String JDBC_URL = "jdbc:postgresql://localhost:5432/Telegram";
|
private static final String JDBC_URL = "jdbc:postgresql://localhost:5432/Telegram";
|
||||||
private static final String USERNAME = "postgres";
|
private static final String USERNAME = "postgres";
|
||||||
private static final String PASSWORD = "124postpass";
|
private static final String PASSWORD = "Partow@1384";
|
||||||
|
|
||||||
public ConnectionDb() {
|
public ConnectionDb() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ public class ContactDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<UUID> getContactUUIDs(UUID userId) {
|
||||||
|
List<Contact> contacts = getContacts(userId);
|
||||||
|
List<UUID> contactIds = new ArrayList<>();
|
||||||
|
for (Contact c : contacts) {
|
||||||
|
contactIds.add(c.getContact_id());
|
||||||
|
}
|
||||||
|
return contactIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean removeContact(UUID user_id, UUID contact_id) {
|
public boolean removeContact(UUID user_id, UUID contact_id) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.to.telegramfinalproject.Database;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Models.Group;
|
import org.to.telegramfinalproject.Models.Group;
|
||||||
|
import org.to.telegramfinalproject.Models.User;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -377,7 +378,7 @@ public class GroupDatabase {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return "member"; // پیشفرض
|
return "member";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -444,7 +445,7 @@ public class GroupDatabase {
|
|||||||
stmt.setObject(2, userId);
|
stmt.setObject(2, userId);
|
||||||
|
|
||||||
ResultSet rs = stmt.executeQuery();
|
ResultSet rs = stmt.executeQuery();
|
||||||
return rs.next(); // اگر رکوردی پیدا شد یعنی owner است
|
return rs.next();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -460,7 +461,7 @@ public class GroupDatabase {
|
|||||||
ResultSet rs = stmt.executeQuery();
|
ResultSet rs = stmt.executeQuery();
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
String role = rs.getString("role");
|
String role = rs.getString("role");
|
||||||
return "admin".equals(role) || "owner".equals(role); // owner هم admin هست
|
return "admin".equals(role) || "owner".equals(role);
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -508,7 +509,7 @@ public class GroupDatabase {
|
|||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
JSONObject member = new JSONObject();
|
JSONObject member = new JSONObject();
|
||||||
member.put("profile_name", rs.getString("profile_name"));
|
member.put("profile_name", rs.getString("profile_name"));
|
||||||
member.put("user_id", rs.getString("user_id")); // آیدی قابل نمایش
|
member.put("user_id", rs.getString("user_id"));
|
||||||
member.put("internal_uuid", rs.getObject("internal_uuid").toString());
|
member.put("internal_uuid", rs.getObject("internal_uuid").toString());
|
||||||
member.put("role", rs.getString("role"));
|
member.put("role", rs.getString("role"));
|
||||||
|
|
||||||
@@ -556,7 +557,7 @@ public class GroupDatabase {
|
|||||||
|
|
||||||
public static boolean transferOwnership(UUID groupId, UUID newOwnerId) {
|
public static boolean transferOwnership(UUID groupId, UUID newOwnerId) {
|
||||||
String demoteOldOwner = "UPDATE group_members SET role = 'admin' WHERE group_id = ? AND role = 'owner'";
|
String demoteOldOwner = "UPDATE group_members SET role = 'admin' WHERE group_id = ? AND role = 'owner'";
|
||||||
String promoteNewOwner = "UPDATE group_members SET role = 'owner' WHERE group_id = ? AND user_id = ?";
|
String promoteNewOwner = "UPDATE group_members SET role = 'owner', permissions = '{}'::jsonb WHERE group_id = ? AND user_id = ?";
|
||||||
|
|
||||||
try (Connection conn = ConnectionDb.connect()) {
|
try (Connection conn = ConnectionDb.connect()) {
|
||||||
conn.setAutoCommit(false);
|
conn.setAutoCommit(false);
|
||||||
@@ -600,4 +601,82 @@ public class GroupDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<UUID> getGroupMemberUUIDs(UUID groupId) {
|
||||||
|
List<UUID> memberIds = new ArrayList<>();
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement("SELECT user_id FROM group_members WHERE group_id = ?")) {
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
memberIds.add(UUID.fromString(rs.getString("user_id")));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return memberIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean updateAdminPermissions(UUID groupId, UUID userId, JSONObject permissions) {
|
||||||
|
String sql = "UPDATE group_members SET permissions = ?::jsonb WHERE group_id = ? AND user_id = ? AND role = 'admin'";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, permissions.toString());
|
||||||
|
stmt.setObject(2, groupId);
|
||||||
|
stmt.setObject(3, userId);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMember(UUID groupId, UUID userId) {
|
||||||
|
String sql = "SELECT 1 FROM group_members WHERE group_id = ? AND user_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
return rs.next();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static List<User> searchGroupMembers(UUID groupId, String keyword) {
|
||||||
|
// List<User> result = new ArrayList<>();
|
||||||
|
// String sql = """
|
||||||
|
// SELECT u.*
|
||||||
|
// FROM users u
|
||||||
|
// JOIN group_members gm ON gm.user_id = u.internal_uuid
|
||||||
|
// WHERE gm.group_id = ?
|
||||||
|
// AND (
|
||||||
|
// LOWER(u.profile_name) LIKE ?
|
||||||
|
// OR LOWER(u.username) LIKE ?
|
||||||
|
// OR LOWER(u.user_id) LIKE ?
|
||||||
|
// )
|
||||||
|
// """;
|
||||||
|
//
|
||||||
|
// try (Connection conn = ConnectionDb.connect();
|
||||||
|
// PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
//
|
||||||
|
// stmt.setObject(1, groupId);
|
||||||
|
// String likePattern = "%" + keyword.toLowerCase() + "%";
|
||||||
|
// stmt.setString(2, likePattern);
|
||||||
|
// stmt.setString(3, likePattern);
|
||||||
|
// stmt.setString(4, likePattern);
|
||||||
|
//
|
||||||
|
// ResultSet rs = stmt.executeQuery();
|
||||||
|
// while (rs.next()) {
|
||||||
|
// User user = User.fromResultSet(rs);
|
||||||
|
// result.add(user);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// } catch (SQLException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,13 +9,58 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class userDatabase {
|
public class userDatabase {
|
||||||
|
|
||||||
|
|
||||||
public userDatabase() {
|
public userDatabase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Connection getConnection() throws SQLException {
|
public static boolean isUserOnline(UUID userId) {
|
||||||
|
String sql = "SELECT status FROM users WHERE internal_uuid = ?";
|
||||||
|
|
||||||
|
try (Connection conn = getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
String status = rs.getString("status");
|
||||||
|
return "online".equalsIgnoreCase(status);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static Connection getConnection() throws SQLException {
|
||||||
return ConnectionDb.connect();
|
return ConnectionDb.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getLastSeen(UUID userId) {
|
||||||
|
String sql = "SELECT last_seen FROM users WHERE internal_uuid = ?";
|
||||||
|
|
||||||
|
try (Connection conn = getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
Timestamp lastSeen = rs.getTimestamp("last_seen");
|
||||||
|
if (lastSeen != null) {
|
||||||
|
return lastSeen.toLocalDateTime().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public User findByUserId(String userId) {
|
public User findByUserId(String userId) {
|
||||||
String query = "SELECT * FROM users WHERE user_id = ?";
|
String query = "SELECT * FROM users WHERE user_id = ?";
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ public class ChatEntry {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChatEntry() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 🟩 گتر و ستر جدید
|
// 🟩 گتر و ستر جدید
|
||||||
public boolean isOwner() {
|
public boolean isOwner() {
|
||||||
return isOwner;
|
return isOwner;
|
||||||
@@ -54,7 +58,6 @@ public class ChatEntry {
|
|||||||
isAdmin = admin;
|
isAdmin = admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// سایر گترها
|
|
||||||
public UUID getId() {
|
public UUID getId() {
|
||||||
return internalId;
|
return internalId;
|
||||||
}
|
}
|
||||||
@@ -87,4 +90,22 @@ public class ChatEntry {
|
|||||||
public void setPermissions(JSONObject permissions) {
|
public void setPermissions(JSONObject permissions) {
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayId(String id) {this.displayId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImageUrl(String image_url) {this.imageUrl = image_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {this.type =type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String internalId) {this.internalId = UUID.fromString(internalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public class ResponseModel {
|
|||||||
private String status;
|
private String status;
|
||||||
private String message;
|
private String message;
|
||||||
private JSONObject data;
|
private JSONObject data;
|
||||||
|
private String requestId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ResponseModel(String status, String message) {
|
public ResponseModel(String status, String message) {
|
||||||
@@ -29,4 +31,20 @@ public class ResponseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject getData() {return this.data;}
|
public JSONObject getData() {return this.data;}
|
||||||
|
|
||||||
|
public void setRequestId(String requestId) {
|
||||||
|
this.requestId = requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JSONObject toJson() {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("status", this.status);
|
||||||
|
json.put("message", this.message);
|
||||||
|
json.put("data", this.data != null ? this.data : JSONObject.NULL);
|
||||||
|
if (this.requestId != null) {
|
||||||
|
json.put("request_id", this.requestId);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -176,7 +176,7 @@ public class RealTimeEventDispatcher {
|
|||||||
|
|
||||||
public static void notifyAddedToChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
public static void notifyAddedToChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("chat_type", type); // group یا channel
|
data.put("chat_type", type);
|
||||||
data.put("chat_id", chatId.toString());
|
data.put("chat_id", chatId.toString());
|
||||||
data.put("chat_name", chatName);
|
data.put("chat_name", chatName);
|
||||||
data.put("image_url", imageUrl);
|
data.put("image_url", imageUrl);
|
||||||
@@ -246,5 +246,63 @@ public class RealTimeEventDispatcher {
|
|||||||
broadcastToUsers(contacts, event);
|
broadcastToUsers(contacts, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendGroupOrChannelUpdate(String type, UUID chatId, String name, String imageUrl, String description, List<UUID> affectedUsers) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("chat_type", type);
|
||||||
|
data.put("chat_id", chatId.toString());
|
||||||
|
data.put("name", name);
|
||||||
|
data.put("image_url", imageUrl);
|
||||||
|
data.put("description", description != null ? description : "");
|
||||||
|
|
||||||
|
JSONObject event = new JSONObject();
|
||||||
|
event.put("action", "chat_updated");
|
||||||
|
event.put("data", data);
|
||||||
|
|
||||||
|
broadcastToUsers(affectedUsers, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void notifyBecameAdmin(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("chat_type", type); // group or channel
|
||||||
|
data.put("chat_id", chatId.toString());
|
||||||
|
data.put("chat_name", chatName);
|
||||||
|
data.put("image_url", imageUrl);
|
||||||
|
|
||||||
|
JSONObject event = new JSONObject();
|
||||||
|
event.put("action", "became_admin");
|
||||||
|
event.put("data", data);
|
||||||
|
|
||||||
|
sendToUser(userId, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void notifyRemovedAdminFromChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("chat_type", type);
|
||||||
|
data.put("chat_id", chatId.toString());
|
||||||
|
data.put("chat_name", chatName);
|
||||||
|
data.put("image_url", imageUrl);
|
||||||
|
|
||||||
|
JSONObject event = new JSONObject();
|
||||||
|
event.put("action", "removed_admin");
|
||||||
|
event.put("data", data);
|
||||||
|
|
||||||
|
sendToUser(userId, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void sendOwnershipTransferred(String type, UUID chatId, String chatName, List<UUID> 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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package org.to.telegramfinalproject.UI;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.PasswordField;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.to.telegramfinalproject.Client.ClientConnection;
|
||||||
|
import org.to.telegramfinalproject.Database.userDatabase;
|
||||||
|
import org.to.telegramfinalproject.Models.User;
|
||||||
|
import org.to.telegramfinalproject.Security.PasswordHashing;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class LoginForm {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button loginButton;
|
||||||
|
@FXML
|
||||||
|
private Button backButton;
|
||||||
|
@FXML private TextField usernameField;
|
||||||
|
@FXML private PasswordField passwordField;
|
||||||
|
|
||||||
|
private ClientConnection connection;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = new ClientConnection("localhost", 8000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Could not connect to server: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
loginButton.setOnAction(e -> {
|
||||||
|
String username = usernameField.getText();
|
||||||
|
String password = passwordField.getText();
|
||||||
|
|
||||||
|
JSONObject request = new JSONObject();
|
||||||
|
request.put("action", "login");
|
||||||
|
request.put("user_id", JSONObject.NULL);
|
||||||
|
request.put("username", username);
|
||||||
|
request.put("password", password);
|
||||||
|
request.put("profile_name", JSONObject.NULL);
|
||||||
|
if (connection!=null) {
|
||||||
|
connection.send(request.toString());
|
||||||
|
}
|
||||||
|
userDatabase userDb = new userDatabase();
|
||||||
|
User user = userDb.findByUsername(username);
|
||||||
|
|
||||||
|
if(!userDb.existsByUsername(username)){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Invalid username");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
else if(!PasswordHashing.verify(password,user.getPassword())){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Invalid password");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
else if(!PasswordHashing.verify(password,user.getPassword()) && !userDb.existsByUsername(username)){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Invalid password and username");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
try {
|
||||||
|
String responseStr = connection.receive();
|
||||||
|
JSONObject response = new JSONObject(responseStr);
|
||||||
|
System.out.println("Status: " + response.getString("status"));
|
||||||
|
System.out.println("Message: " + response.getString("message"));
|
||||||
|
Alert alert = new Alert(Alert.AlertType.INFORMATION, " Message: " + response.getString("message"));
|
||||||
|
alert.show();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Error receiving response: " + ex.getMessage());
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
backButton.setOnAction(e -> {
|
||||||
|
switchScene("login_view.fxml");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchScene(String fxmlFile) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/" + fxmlFile));
|
||||||
|
Parent root = loader.load();
|
||||||
|
|
||||||
|
|
||||||
|
Stage stage = (Stage) backButton.getScene().getWindow();
|
||||||
|
stage.setScene(new Scene(root));
|
||||||
|
stage.show();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package org.to.telegramfinalproject.UI;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.PasswordField;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.to.telegramfinalproject.Client.ClientConnection;
|
||||||
|
import org.to.telegramfinalproject.Database.userDatabase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class RegisterForm {
|
||||||
|
@FXML
|
||||||
|
private Button submitButton;
|
||||||
|
@FXML
|
||||||
|
private Button backButton;
|
||||||
|
@FXML private TextField userIdField;
|
||||||
|
@FXML private TextField usernameField;
|
||||||
|
@FXML private TextField profileNameField;
|
||||||
|
@FXML private PasswordField passwordField;
|
||||||
|
@FXML private PasswordField confirmPasswordField;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ClientConnection connection;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = new ClientConnection("localhost", 8000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Could not connect to server: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
submitButton.setOnAction(e -> {
|
||||||
|
String userID = userIdField.getText();
|
||||||
|
String username = usernameField.getText();
|
||||||
|
String profile_name = profileNameField.getText();
|
||||||
|
String password = passwordField.getText();
|
||||||
|
String confirmPass =confirmPasswordField.getText();
|
||||||
|
JSONObject request = new JSONObject();
|
||||||
|
String passwordRegex = "\\b(?=[^\\s]*[A-Z])(?=[^\\s]*[a-z])(?=[^\\s]*\\d)(?=[^\\s]*[!@#$%^&*])[^\\s]{8,}\\b";
|
||||||
|
|
||||||
|
userDatabase userDb = new userDatabase();
|
||||||
|
if(password.equals(confirmPass) && password.matches(passwordRegex) && !userDb.existsByUserId(userID)&& !userDb.existsByUsername(username)){
|
||||||
|
try {
|
||||||
|
request.put("action", "register");
|
||||||
|
request.put("user_id", userID);
|
||||||
|
request.put("username", username);
|
||||||
|
request.put("password", password);
|
||||||
|
request.put("profile_name", profile_name);
|
||||||
|
connection.send(request.toString());
|
||||||
|
Alert alert = new Alert(Alert.AlertType.INFORMATION, "Registration is successful");
|
||||||
|
alert.show();
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Error receiving response: " + ex.getMessage());
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(!password.equals(confirmPass) && password.matches(passwordRegex)) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Password doesn't match");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
else if(userDb.existsByUserId(userID))
|
||||||
|
{
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "User ID is already exist");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
else if(userDb.existsByUsername(username)){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Username is already exist");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR, "Password isn't Strong enough");
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
backButton.setOnAction(e -> {
|
||||||
|
switchScene("login_view.fxml");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchScene(String fxmlFile) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/" + fxmlFile));
|
||||||
|
Parent root = loader.load();
|
||||||
|
|
||||||
|
|
||||||
|
Stage stage = (Stage) backButton.getScene().getWindow();
|
||||||
|
stage.setScene(new Scene(root));
|
||||||
|
stage.show();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user