Edit text messages

This commit is contained in:
2025-08-07 13:57:29 +03:30
parent ad37f3f26c
commit 33a6c5e55d
4 changed files with 116 additions and 6 deletions
@@ -3375,7 +3375,8 @@ public class ActionHandler {
String content = msg.optString("content", "(no content)"); String content = msg.optString("content", "(no content)");
String time = msg.optString("time", ""); String time = msg.optString("time", "");
boolean isEdited = msg.optBoolean("is_edited", false); boolean isEdited = msg.optBoolean("is_edited", false);
String label = isEdited ? "🖊️ (edited)" : ""; String editedAt = msg.optString("edited_at", "");
String label = isEdited ? "🖊️ (edited at: " + editedAt + ")" : "";
System.out.printf("[%d] [%s] %s: %s %s\n", i + 1, time, senderName, content, label); System.out.printf("[%d] [%s] %s: %s %s\n", i + 1, time, senderName, content, label);
} }
System.out.println("─────────────────────────────────────────────"); System.out.println("─────────────────────────────────────────────");
@@ -3474,11 +3475,30 @@ public class ActionHandler {
} }
} }
private String editMessage(UUID messageId) { private void editMessage(UUID messageId) {
return "not ready"; System.out.print("📝 Enter new content: ");
String newContent = scanner.nextLine().trim();
if (newContent.isEmpty()) {
System.out.println("❌ Content cannot be empty.");
return;
}
JSONObject req = new JSONObject();
req.put("action", "edit_message");
req.put("message_id", messageId.toString());
req.put("new_content", newContent);
JSONObject res = sendWithResponse(req);
if (res == null || !res.getString("status").equals("success")) {
System.out.println("❌ Failed to edit message.");
return;
}
System.out.println("✅ Message updated successfully.");
} }
private String reactToMessage(UUID messageId) { private String reactToMessage(UUID messageId) {
return "not ready"; return "not ready";
@@ -153,7 +153,12 @@ public class MessageDatabase {
rs.getBoolean("is_deleted_globally"), rs.getBoolean("is_deleted_globally"),
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null, rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null, rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null,
rs.getTimestamp("edited_at") != null
? rs.getTimestamp("edited_at").toLocalDateTime()
: null
); );
messages.add(msg); messages.add(msg);
@@ -222,6 +227,26 @@ public class MessageDatabase {
} }
} }
public static boolean updateContentAndMarkEdited(UUID messageId, String newContent) {
String sql = """
UPDATE messages
SET content = ?, is_edited = TRUE, edited_at = CURRENT_TIMESTAMP
WHERE message_id = ?
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, newContent);
ps.setObject(2, messageId);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public void markMessageAsRead(UUID messageId, UUID userId) { public void markMessageAsRead(UUID messageId, UUID userId) {
String sql = "INSERT INTO message_receipts (message_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING"; String sql = "INSERT INTO message_receipts (message_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
@@ -1,6 +1,7 @@
package org.to.telegramfinalproject.Models; package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@@ -22,6 +23,8 @@ public class Message {
private List<FileAttachment> attachments; private List<FileAttachment> attachments;
private transient String sender_name; private transient String sender_name;
private transient String receiver_name; private transient String receiver_name;
private LocalDateTime edited_at;
// ✅ Full Constructor // ✅ Full Constructor
@@ -57,6 +60,33 @@ public class Message {
this.send_at = sendAt; this.send_at = sendAt;
} }
public Message(UUID messageId, UUID senderId, String receiverType, UUID receiverId,
String content, String messageType, LocalDateTime sendAt, String status,
UUID replyToId, boolean isEdited, boolean isDeletedGlobally,
UUID originalMessageId, UUID forwardedBy, UUID forwardedFrom,
LocalDateTime editedAt) {
this.message_id = messageId;
this.sender_id = senderId;
this.receiver_type = receiverType;
this.receiver_id = receiverId;
this.content = content;
this.message_type = messageType;
this.send_at = sendAt;
this.status = status;
this.reply_to_id = replyToId;
this.is_edited = isEdited;
this.is_deleted_globally = isDeletedGlobally;
this.original_message_id = originalMessageId;
this.forwarded_by = forwardedBy;
this.forwarded_from = forwardedFrom;
this.edited_at = editedAt;
}
// ✅ Getters & Setters // ✅ Getters & Setters
public UUID getMessage_id() { return message_id; } public UUID getMessage_id() { return message_id; }
public void setMessage_id(UUID messageId) { this.message_id = messageId; } public void setMessage_id(UUID messageId) { this.message_id = messageId; }
@@ -120,4 +150,13 @@ public class Message {
this.receiver_name = receiver_name; this.receiver_name = receiver_name;
} }
public LocalDateTime getEdited_at() {
return edited_at;
}
public void setEdited_at(LocalDateTime edited_at) {
this.edited_at = edited_at;
}
} }
@@ -2107,8 +2107,8 @@ public class ClientHandler implements Runnable {
case "get_chat_messages" : { case "get_chat_messages" : {
UUID chatId = UUID.fromString(requestJson.getString("chat_id")); UUID chatId = UUID.fromString(requestJson.getString("chat_id"));
String chatType = requestJson.getString("chat_type"); String chatType = requestJson.getString("chat_type");
int offset = requestJson.optInt("offset", 0); // پیش‌فرض 0 int offset = requestJson.optInt("offset", 0);
int limit = requestJson.optInt("limit", 10); // پیش‌فرض 10 int limit = requestJson.optInt("limit", 10);
List<Message> messages = MessageDatabase.getMessagesForChat(chatId, chatType, currentUser.getInternal_uuid(), offset, limit); List<Message> messages = MessageDatabase.getMessagesForChat(chatId, chatType, currentUser.getInternal_uuid(), offset, limit);
@@ -2147,6 +2147,8 @@ public class ClientHandler implements Runnable {
obj.put("time", m.getSend_at().toString()); obj.put("time", m.getSend_at().toString());
obj.put("is_edited", m.isIs_edited()); obj.put("is_edited", m.isIs_edited());
obj.put("is_deleted_globally", m.isIs_deleted_globally()); obj.put("is_deleted_globally", m.isIs_deleted_globally());
obj.put("edited_at", m.getEdited_at() != null ? m.getEdited_at().toString() : JSONObject.NULL);
result.put(obj); result.put(obj);
} }
@@ -2210,6 +2212,30 @@ public class ClientHandler implements Runnable {
break; break;
} }
case "edit_message" : {
UUID msgId = UUID.fromString(requestJson.getString("message_id"));
String newContent = requestJson.getString("new_content");
Message msg = MessageDatabase.findById(msgId);
if (msg == null) {
response = new ResponseModel("error", "Message not found.");
break;
}
//Only sender can edit
if (!msg.getSender_id().equals(currentUser.getInternal_uuid())) {
response = new ResponseModel("error", "You can only edit your own messages.");
break;
}
boolean success = MessageDatabase.updateContentAndMarkEdited(msgId, newContent);
if (!success) {
response = new ResponseModel("error", "Failed to update message.");
} else {
response = new ResponseModel("success", "Message edited.");
}
break;
}