Edit text messages
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user