Work on delete chat
This commit is contained in:
@@ -1237,6 +1237,7 @@ public class ActionHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private JSONObject getGroupPermissions(UUID groupId) {
|
||||
JSONObject req = new JSONObject();
|
||||
req.put("action", "get_group_permissions");
|
||||
@@ -2013,7 +2014,7 @@ public class ActionHandler {
|
||||
private void deleteChat(UUID targetId, boolean both) {
|
||||
JSONObject req = new JSONObject();
|
||||
req.put("action", "delete_private_chat");
|
||||
req.put("target_id", targetId.toString());
|
||||
req.put("chat_id", targetId.toString());
|
||||
req.put("both", both);
|
||||
send(req);
|
||||
|
||||
|
||||
@@ -65,6 +65,54 @@ public class MessageDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public static void markGloballyDeleted(UUID chatId) {
|
||||
String sql = "UPDATE messages SET deleted_globally = true WHERE receiver_id = ? AND receiver_type = 'private'";
|
||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, chatId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logDeletedMessagesFor(UUID chatId, UUID userId) {
|
||||
List<Message> messages = MessageDatabase.privateChatHistory(chatId);
|
||||
for (Message message : messages) {
|
||||
if (!isMessageDeleted(message.getMessage_id(), userId)) {
|
||||
String sql = """
|
||||
INSERT INTO deleted_messages (message_id, user_id)
|
||||
VALUES (?, ?)
|
||||
ON CONFLICT (message_id, user_id) DO NOTHING
|
||||
""";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, message.getMessage_id());
|
||||
ps.setObject(2, userId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMessageDeleted(UUID messageId, UUID userId) {
|
||||
String sql = "SELECT 1 FROM deleted_messages WHERE message_id = ? AND user_id = ?";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, messageId);
|
||||
ps.setObject(2, userId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void markMessageAsRead(UUID messageId, UUID userId) {
|
||||
String sql = "INSERT INTO message_receipts (message_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
|
||||
@@ -2,10 +2,7 @@ package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.PrivateChat;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -133,4 +130,129 @@ public class PrivateChatDatabase {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static PrivateChat extractPrivateChat(ResultSet rs) throws SQLException {
|
||||
UUID chatId = UUID.fromString(rs.getString("chat_id"));
|
||||
UUID user1 = rs.getObject("user1_id", UUID.class);
|
||||
UUID user2 = rs.getObject("user2_id", UUID.class);
|
||||
boolean user1Deleted = rs.getBoolean("user1_deleted");
|
||||
boolean user2Deleted = rs.getBoolean("user2_deleted");
|
||||
LocalDateTime createdAt = rs.getTimestamp("created_at").toLocalDateTime();
|
||||
|
||||
return new PrivateChat(chatId, user1, user2, user1Deleted, user2Deleted, createdAt);
|
||||
}
|
||||
|
||||
public static void markChatDeleted(UUID userId, UUID chatId) {
|
||||
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 chat_id = ?
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setObject(1, userId);
|
||||
stmt.setObject(2, userId);
|
||||
stmt.setObject(3, chatId);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void unmarkChatDeleted(UUID userId, UUID chatId) {
|
||||
String sql = """
|
||||
UPDATE private_chat
|
||||
SET user1_deleted = CASE WHEN user1_id = ? THEN false ELSE user1_deleted END,
|
||||
user2_deleted = CASE WHEN user2_id = ? THEN false ELSE user2_deleted END
|
||||
WHERE chat_id = ?
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setObject(1, userId);
|
||||
stmt.setObject(2, userId);
|
||||
stmt.setObject(3, chatId);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void markUser1Deleted(UUID chatId) {
|
||||
updateBoolField(chatId, "user1_deleted", true);
|
||||
}
|
||||
|
||||
public static void markUser2Deleted(UUID chatId) {
|
||||
updateBoolField(chatId, "user2_deleted", true);
|
||||
}
|
||||
|
||||
public static void markBothDeleted(UUID chatId) {
|
||||
String sql = "UPDATE private_chat SET user1_deleted = true, user2_deleted = true WHERE chat_id = ?";
|
||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, chatId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateBoolField(UUID chatId, String field, boolean value) {
|
||||
String sql = "UPDATE private_chat SET " + field + " = ? WHERE chat_id = ?";
|
||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setBoolean(1, value);
|
||||
ps.setObject(2, chatId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static PrivateChat findById(UUID chatId) {
|
||||
String sql = "SELECT * FROM private_chat WHERE chat_id = ?";
|
||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, chatId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (rs.next()) {
|
||||
UUID user1_id = (UUID) rs.getObject("user1_id");
|
||||
UUID user2_id = (UUID) rs.getObject("user2_id");
|
||||
boolean user1_deleted = rs.getBoolean("user1_deleted");
|
||||
boolean user2_deleted = rs.getBoolean("user2_deleted");
|
||||
LocalDateTime created_at = rs.getTimestamp("created_at").toLocalDateTime();
|
||||
|
||||
return new PrivateChat(chatId, user1_id, user2_id, user1_deleted, user2_deleted, created_at);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void clearDeletedFlag(UUID senderId, UUID receiverId) {
|
||||
String sql = """
|
||||
UPDATE private_chat
|
||||
SET user1_deleted = CASE WHEN user1_id = ? THEN false ELSE user1_deleted END,
|
||||
user2_deleted = CASE WHEN user2_id = ? THEN false ELSE user2_deleted END
|
||||
WHERE (user1_id = ? AND user2_id = ?) OR (user1_id = ? AND user2_id = ?)
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect(); PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, senderId);
|
||||
ps.setObject(2, senderId);
|
||||
ps.setObject(3, senderId);
|
||||
ps.setObject(4, receiverId);
|
||||
ps.setObject(5, receiverId);
|
||||
ps.setObject(6, senderId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import java.util.UUID;
|
||||
|
||||
public class PrivateChat {
|
||||
private final UUID chat_id;
|
||||
private boolean user1_deleted;
|
||||
private boolean user2_deleted;
|
||||
private UUID user1_id;
|
||||
private UUID user2_id;
|
||||
private LocalDateTime created_at;
|
||||
@@ -16,6 +18,16 @@ public class PrivateChat {
|
||||
this.created_at =created_at;
|
||||
}
|
||||
|
||||
public PrivateChat(UUID chatId, UUID user1, UUID user2, boolean user1Deleted, boolean user2Deleted, LocalDateTime createdAt) {
|
||||
this.chat_id = chatId;
|
||||
this.user1_id = user1;
|
||||
this.user2_id = user2;
|
||||
this.user1_deleted = user1Deleted;
|
||||
this.user2_deleted = user2Deleted;
|
||||
this.created_at = createdAt;
|
||||
}
|
||||
|
||||
|
||||
public void setUser1_id(UUID user1_id){this.user1_id =user1_id;}
|
||||
public void setUser2_id(UUID user2_id){this.user2_id =user2_id;}
|
||||
public void setCreated_at(LocalDateTime created_at){this.created_at = created_at;}
|
||||
|
||||
@@ -1432,26 +1432,33 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
|
||||
|
||||
case "delete_private_chat" : {
|
||||
case "delete_private_chat": {
|
||||
if (currentUser == null) {
|
||||
response = new ResponseModel("error", "Unauthorized. Please login first.");
|
||||
break;
|
||||
}
|
||||
UUID targetId = UUID.fromString(requestJson.getString("target_id"));
|
||||
|
||||
// دریافت شناسه چت و نوع حذف (یکطرفه یا دوطرفه)
|
||||
UUID targetId = UUID.fromString(requestJson.getString("chat_id"));
|
||||
boolean both = requestJson.getBoolean("both");
|
||||
|
||||
//RealTime
|
||||
// Real-Time Event Dispatch (اطلاعرسانی ریل تایم)
|
||||
if (both) {
|
||||
// حذف دوطرفه
|
||||
RealTimeEventDispatcher.notifyChatDeleted("private", targetId, List.of(currentUser.getInternal_uuid()));
|
||||
RealTimeEventDispatcher.notifyChatDeleted("private", currentUser.getInternal_uuid(), List.of(targetId));
|
||||
} else {
|
||||
// حذف یکطرفه
|
||||
RealTimeEventDispatcher.notifyChatDeleted("private", targetId, List.of(currentUser.getInternal_uuid()));
|
||||
}
|
||||
response = PrivateChatService.deletePrivateChat(currentUser.getInternal_uuid(), targetId, both);
|
||||
|
||||
// فراخوانی متد حذف چت
|
||||
response = handleDeleteChat(requestJson);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
case "get_group_permissions": {
|
||||
if (currentUser == null) {
|
||||
response = new ResponseModel("error", "Unauthorized. Please login first.");
|
||||
@@ -2025,8 +2032,6 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
response = new ResponseModel("error", "Unknown action: " + action);
|
||||
}
|
||||
@@ -2085,6 +2090,7 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
|
||||
private ResponseModel handleSendMessage(JSONObject json) {
|
||||
|
||||
try {
|
||||
if (currentUser == null)
|
||||
return new ResponseModel("error", "Unauthorized. Please login first.");
|
||||
@@ -2093,9 +2099,13 @@ public class ClientHandler implements Runnable {
|
||||
UUID senderId = currentUser.getInternal_uuid();
|
||||
String receiverType = json.getString("receiver_type");
|
||||
UUID receiverId;
|
||||
|
||||
receiverId = UUID.fromString(json.getString("receiver_id"));
|
||||
|
||||
if(Objects.equals(receiverType, "private")){
|
||||
PrivateChatDatabase.clearDeletedFlag(senderId, receiverId);
|
||||
}
|
||||
|
||||
|
||||
String content = json.optString("content", "");
|
||||
String messageType = json.optString("message_type", "TEXT");
|
||||
|
||||
@@ -2165,5 +2175,42 @@ public class ClientHandler implements Runnable {
|
||||
}
|
||||
|
||||
|
||||
private ResponseModel handleDeleteChat(JSONObject json) {
|
||||
try {
|
||||
if (currentUser == null)
|
||||
return new ResponseModel("error", "Unauthorized");
|
||||
|
||||
UUID chatId = UUID.fromString(json.getString("chat_id"));
|
||||
boolean bothSides = json.optBoolean("both_sides", false);
|
||||
|
||||
PrivateChat chat = PrivateChatDatabase.findById(chatId);
|
||||
if (chat == null) return new ResponseModel("error", "Chat not found.");
|
||||
|
||||
UUID self = currentUser.getInternal_uuid();
|
||||
UUID other = chat.getUser1_id().equals(self) ? chat.getUser2_id() : chat.getUser1_id();
|
||||
|
||||
if (bothSides) {
|
||||
PrivateChatDatabase.markBothDeleted(chatId);
|
||||
MessageDatabase.markGloballyDeleted(chatId);
|
||||
MessageDatabase.logDeletedMessagesFor(chatId, self);
|
||||
MessageDatabase.logDeletedMessagesFor(chatId, other);
|
||||
return new ResponseModel("success", "Chat deleted for both sides.");
|
||||
} else {
|
||||
if (chat.getUser1_id().equals(self))
|
||||
PrivateChatDatabase.markUser1Deleted(chatId);
|
||||
else
|
||||
PrivateChatDatabase.markUser2Deleted(chatId);
|
||||
|
||||
MessageDatabase.logDeletedMessagesFor(chatId, self);
|
||||
return new ResponseModel("success", "Chat deleted (one-sided).");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ResponseModel("error", "Exception while deleting chat.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user