RealTime and openChat
This commit is contained in:
@@ -13,4 +13,6 @@ module org.to.telegramfinalproject {
|
|||||||
requires java.sql;
|
requires java.sql;
|
||||||
opens org.to.telegramfinalproject to javafx.fxml;
|
opens org.to.telegramfinalproject to javafx.fxml;
|
||||||
exports org.to.telegramfinalproject;
|
exports org.to.telegramfinalproject;
|
||||||
|
exports org.to.telegramfinalproject.Client;
|
||||||
|
opens org.to.telegramfinalproject.Client to javafx.fxml;
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
|||||||
|
package org.to.telegramfinalproject.Client;
|
||||||
|
|
||||||
|
public class EventProcessorThread extends Thread {
|
||||||
|
private final ActionHandler handler;
|
||||||
|
|
||||||
|
public EventProcessorThread(ActionHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
setDaemon(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
handler.processIncomingEvents();
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,72 +15,107 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
System.out.println("👂 Real-Time Listener started.");
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if (!response.has("action")) continue;
|
if (response.has("action")) {
|
||||||
String action = response.getString("action");
|
String action = response.getString("action");
|
||||||
|
if (isRealTimeEvent(action)) {
|
||||||
switch (action) {
|
handleRealTimeEvent(response);
|
||||||
case "new_message" -> {
|
} else {
|
||||||
JSONObject msg = response.getJSONObject("data");
|
TelegramClient.responseQueue.put(response);
|
||||||
System.out.println("\n🔔 New Message:");
|
|
||||||
System.out.println("From: " + msg.getString("sender"));
|
|
||||||
System.out.println("Time: " + msg.getString("time"));
|
|
||||||
System.out.println("Content: " + msg.getString("content"));
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
}
|
||||||
|
} else if (response.has("status") && response.has("message")) {
|
||||||
case "message_edited" -> {
|
TelegramClient.responseQueue.put(response);
|
||||||
JSONObject msg = response.getJSONObject("data");
|
} else {
|
||||||
System.out.println("\n✏️ Message Edited:");
|
TelegramClient.responseQueue.put(response);
|
||||||
System.out.println("ID: " + msg.getString("message_id"));
|
|
||||||
System.out.println("New Content: " + msg.getString("new_content"));
|
|
||||||
System.out.println("Edit Time: " + msg.getString("edit_time"));
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
case "message_deleted" -> {
|
|
||||||
JSONObject msg = response.getJSONObject("data");
|
|
||||||
System.out.println("\n🗑️ Message Deleted:");
|
|
||||||
System.out.println("Message ID: " + msg.getString("message_id"));
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
case "status_change" -> {
|
|
||||||
JSONObject msg = response.getJSONObject("data");
|
|
||||||
System.out.println("\n🔄 User Status Changed:");
|
|
||||||
System.out.println("User: " + msg.getString("user_id"));
|
|
||||||
System.out.println("Status: " + msg.getString("status"));
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
case "system_notification" -> {
|
|
||||||
JSONObject msg = response.getJSONObject("data");
|
|
||||||
System.out.println("\n⚠️ System Notification:");
|
|
||||||
System.out.println(msg.getString("content"));
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
case "contact_added" ->{
|
|
||||||
System.out.println("\n🔔 You were added by a new contact: " + response.getString("user_id"));
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
default -> {
|
|
||||||
if (!action.equals("search")) { // ignore action: search
|
|
||||||
System.out.println("\n❓ Unknown action received: " + action);
|
|
||||||
System.out.print(">> ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("🔴 Listener stopped: " + e.getMessage());
|
System.out.println("🔴 Listener stopped: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRealTimeEvent(String action) {
|
||||||
|
return switch (action) {
|
||||||
|
case "new_message", "message_edited", "message_deleted",
|
||||||
|
"user_status_changed", "added_to_group", "added_to_channel",
|
||||||
|
"update_group_or_channel", "chat_deleted",
|
||||||
|
"blocked_by_user", "unblocked_by_user", "message_seen" -> true;
|
||||||
|
default -> false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRealTimeEvent(JSONObject response) {
|
||||||
|
String action = response.getString("action");
|
||||||
|
JSONObject msg = response.getJSONObject("data");
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "new_message" -> {
|
||||||
|
System.out.println("\n🔔 New Message:");
|
||||||
|
System.out.println("From: " + msg.getString("sender"));
|
||||||
|
System.out.println("Time: " + msg.getString("time"));
|
||||||
|
System.out.println("Content: " + msg.getString("content"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "message_edited" -> {
|
||||||
|
System.out.println("\n✏️ Message Edited:");
|
||||||
|
System.out.println("ID: " + msg.getString("message_id"));
|
||||||
|
System.out.println("New Content: " + msg.getString("new_content"));
|
||||||
|
System.out.println("Edit Time: " + msg.getString("edited_at"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "message_deleted" -> {
|
||||||
|
System.out.println("\n🗑️ Message Deleted:");
|
||||||
|
System.out.println("Message ID: " + msg.getString("message_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "user_status_changed" -> {
|
||||||
|
System.out.println("\n🔄 User Status Changed:");
|
||||||
|
System.out.println("User: " + msg.getString("user_id"));
|
||||||
|
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" -> {
|
||||||
|
System.out.println("\n⛔ You were blocked by user: " + msg.getString("blocker_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "unblocked_by_user" -> {
|
||||||
|
System.out.println("\n✅ You were unblocked by user: " + msg.getString("unblocker_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "message_seen" -> {
|
||||||
|
System.out.println("\n👁️ Your message was seen:");
|
||||||
|
System.out.println("Message ID: " + msg.getString("message_id"));
|
||||||
|
System.out.println("Seen at: " + msg.getString("seen_at"));
|
||||||
|
}
|
||||||
|
|
||||||
|
default -> {
|
||||||
|
System.out.println("\n❓ Unknown real-time action: " + action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print(">> ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.to.telegramfinalproject.Client;
|
||||||
|
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
public class RealTimeBuffer {
|
||||||
|
public static final BlockingQueue<JSONObject> incomingEvents = new LinkedBlockingQueue<>();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -9,6 +9,8 @@ import java.io.PrintWriter;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
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.LinkedBlockingQueue;
|
||||||
|
|
||||||
public class TelegramClient {
|
public class TelegramClient {
|
||||||
private static final String SERVER_HOST = "localhost";
|
private static final String SERVER_HOST = "localhost";
|
||||||
@@ -18,6 +20,7 @@ public class TelegramClient {
|
|||||||
private PrintWriter out;
|
private PrintWriter out;
|
||||||
private final Scanner scanner;
|
private final Scanner scanner;
|
||||||
ActionHandler handler = null;
|
ActionHandler handler = null;
|
||||||
|
public static BlockingQueue<JSONObject> responseQueue = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
public TelegramClient() {
|
public TelegramClient() {
|
||||||
this.scanner = new Scanner(System.in);
|
this.scanner = new Scanner(System.in);
|
||||||
@@ -28,76 +31,52 @@ public class TelegramClient {
|
|||||||
this.socket = new Socket(SERVER_HOST, SERVER_PORT);
|
this.socket = new Socket(SERVER_HOST, SERVER_PORT);
|
||||||
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
||||||
this.out = new PrintWriter(this.socket.getOutputStream(), true);
|
this.out = new PrintWriter(this.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);
|
this.handler = new ActionHandler(this.out, this.in, this.scanner);
|
||||||
this.showMainMenu();
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Error connecting to server: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 👂 فقط این ترد مجاز به خواندن از in است
|
||||||
|
Thread listenerThread = new Thread(new IncomingMessageListener(in));
|
||||||
|
listenerThread.setDaemon(true);
|
||||||
|
listenerThread.start();
|
||||||
|
|
||||||
|
showMainMenu();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("❌ Error connecting to server: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showMainMenu() {
|
private void showMainMenu() {
|
||||||
while(true) {
|
while (true) {
|
||||||
System.out.println("Main Menu:");
|
System.out.println("Main Menu:");
|
||||||
System.out.println("1. Register");
|
System.out.println("1. Register");
|
||||||
System.out.println("2. Login");
|
System.out.println("2. Login");
|
||||||
System.out.println("3. Exit");
|
System.out.println("3. Exit");
|
||||||
System.out.print("Choose an option: ");
|
System.out.print("Choose an option: ");
|
||||||
switch (this.scanner.nextLine()) {
|
String choice = scanner.nextLine();
|
||||||
case "1":
|
|
||||||
this.handler.register();
|
switch (choice) {
|
||||||
break;
|
case "1" -> handler.register();
|
||||||
case "2":
|
case "2" -> {
|
||||||
this.handler.loginHandler();
|
handler.loginHandler();
|
||||||
if (Session.currentUser != null) {
|
if (Session.currentUser != null) {
|
||||||
System.out.println("Login successful.");
|
System.out.println("✅ Login successful.");
|
||||||
UUID internalId = UUID.fromString(Session.currentUser.getString("internalUUID"));
|
UUID internalId = UUID.fromString(Session.currentUser.getString("internal_uuid"));
|
||||||
//Thread listenerThread = new Thread(new IncomingMessageListener(in));
|
handler.userMenu(internalId);
|
||||||
//listenerThread.setDaemon(true);
|
|
||||||
//listenerThread.start();
|
|
||||||
this.handler.userMenu(internalId);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Login failed.");
|
System.out.println("❌ Login failed.");
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case "3":
|
case "3" -> {
|
||||||
System.out.println("Disconnecting...");
|
System.out.println("Exiting...");
|
||||||
|
|
||||||
if (Session.currentUser != null && Session.currentUser.has("internalUUID")) {
|
|
||||||
try {
|
|
||||||
JSONObject logoutRequest = new JSONObject();
|
|
||||||
logoutRequest.put("action", "logout");
|
|
||||||
logoutRequest.put("user_id", Session.currentUser.getString("internalUUID"));
|
|
||||||
out.println(logoutRequest.toString());
|
|
||||||
in.readLine();
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("Failed to notify server on logout: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (socket != null) socket.close();
|
|
||||||
if (in != null) in.close();
|
|
||||||
if (out != null) out.close();
|
|
||||||
System.out.println("Disconnected.");
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Error closing connection: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
default -> System.out.println("Invalid choice.");
|
||||||
default:
|
|
||||||
System.out.println("Invalid choice. Please try again.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
TelegramClient client = new TelegramClient();
|
new TelegramClient().start();
|
||||||
client.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.to.telegramfinalproject.Database;
|
package org.to.telegramfinalproject.Database;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Models.Channel;
|
import org.to.telegramfinalproject.Models.Channel;
|
||||||
import org.to.telegramfinalproject.Models.Group;
|
import org.to.telegramfinalproject.Models.Group;
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ public class ChannelDatabase {
|
|||||||
|
|
||||||
public static List<UUID> getSubscriberUUIDs(UUID channelInternalUUID) {
|
public static List<UUID> getSubscriberUUIDs(UUID channelInternalUUID) {
|
||||||
List<UUID> subscriberIds = new ArrayList<>();
|
List<UUID> subscriberIds = new ArrayList<>();
|
||||||
String sql = "SELECT user_id FROM channel_subscribe WHERE channel_id = ?";
|
String sql = "SELECT user_id FROM channel_subscribers WHERE channel_id = ?";
|
||||||
|
|
||||||
try (Connection conn = ConnectionDb.connect();
|
try (Connection conn = ConnectionDb.connect();
|
||||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
@@ -128,7 +129,7 @@ public class ChannelDatabase {
|
|||||||
|
|
||||||
|
|
||||||
public static boolean isUserSubscribed(UUID userId, UUID channelInternalId) {
|
public static boolean isUserSubscribed(UUID userId, UUID channelInternalId) {
|
||||||
String sql = "SELECT * FROM channel_subscribe WHERE user_id = ? AND channel_id = ?";
|
String sql = "SELECT * FROM channel_subscribers WHERE user_id = ? AND channel_id = ?";
|
||||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) {
|
try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
stmt.setObject(1, userId);
|
stmt.setObject(1, userId);
|
||||||
stmt.setObject(2, channelInternalId);
|
stmt.setObject(2, channelInternalId);
|
||||||
@@ -240,12 +241,14 @@ public class ChannelDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addSubscriber(UUID channelId, UUID userId) {
|
public static void addSubscriber(UUID channelId, UUID userId, String role) {
|
||||||
String sql = "INSERT INTO channel_subscribers (channel_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
|
String sql = "INSERT INTO channel_subscribers (channel_id, user_id, role) VALUES (?, ?, ?) ON CONFLICT DO NOTHING";
|
||||||
|
|
||||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) {
|
try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
stmt.setObject(1, channelId);
|
stmt.setObject(1, channelId);
|
||||||
stmt.setObject(2, userId);
|
stmt.setObject(2, userId);
|
||||||
|
stmt.setString(3, role);
|
||||||
|
|
||||||
stmt.executeUpdate();
|
stmt.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -279,4 +282,142 @@ public class ChannelDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean addOwnerToChannel(UUID channelId, UUID userId) {
|
||||||
|
String sql = "INSERT INTO channel_subscribers (channel_id, user_id, role) VALUES (?, ?, 'owner')";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean addAdminToChannel(UUID channelId, UUID userId, JSONObject permissions) {
|
||||||
|
String sql = "UPDATE channel_subscribers SET role = 'admin', permissions = ?::jsonb WHERE channel_id = ? AND user_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setString(1, permissions.toString());
|
||||||
|
stmt.setObject(2, channelId);
|
||||||
|
stmt.setObject(3, userId);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getChannelRole(UUID channelId, UUID userId) {
|
||||||
|
String sql = "SELECT role FROM channel_subscribers WHERE channel_id = ? AND user_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return rs.getString("role");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "subscriber"; // پیشفرض
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static JSONObject getChannelPermissions(UUID channelId, UUID userId) {
|
||||||
|
String sql = "SELECT permissions FROM channel_subscribers WHERE channel_id = ? AND user_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return new JSONObject(rs.getString("permissions"));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean updateChannelAdminPermissions(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(3, userId);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static List<JSONObject> getChannelAdminsAndOwner(UUID channelId) {
|
||||||
|
String sql = "SELECT user_id, role, permissions FROM channel_subscribers WHERE channel_id = ? AND role IN ('owner', 'admin')";
|
||||||
|
List<JSONObject> admins = new ArrayList<>();
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("user_id", rs.getObject("user_id").toString());
|
||||||
|
obj.put("role", rs.getString("role"));
|
||||||
|
obj.put("permissions", new JSONObject(rs.getString("permissions")));
|
||||||
|
admins.add(obj);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return admins;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isOwner(UUID channelId, UUID userId) {
|
||||||
|
String sql = "SELECT role FROM channel_subscribers WHERE channel_id = ? AND user_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return "owner".equals(rs.getString("role"));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isAdmin(UUID channelId, UUID userId) {
|
||||||
|
String sql = "SELECT role FROM channel_subscribers WHERE channel_id = ? AND user_id = ?";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
String role = rs.getString("role");
|
||||||
|
return "admin".equals(role) || "owner".equals(role); // owner هم admin هست
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,19 +49,47 @@ public class ContactDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean blockContact(UUID user_id, UUID contact_id) {
|
public static boolean toggleBlock(UUID userId, UUID targetId) {
|
||||||
String sql = "UPDATE contacts SET is_blocked = TRUE WHERE user_id = ? AND contact_id = ?";
|
String selectSql = "SELECT is_blocked FROM contacts WHERE user_id = ? AND contact_id = ?";
|
||||||
try (Connection connection = getConnection()) {
|
String updateSql = "UPDATE contacts SET is_blocked = ? WHERE user_id = ? AND contact_id = ?";
|
||||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
|
||||||
stmt.setObject(1, user_id);
|
try (Connection conn = getConnection();
|
||||||
stmt.setObject(2, contact_id);
|
PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
|
||||||
return stmt.executeUpdate() > 0;
|
|
||||||
|
selectStmt.setObject(1, userId);
|
||||||
|
selectStmt.setObject(2, targetId);
|
||||||
|
|
||||||
|
ResultSet rs = selectStmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
boolean currentlyBlocked = rs.getBoolean("is_blocked");
|
||||||
|
|
||||||
|
try (PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
|
||||||
|
updateStmt.setBoolean(1, !currentlyBlocked);
|
||||||
|
updateStmt.setObject(2, userId);
|
||||||
|
updateStmt.setObject(3, targetId);
|
||||||
|
updateStmt.executeUpdate();
|
||||||
|
}
|
||||||
|
return !currentlyBlocked;
|
||||||
|
} else {
|
||||||
|
// اگر رابطه وجود نداره، اول باید کاربر رو به contact ها اضافه کنیم
|
||||||
|
String insertSql = "INSERT INTO contacts (user_id, contact_id, is_blocked) VALUES (?, ?, ?)";
|
||||||
|
try (PreparedStatement insertStmt = conn.prepareStatement(insertSql)) {
|
||||||
|
insertStmt.setObject(1, userId);
|
||||||
|
insertStmt.setObject(2, targetId);
|
||||||
|
insertStmt.setBoolean(3, true);
|
||||||
|
insertStmt.executeUpdate();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean unblockContact(UUID user_id, UUID contact_id) {
|
public boolean unblockContact(UUID user_id, UUID contact_id) {
|
||||||
String sql = "UPDATE contacts SET is_blocked = FALSE WHERE user_id = ? AND contact_id = ?";
|
String sql = "UPDATE contacts SET is_blocked = FALSE WHERE user_id = ? AND contact_id = ?";
|
||||||
try (Connection connection = getConnection()) {
|
try (Connection connection = getConnection()) {
|
||||||
@@ -160,6 +188,76 @@ public class ContactDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean deleteChatOneSide(UUID currentUserId, UUID otherUserId) {
|
||||||
|
String sql = """
|
||||||
|
UPDATE private_chat
|
||||||
|
SET user1_deleted = CASE WHEN user1_id = ? THEN TRUE ELSE user1_deleted END,
|
||||||
|
user2_deleted = CASE WHEN user2_id = ? THEN TRUE ELSE user2_deleted END
|
||||||
|
WHERE (user1_id = ? AND user2_id = ?) OR (user1_id = ? AND user2_id = ?)
|
||||||
|
""";
|
||||||
|
|
||||||
|
try (Connection conn = getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
stmt.setObject(1, currentUserId);
|
||||||
|
stmt.setObject(2, currentUserId);
|
||||||
|
stmt.setObject(3, currentUserId);
|
||||||
|
stmt.setObject(4, otherUserId);
|
||||||
|
stmt.setObject(5, otherUserId);
|
||||||
|
stmt.setObject(6, currentUserId);
|
||||||
|
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean deleteChatBoth(UUID currentUserId, UUID otherUserId) {
|
||||||
|
String sqlDeleteMessages = """
|
||||||
|
DELETE FROM messages
|
||||||
|
WHERE receiver_type = 'private' AND (
|
||||||
|
(sender_id = ? AND receiver_id = ?) OR
|
||||||
|
(sender_id = ? AND receiver_id = ?)
|
||||||
|
)
|
||||||
|
""";
|
||||||
|
|
||||||
|
String sqlDeleteChat = """
|
||||||
|
DELETE FROM private_chat
|
||||||
|
WHERE (user1_id = ? AND user2_id = ?) OR (user1_id = ? AND user2_id = ?)
|
||||||
|
""";
|
||||||
|
|
||||||
|
try (Connection conn = getConnection()) {
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
try (PreparedStatement stmtMsg = conn.prepareStatement(sqlDeleteMessages);
|
||||||
|
PreparedStatement stmtChat = conn.prepareStatement(sqlDeleteChat)) {
|
||||||
|
|
||||||
|
stmtMsg.setObject(1, currentUserId);
|
||||||
|
stmtMsg.setObject(2, otherUserId);
|
||||||
|
stmtMsg.setObject(3, otherUserId);
|
||||||
|
stmtMsg.setObject(4, currentUserId);
|
||||||
|
stmtMsg.executeUpdate();
|
||||||
|
|
||||||
|
stmtChat.setObject(1, currentUserId);
|
||||||
|
stmtChat.setObject(2, otherUserId);
|
||||||
|
stmtChat.setObject(3, otherUserId);
|
||||||
|
stmtChat.setObject(4, currentUserId);
|
||||||
|
stmtChat.executeUpdate();
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
conn.rollback();
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.to.telegramfinalproject.Database;
|
package org.to.telegramfinalproject.Database;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Models.Group;
|
import org.to.telegramfinalproject.Models.Group;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -284,4 +286,223 @@ public class GroupDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean addOwnerToGroup(UUID groupId, UUID userId) {
|
||||||
|
String sql = "INSERT INTO group_members (group_id, user_id, role) VALUES (?, ?, 'owner')";
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean addAdminToGroup(UUID groupId, UUID userId, JSONObject permissions) {
|
||||||
|
String sql = """
|
||||||
|
UPDATE group_members
|
||||||
|
SET role = 'admin',
|
||||||
|
permissions = ?::jsonb
|
||||||
|
WHERE group_id = ? AND user_id = ? AND role = 'member'
|
||||||
|
""";
|
||||||
|
|
||||||
|
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 String getGroupRole(UUID groupId, UUID userId) {
|
||||||
|
String sql = "SELECT role 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();
|
||||||
|
if (rs.next()) {
|
||||||
|
return rs.getString("role");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "member"; // پیشفرض
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean updateGroupAdminPermissions(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 List<JSONObject> getGroupAdminsAndOwner(UUID groupId) {
|
||||||
|
String sql = "SELECT user_id, role, permissions FROM group_members WHERE group_id = ? AND role IN ('owner', 'admin')";
|
||||||
|
List<JSONObject> admins = new ArrayList<>();
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("user_id", rs.getObject("user_id").toString());
|
||||||
|
obj.put("role", rs.getString("role"));
|
||||||
|
obj.put("permissions", new JSONObject(rs.getString("permissions")));
|
||||||
|
admins.add(obj);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return admins;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isOwner(UUID groupId, UUID userId) {
|
||||||
|
String sql = "SELECT 1 FROM group_members WHERE group_id = ? AND user_id = ? AND role = 'owner'";
|
||||||
|
|
||||||
|
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(); // اگر رکوردی پیدا شد یعنی owner است
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAdmin(UUID groupId, UUID userId) {
|
||||||
|
String sql = "SELECT role 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();
|
||||||
|
if (rs.next()) {
|
||||||
|
String role = rs.getString("role");
|
||||||
|
return "admin".equals(role) || "owner".equals(role); // owner هم admin هست
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSONObject getGroupPermissions(UUID groupId, UUID userId) {
|
||||||
|
String sql = "SELECT permissions 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();
|
||||||
|
if (rs.next()) {
|
||||||
|
String permissions = rs.getString("permissions");
|
||||||
|
if (permissions != null && !permissions.isBlank()) {
|
||||||
|
return new JSONObject(permissions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static JSONArray getGroupMembers(UUID groupId) {
|
||||||
|
String sql = """
|
||||||
|
SELECT u.profile_name, u.user_id, u.internal_uuid, gm.role, gm.permissions
|
||||||
|
FROM group_members gm
|
||||||
|
JOIN users u ON gm.user_id = u.internal_uuid
|
||||||
|
WHERE gm.group_id = ?
|
||||||
|
""";
|
||||||
|
|
||||||
|
JSONArray members = new JSONArray();
|
||||||
|
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
|
||||||
|
while (rs.next()) {
|
||||||
|
JSONObject member = new JSONObject();
|
||||||
|
member.put("profile_name", rs.getString("profile_name"));
|
||||||
|
member.put("user_id", rs.getString("user_id")); // آیدی قابل نمایش
|
||||||
|
member.put("internal_uuid", rs.getObject("internal_uuid").toString());
|
||||||
|
member.put("role", rs.getString("role"));
|
||||||
|
|
||||||
|
String permissions = rs.getString("permissions");
|
||||||
|
if (permissions != null && !permissions.isBlank()) {
|
||||||
|
member.put("permissions", new JSONObject(permissions));
|
||||||
|
}
|
||||||
|
|
||||||
|
members.put(member);
|
||||||
|
}
|
||||||
|
|
||||||
|
return members;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean demoteAdminToMember(UUID groupId, UUID userId) {
|
||||||
|
String sql = "UPDATE group_members SET role = 'member', permissions = '{}'::jsonb WHERE group_id = ? AND user_id = ? AND role = 'admin'";
|
||||||
|
try (Connection conn = ConnectionDb.connect(); PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
stmt.setObject(2, userId);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean removeMemberFromGroup(UUID groupId, UUID userId) {
|
||||||
|
String sql = "DELETE 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);
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -217,6 +217,80 @@ public class MessageDatabase {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Message> privateChatHistory(UUID user1, UUID user2) {
|
||||||
|
List<Message> result = new ArrayList<>();
|
||||||
|
String sql = """
|
||||||
|
SELECT * FROM messages
|
||||||
|
WHERE receiver_type = 'private'
|
||||||
|
AND (
|
||||||
|
(sender_id = ? AND receiver_id = ?)
|
||||||
|
OR (sender_id = ? AND receiver_id = ?)
|
||||||
|
)
|
||||||
|
ORDER BY send_at
|
||||||
|
""";
|
||||||
|
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setObject(1, user1);
|
||||||
|
stmt.setObject(2, user2);
|
||||||
|
stmt.setObject(3, user2);
|
||||||
|
stmt.setObject(4, user1);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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> 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> searchMessagesInGroups(List<UUID> groupIds, String keyword) {
|
public static List<Message> searchMessagesInGroups(List<UUID> groupIds, String keyword) {
|
||||||
List<Message> result = new ArrayList<>();
|
List<Message> result = new ArrayList<>();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class userDatabase {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
User var6;
|
User var6;
|
||||||
try (Connection conn = this.getConnection()) {
|
try (Connection conn = ConnectionDb.connect()) {
|
||||||
try (PreparedStatement stmt = conn.prepareStatement(query)) {
|
try (PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||||
stmt.setString(1, userId);
|
stmt.setString(1, userId);
|
||||||
ResultSet rs = stmt.executeQuery();
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
|||||||
@@ -1,28 +1,70 @@
|
|||||||
package org.to.telegramfinalproject.Models;
|
package org.to.telegramfinalproject.Models;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ChatEntry {
|
public class ChatEntry {
|
||||||
private final String name;
|
private UUID internalId;
|
||||||
private final String id;
|
private String displayId;
|
||||||
private final String imageUrl;
|
private String name;
|
||||||
private final String type; // "private", "group", "channel"
|
private String imageUrl;
|
||||||
private final LocalDateTime lastMessageTime;
|
private String type;
|
||||||
|
private LocalDateTime lastMessageTime;
|
||||||
|
|
||||||
public ChatEntry(String name, String id, String imageUrl, String type, LocalDateTime lastMessageTime) {
|
// 🔹 نقشها
|
||||||
|
private boolean isOwner = false;
|
||||||
|
private boolean isAdmin = false;
|
||||||
|
private JSONObject permissions;
|
||||||
|
|
||||||
|
|
||||||
|
public ChatEntry(UUID internalId, String displayId, String name, String imageUrl, String type, LocalDateTime lastMessageTime) {
|
||||||
|
this.internalId = internalId;
|
||||||
|
this.displayId = displayId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.id = id;
|
|
||||||
this.imageUrl = imageUrl;
|
this.imageUrl = imageUrl;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.lastMessageTime = lastMessageTime;
|
this.lastMessageTime = lastMessageTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
// ✅ کانستراکتور اضافهشده برای پشتیبانی از نقشها (اختیاری، برای استفادههای جدید)
|
||||||
return name;
|
public ChatEntry(UUID internalId, String displayId, String name, String imageUrl, String type, LocalDateTime lastMessageTime, boolean isOwner, boolean isAdmin) {
|
||||||
|
this(internalId, displayId, name, imageUrl, type, lastMessageTime);
|
||||||
|
this.isOwner = isOwner;
|
||||||
|
this.isAdmin = isAdmin;
|
||||||
|
this.permissions = permissions;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
// 🟩 گتر و ستر جدید
|
||||||
return id;
|
public boolean isOwner() {
|
||||||
|
return isOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(boolean owner) {
|
||||||
|
isOwner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAdmin() {
|
||||||
|
return isAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAdmin(boolean admin) {
|
||||||
|
isAdmin = admin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// سایر گترها
|
||||||
|
public UUID getId() {
|
||||||
|
return internalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayId() {
|
||||||
|
return displayId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getImageUrl() {
|
public String getImageUrl() {
|
||||||
@@ -36,4 +78,13 @@ public class ChatEntry {
|
|||||||
public LocalDateTime getLastMessageTime() {
|
public LocalDateTime getLastMessageTime() {
|
||||||
return lastMessageTime;
|
return lastMessageTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JSONObject getPermissions() {
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissions(JSONObject permissions) {
|
||||||
|
this.permissions = permissions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class JsonUtil {
|
|||||||
|
|
||||||
public static JSONObject userToJson(User user) {
|
public static JSONObject userToJson(User user) {
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("internalUUID", user.getInternal_uuid().toString());
|
obj.put("internal_uuid", user.getInternal_uuid().toString());
|
||||||
obj.put("user_id", user.getUser_id() != null ?user.getUser_id().toString() :JSONObject.NULL);
|
obj.put("user_id", user.getUser_id() != null ?user.getUser_id().toString() :JSONObject.NULL);
|
||||||
obj.put("username", user.getUsername());
|
obj.put("username", user.getUsername());
|
||||||
obj.put("profile_name", user.getProfile_name());
|
obj.put("profile_name", user.getProfile_name());
|
||||||
@@ -154,11 +154,15 @@ public class JsonUtil {
|
|||||||
|
|
||||||
for (ChatEntry entry : chatList) {
|
for (ChatEntry entry : chatList) {
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("id", entry.getId() != null ?entry.getId() :JSONObject.NULL);
|
obj.put("internal_id", entry.getId().toString());
|
||||||
|
obj.put("id", entry.getDisplayId());
|
||||||
obj.put("name", entry.getName());
|
obj.put("name", entry.getName());
|
||||||
obj.put("image_url", entry.getImageUrl() != null ?entry.getImageUrl() :JSONObject.NULL);
|
obj.put("image_url", entry.getImageUrl());
|
||||||
obj.put("type", entry.getType());
|
obj.put("type", entry.getType());
|
||||||
obj.put("last_message_time", entry.getLastMessageTime() != null ? entry.getLastMessageTime().toString() : JSONObject.NULL);
|
obj.put("last_message_time", entry.getLastMessageTime() == null ? JSONObject.NULL : entry.getLastMessageTime().toString());
|
||||||
|
obj.put("is_owner", entry.isOwner());
|
||||||
|
obj.put("is_admin", entry.isAdmin());
|
||||||
|
|
||||||
|
|
||||||
jsonArray.put(obj);
|
jsonArray.put(obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PrivateChat {
|
public class PrivateChat {
|
||||||
private UUID chat_id;
|
private final UUID chat_id;
|
||||||
private UUID user1_id;
|
private UUID user1_id;
|
||||||
private UUID user2_id;
|
private UUID user2_id;
|
||||||
private LocalDateTime created_at;
|
private LocalDateTime created_at;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class ChannelService {
|
|||||||
boolean inserted = ChannelDatabase.insertChannel(internalUUID, channelId, channelName, creatorUUID, imageUrl, now);
|
boolean inserted = ChannelDatabase.insertChannel(internalUUID, channelId, channelName, creatorUUID, imageUrl, now);
|
||||||
|
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
ChannelDatabase.addSubscriber(internalUUID, creatorUUID); // اضافه کردن سازنده
|
ChannelDatabase.addSubscriber(internalUUID, creatorUUID,"owner");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Database.*;
|
import org.to.telegramfinalproject.Database.*;
|
||||||
import org.to.telegramfinalproject.Models.*;
|
import org.to.telegramfinalproject.Models.*;
|
||||||
|
import org.to.telegramfinalproject.Utils.GroupPermissionUtil;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@@ -92,17 +93,54 @@ public class ClientHandler implements Runnable {
|
|||||||
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");
|
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
|
||||||
chatList.add(new ChatEntry(target.getUser_id(), target.getProfile_name(), target.getImage_url(), "private", last));
|
|
||||||
|
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
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Group group : groups) {
|
for (Group group : groups) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
||||||
chatList.add(new ChatEntry(group.getGroup_id(), group.getGroup_name(), group.getImage_url(), "group", last));
|
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
boolean isAdmin = GroupDatabase.isAdmin(group.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
|
||||||
|
chatList.add(new ChatEntry(
|
||||||
|
group.getInternal_uuid(),
|
||||||
|
group.getGroup_id(),
|
||||||
|
group.getGroup_name(),
|
||||||
|
group.getImage_url(),
|
||||||
|
"group",
|
||||||
|
last,
|
||||||
|
isOwner,
|
||||||
|
isAdmin
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Channel channel : channels) {
|
for (Channel channel : channels) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
||||||
chatList.add(new ChatEntry(channel.getChannel_id(), channel.getChannel_name(), channel.getImage_url(), "channel", last));
|
boolean isOwner = ChannelDatabase.isOwner(channel.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
boolean isAdmin = ChannelDatabase.isAdmin(channel.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
|
||||||
|
chatList.add(new ChatEntry(
|
||||||
|
channel.getInternal_uuid(),
|
||||||
|
channel.getChannel_id(),
|
||||||
|
channel.getChannel_name(),
|
||||||
|
channel.getImage_url(),
|
||||||
|
"channel",
|
||||||
|
last,
|
||||||
|
isOwner,
|
||||||
|
isAdmin
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -115,21 +153,46 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "logout": {
|
case "logout": {
|
||||||
String user_Id = requestJson.optString("user_id");
|
String user_Id = requestJson.optString("user_id");
|
||||||
if (userId != null && !user_Id.isEmpty()) {
|
if (user_Id != null && !user_Id.isEmpty()) {
|
||||||
UUID uuid = UUID.fromString(user_Id);
|
try {
|
||||||
userDatabase.updateUserStatus(uuid, "offline");
|
UUID uuid = UUID.fromString(user_Id);
|
||||||
userDatabase.updateLastSeen(uuid);
|
userDatabase.updateUserStatus(uuid, "offline");
|
||||||
SessionManager.removeUser(uuid);
|
userDatabase.updateLastSeen(uuid);
|
||||||
response = new ResponseModel("success", "Logged out.");
|
SessionManager.removeUser(uuid);
|
||||||
|
response = new ResponseModel("success", "Logged out.");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
response = new ResponseModel("error", "Invalid UUID format.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
response = new ResponseModel("error", "Invalid user_id for logout.");
|
response = new ResponseModel("error", "Invalid user_id for logout.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "searchInUsers":{
|
||||||
|
String keyword = requestJson.optString("keyword");
|
||||||
|
List<JSONObject> results = new ArrayList<>();
|
||||||
|
String user_Id = requestJson.getString("user_id");
|
||||||
|
User currentUser = new userDatabase().findByUserId(user_Id);
|
||||||
|
UUID currentUserUUID = currentUser.getInternal_uuid();
|
||||||
|
|
||||||
|
for (User u : new userDatabase().searchUsers(keyword, currentUserUUID)) {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", "user");
|
||||||
|
obj.put("id", u.getUser_id());
|
||||||
|
obj.put("uuid", u.getInternal_uuid().toString());
|
||||||
|
obj.put("name", u.getProfile_name());
|
||||||
|
results.add(obj);
|
||||||
|
}
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("results", new JSONArray(results));
|
||||||
|
response = new ResponseModel("success", "Search results found", data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "search": {
|
case "search": {
|
||||||
String keyword = requestJson.optString("keyword");
|
String keyword = requestJson.optString("keyword");
|
||||||
List<JSONObject> results = new ArrayList<>();
|
List<JSONObject> results = new ArrayList<>();
|
||||||
@@ -228,7 +291,7 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "join_group": {
|
case "join_group": {
|
||||||
UUID userUUID = UUID.fromString(requestJson.getString("user_id")); // مستقیم internalUUID دریافت میکنیم
|
UUID userUUID = UUID.fromString(requestJson.getString("user_id"));
|
||||||
Group group = GroupDatabase.findByInternalUUID(UUID.fromString(requestJson.getString("id")));
|
Group group = GroupDatabase.findByInternalUUID(UUID.fromString(requestJson.getString("id")));
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
response = new ResponseModel("error", "Group not found.");
|
response = new ResponseModel("error", "Group not found.");
|
||||||
@@ -244,7 +307,7 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "join_channel": {
|
case "join_channel": {
|
||||||
UUID userUUID = UUID.fromString(requestJson.getString("user_id")); // مستقیم internalUUID دریافت میکنیم
|
UUID userUUID = UUID.fromString(requestJson.getString("user_id"));
|
||||||
Channel channel = ChannelDatabase.findByInternalUUID(UUID.fromString(requestJson.getString("id")));
|
Channel channel = ChannelDatabase.findByInternalUUID(UUID.fromString(requestJson.getString("id")));
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
response = new ResponseModel("error", "Channel not found.");
|
response = new ResponseModel("error", "Channel not found.");
|
||||||
@@ -261,57 +324,88 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
case "get_chat_info": {
|
case "get_chat_info": {
|
||||||
String id = requestJson.getString("receiver_id");
|
try {
|
||||||
String type = requestJson.getString("receiver_type");
|
String id = requestJson.getString("receiver_id");
|
||||||
JSONObject data = new JSONObject();
|
String type = requestJson.getString("receiver_type");
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "private" -> {
|
case "private" -> {
|
||||||
User u = new userDatabase().findByUserId(id);
|
userDatabase userDatabase = new userDatabase();
|
||||||
if (u != null) {
|
User u = userDatabase.findByUserId(id);
|
||||||
data.put("name", u.getProfile_name());
|
if (u == null) {
|
||||||
data.put("image_url", u.getImage_url());
|
try {
|
||||||
} else {
|
UUID uuid = UUID.fromString(id);
|
||||||
response = new ResponseModel("error", "User not found.");
|
u = userDatabase.findByInternalUUID(uuid);
|
||||||
break;
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u != null) {
|
||||||
|
data.put("internal_id", u.getInternal_uuid().toString());
|
||||||
|
data.put("name", u.getProfile_name());
|
||||||
|
data.put("image_url", u.getImage_url());
|
||||||
|
data.put("type", "private");
|
||||||
|
data.put("id", u.getUser_id());
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "User not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
case "group" -> {
|
||||||
case "group" -> {
|
Group group = GroupDatabase.findByInternalUUID(UUID.fromString(id));
|
||||||
Group g = GroupDatabase.findByGroupId(id);
|
if (group != null) {
|
||||||
if (g != null) {
|
data.put("internal_id", group.getInternal_uuid().toString());
|
||||||
data.put("name", g.getGroup_name());
|
data.put("name", group.getGroup_name());
|
||||||
data.put("image_url", g.getImage_url());
|
data.put("image_url", group.getImage_url());
|
||||||
} else {
|
data.put("type", "group");
|
||||||
response = new ResponseModel("error", "Group not found.");
|
data.put("id", group.getGroup_id());
|
||||||
break;
|
|
||||||
|
// اضافه کردن owner و admin بودن
|
||||||
|
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), currentUser.getInternal_uuid());
|
||||||
|
boolean isAdmin = GroupDatabase.isAdmin(group.getInternal_uuid(), currentUser.getInternal_uuid());
|
||||||
|
|
||||||
|
data.put("is_owner", isOwner);
|
||||||
|
data.put("is_admin", isAdmin);
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Group not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
case "channel" -> {
|
|
||||||
Channel c = ChannelDatabase.findByChannelId(id);
|
case "channel" -> {
|
||||||
if (c != null) {
|
Channel channel = ChannelDatabase.findByChannelId(id);
|
||||||
data.put("name", c.getChannel_name());
|
if (channel != null) {
|
||||||
data.put("image_url", c.getImage_url());
|
data.put("internal_id", channel.getInternal_uuid().toString());
|
||||||
} else {
|
data.put("name", channel.getChannel_name());
|
||||||
response = new ResponseModel("error", "Channel not found.");
|
data.put("image_url", channel.getImage_url());
|
||||||
|
data.put("type", "channel");
|
||||||
|
data.put("id", channel.getChannel_id());
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Channel not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default -> {
|
||||||
|
response = new ResponseModel("error", "Unknown type.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default -> {
|
if (response == null) {
|
||||||
response = new ResponseModel("error", "Unknown type.");
|
response = new ResponseModel("success", "Chat info fetched", data);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
response = new ResponseModel("error", "Error fetching chat info: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.has("name")) {
|
|
||||||
response = new ResponseModel("success", "Chat info fetched", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case "get_chat_list": {
|
case "get_chat_list": {
|
||||||
String userIdStr = requestJson.getString("user_id");
|
String userIdStr = requestJson.getString("user_id");
|
||||||
User user = new userDatabase().findByUserId(userIdStr);
|
User user = new userDatabase().findByUserId(userIdStr);
|
||||||
@@ -321,25 +415,58 @@ public class ClientHandler implements Runnable {
|
|||||||
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
||||||
|
|
||||||
List<ChatEntry> chatList = new ArrayList<>();
|
List<ChatEntry> chatList = new ArrayList<>();
|
||||||
|
|
||||||
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");
|
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
|
||||||
|
|
||||||
chatList.add(new ChatEntry(target.getUser_id(), target.getProfile_name(), target.getImage_url(), "private", last));
|
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
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Group group : groups) {
|
for (Group group : groups) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
||||||
chatList.add(new ChatEntry(group.getGroup_id(), group.getGroup_name(), group.getImage_url(), "group", last));
|
boolean isOwner = GroupDatabase.isOwner(group.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
boolean isAdmin = GroupDatabase.isAdmin(group.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
|
||||||
|
chatList.add(new ChatEntry(
|
||||||
|
group.getInternal_uuid(),
|
||||||
|
group.getGroup_id(),
|
||||||
|
group.getGroup_name(),
|
||||||
|
group.getImage_url(),
|
||||||
|
"group",
|
||||||
|
last,
|
||||||
|
isOwner,
|
||||||
|
isAdmin
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Channel channel : channels) {
|
for (Channel channel : channels) {
|
||||||
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
||||||
chatList.add(new ChatEntry(channel.getChannel_id(), channel.getChannel_name(), channel.getImage_url(), "channel", last));
|
boolean isOwner = ChannelDatabase.isOwner(channel.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
boolean isAdmin = ChannelDatabase.isAdmin(channel.getInternal_uuid(), user.getInternal_uuid());
|
||||||
|
|
||||||
|
chatList.add(new ChatEntry(
|
||||||
|
channel.getInternal_uuid(),
|
||||||
|
channel.getChannel_id(),
|
||||||
|
channel.getChannel_name(),
|
||||||
|
channel.getImage_url(),
|
||||||
|
"channel",
|
||||||
|
last,
|
||||||
|
isOwner,
|
||||||
|
isAdmin
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -354,7 +481,7 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
case "create_group": {
|
case "create_group": {
|
||||||
try {
|
try {
|
||||||
String groupId = requestJson.getString("group_id"); // ID نمایشی
|
String groupId = requestJson.getString("group_id");
|
||||||
String groupName = requestJson.getString("group_name");
|
String groupName = requestJson.getString("group_name");
|
||||||
String userIdStr = requestJson.getString("user_id");
|
String userIdStr = requestJson.getString("user_id");
|
||||||
String imageUrl = requestJson.optString("image_url", null);
|
String imageUrl = requestJson.optString("image_url", null);
|
||||||
@@ -363,16 +490,30 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
boolean created = GroupService.createGroup(groupId, groupName, creatorUUID, imageUrl);
|
boolean created = GroupService.createGroup(groupId, groupName, creatorUUID, imageUrl);
|
||||||
|
|
||||||
response = created
|
if (created) {
|
||||||
? new ResponseModel("success", "Group created.")
|
Group createdGroup = GroupDatabase.findByGroupId(groupId);
|
||||||
: new ResponseModel("error", "Group creation failed.");
|
if (createdGroup != null) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("internal_id", createdGroup.getInternal_uuid().toString());
|
||||||
|
data.put("id", createdGroup.getGroup_id());
|
||||||
|
data.put("name", createdGroup.getGroup_name());
|
||||||
|
data.put("image_url", createdGroup.getImage_url());
|
||||||
|
data.put("type", "group");
|
||||||
|
|
||||||
|
response = new ResponseModel("success", "Group created.", data);
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Group created but not found.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Group creation failed.");
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
response = new ResponseModel("error", "Error creating group: " + e.getMessage());
|
response = new ResponseModel("error", "Error creating group: " + e.getMessage());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case "create_channel": {
|
case "create_channel": {
|
||||||
try {
|
try {
|
||||||
String channelId = requestJson.getString("channel_id");
|
String channelId = requestJson.getString("channel_id");
|
||||||
@@ -384,9 +525,23 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
boolean created = ChannelService.createChannel(channelId, channelName, creatorUUID, imageUrl);
|
boolean created = ChannelService.createChannel(channelId, channelName, creatorUUID, imageUrl);
|
||||||
|
|
||||||
response = created
|
if (created) {
|
||||||
? new ResponseModel("success", "Channel created.")
|
Channel createdChannel = ChannelDatabase.findByChannelId(channelId);
|
||||||
: new ResponseModel("error", "Channel creation failed.");
|
if (createdChannel != null) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("internal_id", createdChannel.getInternal_uuid().toString());
|
||||||
|
data.put("id", createdChannel.getChannel_id());
|
||||||
|
data.put("name", createdChannel.getChannel_name());
|
||||||
|
data.put("image_url", createdChannel.getImage_url());
|
||||||
|
data.put("type", "channel");
|
||||||
|
|
||||||
|
response = new ResponseModel("success", "Channel created.", data);
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Channel created but not found.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Channel creation failed.");
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
response = new ResponseModel("error", "Error creating channel: " + e.getMessage());
|
response = new ResponseModel("error", "Error creating channel: " + e.getMessage());
|
||||||
@@ -395,6 +550,319 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "add_admin_to_channel": {
|
||||||
|
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("target_user_id"));
|
||||||
|
JSONObject permissions = requestJson.optJSONObject("permissions");
|
||||||
|
|
||||||
|
//if (!ChannelPermissionUtil.canAddAdmins(channelId, currentUser.getInternal_uuid())) {
|
||||||
|
//response = new ResponseModel("error", "You are not allowed to add admins to the channel.");
|
||||||
|
//break;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
boolean success = ChannelDatabase.addAdminToChannel(channelId, targetUserId, permissions);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Admin added to channel.")
|
||||||
|
: new ResponseModel("error", "Failed to add admin.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "edit_channel_admin_permissions": {
|
||||||
|
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("target_user_id"));
|
||||||
|
JSONObject permissions = requestJson.optJSONObject("permissions");
|
||||||
|
|
||||||
|
String role = ChannelDatabase.getChannelRole(channelId, currentUser.getInternal_uuid());
|
||||||
|
if (!role.equals("owner")) {
|
||||||
|
response = new ResponseModel("error", "Only owner can update admin permissions.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = ChannelDatabase.updateChannelAdminPermissions(channelId, targetUserId, permissions);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Permissions updated.")
|
||||||
|
: new ResponseModel("error", "Failed to update permissions.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "view_channel_admins": {
|
||||||
|
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
||||||
|
|
||||||
|
//if (!ChannelPermissionUtil.canAddAdmins(channelId, currentUser.getInternal_uuid())) {
|
||||||
|
// response = new ResponseModel("error", "You are not allowed to add admins to the channel.");
|
||||||
|
//break;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
List<JSONObject> admins = ChannelDatabase.getChannelAdminsAndOwner(channelId);
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("admins", new JSONArray(admins));
|
||||||
|
response = new ResponseModel("success", "Admins fetched.", data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "add_admin_to_group": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("user_id"));
|
||||||
|
JSONObject permissions = requestJson.optJSONObject("permissions");
|
||||||
|
|
||||||
|
if (!GroupPermissionUtil.canAddAdmins(groupId, currentUser.getInternal_uuid())) {
|
||||||
|
response = new ResponseModel("error", "You are not allowed to add admins.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean success = GroupDatabase.addAdminToGroup(groupId, targetUserId, permissions);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Admin added to group.")
|
||||||
|
: new ResponseModel("error", "Failed to add admin.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "edit_group_admin_permissions": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("target_user_id"));
|
||||||
|
JSONObject permissions = requestJson.optJSONObject("permissions");
|
||||||
|
|
||||||
|
if (!GroupPermissionUtil.canAddAdmins(groupId, currentUser.getInternal_uuid())) {
|
||||||
|
response = new ResponseModel("error", "You are not allowed to edit admin permissions.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = GroupDatabase.updateGroupAdminPermissions(groupId, targetUserId, permissions);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Permissions updated.")
|
||||||
|
: new ResponseModel("error", "Failed to update permissions.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "remove_admin_from_group": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
String targetUserIdStr = requestJson.getString("user_id");
|
||||||
|
|
||||||
|
// تبدیل user_id نمایشی به internal_uuid واقعی
|
||||||
|
User targetUser = new userDatabase().findByUserId(targetUserIdStr);
|
||||||
|
if (targetUser == null) {
|
||||||
|
response = new ResponseModel("error", "User not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID targetUserUUID = targetUser.getInternal_uuid();
|
||||||
|
|
||||||
|
if (!GroupPermissionUtil.canRemoveAdmins(groupId, currentUser.getInternal_uuid())) {
|
||||||
|
response = new ResponseModel("error", "You are not allowed to remove admins.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String targetRole = GroupDatabase.getGroupRole(groupId, targetUserUUID);
|
||||||
|
if (targetRole.equals("owner")) {
|
||||||
|
response = new ResponseModel("error", "You cannot remove the owner.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!targetRole.equals("admin")) {
|
||||||
|
response = new ResponseModel("error", "Target user is not an admin.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = GroupDatabase.demoteAdminToMember(groupId, targetUserUUID);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Admin removed successfully.")
|
||||||
|
: new ResponseModel("error", "Failed to remove admin.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "add_member_to_group": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("user_id"));
|
||||||
|
|
||||||
|
if (!GroupPermissionUtil.canAddMembers(groupId, currentUser.getInternal_uuid())) {
|
||||||
|
response = new ResponseModel("error", "You are not allowed to add members.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GroupDatabase.isUserInGroup(targetUserId, groupId)) {
|
||||||
|
response = new ResponseModel("error", "User is already a member.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = GroupDatabase.addMemberToGroup(targetUserId, groupId);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Member added to group.")
|
||||||
|
: new ResponseModel("error", "Failed to add member.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "remove_member_from_group": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("user_id"));
|
||||||
|
|
||||||
|
if (!GroupPermissionUtil.canRemoveMembers(groupId, currentUser.getInternal_uuid())) {
|
||||||
|
response = new ResponseModel("error", "You are not allowed to remove members.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String targetRole = GroupDatabase.getGroupRole(groupId, targetUserId);
|
||||||
|
if (targetRole.equals("owner") || targetRole.equals("admin")) {
|
||||||
|
response = new ResponseModel("error", "You cannot remove admins or owner this way.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = GroupDatabase.removeMemberFromGroup(groupId, targetUserId);
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Member removed from group.")
|
||||||
|
: new ResponseModel("error", "Failed to remove member.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "view_group_admins": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
|
||||||
|
String role = GroupDatabase.getGroupRole(groupId, currentUser.getInternal_uuid());
|
||||||
|
if (!role.equals("owner") && !role.equals("admin")) {
|
||||||
|
response = new ResponseModel("error", "You are not authorized to view admins.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<JSONObject> admins = GroupDatabase.getGroupAdminsAndOwner(groupId);
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("admins", new JSONArray(admins));
|
||||||
|
response = new ResponseModel("success", "Admins fetched.", data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "get_messages": {
|
||||||
|
try {
|
||||||
|
String receiverId = requestJson.getString("receiver_id");
|
||||||
|
String receiverType = requestJson.getString("receiver_type");
|
||||||
|
|
||||||
|
List<Message> messages = new ArrayList<>();
|
||||||
|
|
||||||
|
switch (receiverType) {
|
||||||
|
case "private" -> {
|
||||||
|
// تبدیل user_id به internal_uuid
|
||||||
|
User otherUser = new userDatabase().findByInternalUUID(UUID.fromString(receiverId));
|
||||||
|
if (otherUser == null) {
|
||||||
|
response = new ResponseModel("error", "User not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
messages = MessageDatabase.privateChatHistory(currentUser.getInternal_uuid(), otherUser.getInternal_uuid());
|
||||||
|
}
|
||||||
|
case "group" -> {
|
||||||
|
Group group = GroupDatabase.findByInternalUUID(UUID.fromString(receiverId));
|
||||||
|
if (group == null) {
|
||||||
|
response = new ResponseModel("error", "Group not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
messages = MessageDatabase.groupChatHistory(group.getInternal_uuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "channel" -> {
|
||||||
|
Channel channel = ChannelDatabase.findByChannelId(receiverId);
|
||||||
|
if (channel == null) {
|
||||||
|
response = new ResponseModel("error", "Channel not found.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
messages = MessageDatabase.channelChatHistory(channel.getInternal_uuid());
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
response = new ResponseModel("error", "Invalid receiver type.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
JSONArray messageArray = new JSONArray();
|
||||||
|
for (Message m : messages) {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("id", m.getMessage_id().toString());
|
||||||
|
obj.put("sender_id", m.getSender_id().toString());
|
||||||
|
obj.put("receiver_id", m.getReceiver_id().toString());
|
||||||
|
obj.put("receiver_type", m.getReceiver_type());
|
||||||
|
obj.put("content", m.getContent());
|
||||||
|
obj.put("send_at", m.getSend_at().toString());
|
||||||
|
messageArray.put(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("messages", messageArray);
|
||||||
|
|
||||||
|
response = new ResponseModel("success", "Messages fetched.", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
response = new ResponseModel("error", "Error fetching messages: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "toggle_block": {
|
||||||
|
try {
|
||||||
|
UUID userUUID = UUID.fromString(requestJson.getString("user_id"));
|
||||||
|
UUID targetUUID = UUID.fromString(requestJson.getString("target_id"));
|
||||||
|
|
||||||
|
boolean isBlocked = ContactDatabase.toggleBlock(userUUID, targetUUID);
|
||||||
|
|
||||||
|
String message = isBlocked ? "🔒 User blocked successfully." : "🔓 User unblocked successfully.";
|
||||||
|
response = new ResponseModel("success", message);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
response = new ResponseModel("error", "Error processing block/unblock: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "view_group_members" : {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
|
||||||
|
JSONArray members = GroupDatabase.getGroupMembers(groupId);
|
||||||
|
|
||||||
|
if (members != null) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("members", members);
|
||||||
|
response = new ResponseModel("success", "Members fetched successfully.", data);
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Failed to fetch members.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "delete_private_chat" : {
|
||||||
|
UUID targetId = UUID.fromString(requestJson.getString("target_id"));
|
||||||
|
boolean both = requestJson.getBoolean("both");
|
||||||
|
response = PrivateChatService.deletePrivateChat(currentUser.getInternal_uuid(), targetId, both);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "get_group_permissions": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
userId = currentUser.getInternal_uuid();
|
||||||
|
|
||||||
|
JSONObject permissions = GroupDatabase.getGroupPermissions(groupId, userId);
|
||||||
|
|
||||||
|
response = new ResponseModel("success", "Permissions fetched.", permissions);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,13 @@ public class GroupService {
|
|||||||
boolean inserted = GroupDatabase.insertGroup(internalUUID, groupId, groupName, creatorUUID, imageUrl, now);
|
boolean inserted = GroupDatabase.insertGroup(internalUUID, groupId, groupName, creatorUUID, imageUrl, now);
|
||||||
|
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
GroupDatabase.addMember(internalUUID, creatorUUID, "owner"); // سازنده owner میشود
|
GroupDatabase.addMember(internalUUID, creatorUUID, "owner");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.to.telegramfinalproject.Server;
|
||||||
|
|
||||||
|
|
||||||
|
import org.to.telegramfinalproject.Database.ContactDatabase;
|
||||||
|
import org.to.telegramfinalproject.Models.ResponseModel;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PrivateChatService {
|
||||||
|
|
||||||
|
public static ResponseModel deletePrivateChat(UUID currentUserId, UUID targetUserId, boolean both) {
|
||||||
|
boolean success = both ?
|
||||||
|
ContactDatabase.deleteChatBoth(currentUserId, targetUserId) :
|
||||||
|
ContactDatabase.deleteChatOneSide(currentUserId, targetUserId);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
return new ResponseModel("success", "Chat deleted successfully");
|
||||||
|
} else {
|
||||||
|
return new ResponseModel("error", "Chat not found or failed to delete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,8 @@ public class RealTimeEventDispatcher {
|
|||||||
|
|
||||||
|
|
||||||
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
|
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
System.out.println("🚀 Sending to user: " + userId + " → " + data);
|
||||||
|
|
||||||
out.println(data.toString());
|
out.println(data.toString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.err.println("❌ Error sending to user: " + e.getMessage());
|
System.err.println("❌ Error sending to user: " + e.getMessage());
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.to.telegramfinalproject.Utils;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.to.telegramfinalproject.Database.GroupDatabase;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class GroupPermissionUtil {
|
||||||
|
|
||||||
|
public static boolean canAddMembers(UUID groupId, UUID userId) {
|
||||||
|
String role = GroupDatabase.getGroupRole(groupId, userId);
|
||||||
|
if (role.equals("owner")) return true;
|
||||||
|
if (role.equals("admin")) {
|
||||||
|
JSONObject permissions = GroupDatabase.getGroupPermissions(groupId, userId);
|
||||||
|
return permissions.optBoolean("can_add_members", false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canRemoveMembers(UUID groupId, UUID userId) {
|
||||||
|
String role = GroupDatabase.getGroupRole(groupId, userId);
|
||||||
|
if (role.equals("owner")) return true;
|
||||||
|
if (role.equals("admin")) {
|
||||||
|
JSONObject permissions = GroupDatabase.getGroupPermissions(groupId, userId);
|
||||||
|
return permissions.optBoolean("can_remove_members", false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canAddAdmins(UUID groupId, UUID userId) {
|
||||||
|
String role = GroupDatabase.getGroupRole(groupId, userId);
|
||||||
|
if (role.equals("owner")) return true;
|
||||||
|
if (role.equals("admin")) {
|
||||||
|
JSONObject permissions = GroupDatabase.getGroupPermissions(groupId, userId);
|
||||||
|
return permissions.optBoolean("can_add_admins", false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canRemoveAdmins(UUID groupId, UUID userId) {
|
||||||
|
String role = GroupDatabase.getGroupRole(groupId, userId);
|
||||||
|
if (role.equals("owner")) return true;
|
||||||
|
if (role.equals("admin")) {
|
||||||
|
JSONObject permissions = GroupDatabase.getGroupPermissions(groupId, userId);
|
||||||
|
return permissions.optBoolean("can_remove_admins", false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canEditGroup(UUID groupId, UUID userId) {
|
||||||
|
String role = GroupDatabase.getGroupRole(groupId, userId);
|
||||||
|
if (role.equals("owner")) return true;
|
||||||
|
if (role.equals("admin")) {
|
||||||
|
JSONObject permissions = GroupDatabase.getGroupPermissions(groupId, userId);
|
||||||
|
return permissions.optBoolean("can_edit_group", false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user