Send text message
This commit is contained in:
@@ -25,6 +25,8 @@ public class ActionHandler {
|
||||
public static ActionHandler instance;
|
||||
|
||||
|
||||
|
||||
|
||||
private void handleRealTime(JSONObject json) throws IOException {
|
||||
IncomingMessageListener listener = new IncomingMessageListener(this.in);
|
||||
listener.handleRealTimeEvent (json);
|
||||
@@ -705,12 +707,14 @@ public class ActionHandler {
|
||||
System.out.println("\n🔓 Messages fetched:");
|
||||
System.out.println("─────────────────────────────────────────────");
|
||||
for (int i = 0; i < messages.length(); i++) {
|
||||
|
||||
JSONObject m = messages.getJSONObject(i);
|
||||
String senderId = m.getString("sender_id");
|
||||
String senderName = m.optString("sender_name", "Other");
|
||||
String content = m.getString("content");
|
||||
String time = m.getString("send_at");
|
||||
|
||||
String label = senderId.equals(Session.currentUser.getString("internal_uuid")) ? "You" : "Other";
|
||||
String label = senderId.equals(Session.currentUser.getString("internal_uuid")) ? "You" : senderName;
|
||||
System.out.println("[" + time + "] " + label + ": " + content);
|
||||
}
|
||||
System.out.println("─────────────────────────────────────────────");
|
||||
@@ -891,10 +895,11 @@ public class ActionHandler {
|
||||
for (int i = 0; i < messages.length(); i++) {
|
||||
JSONObject m = messages.getJSONObject(i);
|
||||
String senderId = m.getString("sender_id");
|
||||
String senderName = m.optString("sender_name", "Other");
|
||||
String content = m.getString("content");
|
||||
String time = m.getString("send_at");
|
||||
|
||||
String label = senderId.equals(Session.currentUser.getString("internal_uuid")) ? "You" : "Other";
|
||||
String label = senderId.equals(Session.currentUser.getString("internal_uuid")) ? "You" : senderName;
|
||||
System.out.println("[" + time + "] " + label + ": " + content);
|
||||
}
|
||||
System.out.println("─────────────────────────────────────────────");
|
||||
@@ -982,7 +987,7 @@ public class ActionHandler {
|
||||
|
||||
String input = scanner.nextLine();
|
||||
switch (input) {
|
||||
case "1" -> sendMessageTo(chat.getId(), "private");
|
||||
case "1" -> sendMessage(chat.getId(), "private");
|
||||
case "2" -> toggleBlock(chat.getId());
|
||||
case "3" -> {
|
||||
deleteChat(chat.getId(), false);
|
||||
@@ -1094,7 +1099,7 @@ public class ActionHandler {
|
||||
|
||||
String input = scanner.nextLine();
|
||||
switch (input) {
|
||||
case "1" -> sendMessageTo(chat.getId(), "group");
|
||||
case "1" -> sendMessage(chat.getId(), "group");
|
||||
case "2" -> viewGroupMembers(chat.getId());
|
||||
case "3" -> {
|
||||
if (isOwner || (isAdmin && perms.optBoolean("can_add_members", false)))
|
||||
@@ -1216,7 +1221,7 @@ public class ActionHandler {
|
||||
switch (input) {
|
||||
case "1" -> {
|
||||
if (isOwner || (isAdmin && perms.optBoolean("can_post", false))) {
|
||||
sendMessageTo(chat.getId(), "channel");
|
||||
sendMessage(chat.getId(), "channel");
|
||||
} else {
|
||||
System.out.println("❌ You don't have permission to post.");
|
||||
}
|
||||
@@ -1985,31 +1990,7 @@ public class ActionHandler {
|
||||
|
||||
|
||||
|
||||
private void sendMessageTo(UUID id, String type) {
|
||||
System.out.print("Enter message: ");
|
||||
String text = scanner.nextLine().trim();
|
||||
|
||||
if (text.isEmpty()) {
|
||||
System.out.println("Message cannot be empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject req = new JSONObject();
|
||||
req.put("action", "send_message");
|
||||
req.put("sender_id", Session.getUserUUID());
|
||||
req.put("receiver_id", id.toString());
|
||||
req.put("receiver_type", type);
|
||||
req.put("text", text);
|
||||
|
||||
JSONObject res = sendWithResponse(req);
|
||||
if (res == null) return;
|
||||
|
||||
if (res.getBoolean("success")) {
|
||||
System.out.println("✅ Message sent.");
|
||||
} else {
|
||||
System.out.println("❌ Failed to send message.");
|
||||
}
|
||||
}
|
||||
|
||||
private void addMemberToGroup(UUID groupId, UUID userId) {
|
||||
JSONObject req = new JSONObject();
|
||||
@@ -2529,7 +2510,8 @@ public class ActionHandler {
|
||||
|
||||
System.out.println("\n💬 Your Chats:");
|
||||
int index = 1;
|
||||
for (ChatEntry chat : Session.chatList) {
|
||||
System.out.println("0. Archived chats");
|
||||
for (ChatEntry chat : Session.activeChats) {
|
||||
System.out.printf("%d. [%s] %s (%s)\n", index++, chat.getType(), chat.getName(), chat.getDisplayId());
|
||||
}
|
||||
}
|
||||
@@ -2898,6 +2880,64 @@ public class ActionHandler {
|
||||
}
|
||||
|
||||
|
||||
public void sendMessage(UUID receiverId, String receiverType) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
System.out.print("Enter your message: ");
|
||||
String content = scanner.nextLine();
|
||||
|
||||
System.out.print("Enter message type (TEXT / IMAGE / VIDEO / FILE): ");
|
||||
String messageType = scanner.nextLine();
|
||||
Set<String> allowedTypes = Set.of("TEXT", "IMAGE", "VIDEO", "FILE");
|
||||
while (!allowedTypes.contains(messageType.toUpperCase())) {
|
||||
System.out.println("❌ Invalid message type. Try again (TEXT / IMAGE / VIDEO / FILE): ");
|
||||
messageType = scanner.nextLine();
|
||||
}
|
||||
|
||||
JSONArray attachmentsArray = new JSONArray();
|
||||
|
||||
System.out.print("Do you want to attach files? (yes/no): ");
|
||||
if (scanner.nextLine().equalsIgnoreCase("yes")) {
|
||||
while (true) {
|
||||
System.out.print("File URL: ");
|
||||
String fileUrl = scanner.nextLine();
|
||||
|
||||
System.out.print("File Type (IMAGE / VIDEO / FILE): ");
|
||||
String fileType = scanner.nextLine();
|
||||
|
||||
JSONObject fileJson = new JSONObject();
|
||||
fileJson.put("file_url", fileUrl);
|
||||
fileJson.put("file_type", fileType);
|
||||
attachmentsArray.put(fileJson);
|
||||
|
||||
System.out.print("Add another file? (yes/no): ");
|
||||
if (!scanner.nextLine().equalsIgnoreCase("yes")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject messageJson = new JSONObject();
|
||||
messageJson.put("action", "send_message");
|
||||
messageJson.put("receiver_id", receiverId.toString());
|
||||
messageJson.put("receiver_type", receiverType);
|
||||
messageJson.put("content", content);
|
||||
messageJson.put("message_type", messageType);
|
||||
|
||||
if (!attachmentsArray.isEmpty()) {
|
||||
messageJson.put("attachments", attachmentsArray);
|
||||
}
|
||||
|
||||
JSONObject response = sendWithResponse(messageJson);
|
||||
if (response != null && response.getString("status").equals("success")) {
|
||||
System.out.println("✅ Message sent successfully! ID: " + response.getJSONObject("data").getString("message_id"));
|
||||
} else {
|
||||
System.out.println("❌ Failed to send message: " + (response != null ? response.getString("message") : "no response"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -107,16 +107,22 @@ public class IncomingMessageListener implements Runnable {
|
||||
}
|
||||
|
||||
case "chat_updated" -> {
|
||||
System.out.println("\n🔄 Group/Channel info updated.");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
handleAdminRoleChanged(msg);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
System.out.println("\n🔄 Chat info updated.");
|
||||
|
||||
if (msg.has("last_message_time")) {
|
||||
updateLastMessageTime(msg);
|
||||
} else {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
handleAdminRoleChanged(msg);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case "became_admin", "removed_admin", "ownership_transferred","admin_permissions_updated" -> {
|
||||
System.out.println("🧩 Detected admin/owner role change. Calling handler...");
|
||||
new Thread(() -> {
|
||||
@@ -139,6 +145,30 @@ public class IncomingMessageListener implements Runnable {
|
||||
System.out.print(">> ");
|
||||
}
|
||||
|
||||
private void updateLastMessageTime(JSONObject msg) {
|
||||
try {
|
||||
UUID chatUUID = UUID.fromString(msg.getString("chat_id"));
|
||||
String newTime = msg.optString("last_message_time", null);
|
||||
|
||||
Session.chatList.stream()
|
||||
.filter(chat -> chat.getId().equals(chatUUID))
|
||||
.findFirst()
|
||||
.ifPresent(chat -> {
|
||||
chat.setLastMessageTime(newTime);
|
||||
System.out.println("✅ Updated last message time for chat: " + chat.getDisplayId());
|
||||
});
|
||||
|
||||
if (Session.inChatListMenu) {
|
||||
ActionHandler.displayChatList();
|
||||
System.out.print("Select a chat by number: ");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("❌ Failed to update last message time: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleAdminRoleChanged(JSONObject data) throws IOException {
|
||||
String chatType = data.getString("chat_type");
|
||||
String chatId = data.optString("group_id", data.optString("channel_id", data.optString("chat_id", null)));
|
||||
@@ -230,11 +260,26 @@ public class IncomingMessageListener implements Runnable {
|
||||
private void displayRealTimeMessage(String action, JSONObject msg) {
|
||||
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"));
|
||||
System.out.println("\n🔔 New Message Received:");
|
||||
String senderName = msg.optString("sender_name", "Unknown");
|
||||
String content = msg.optString("content", "(empty)");
|
||||
String sendAt = msg.optString("send_at", "-");
|
||||
|
||||
String receiverId = msg.optString("receiver_id", "");
|
||||
String receiverType = msg.optString("receiver_type", "");
|
||||
|
||||
boolean isInCurrentChat = Session.inChatMenu &&
|
||||
Session.currentChatId != null &&
|
||||
Session.currentChatId.equals(receiverId);
|
||||
|
||||
if (isInCurrentChat) {
|
||||
System.out.println(senderName + ": " + content + " (" + sendAt + ")");
|
||||
} else {
|
||||
System.out.println("💬 Message from " + senderName + " in " + receiverType + " chat: " + content);
|
||||
Session.forceRefreshChatList = true;
|
||||
}
|
||||
}
|
||||
|
||||
case "message_edited" -> {
|
||||
System.out.println("\n✏️ Message Edited:");
|
||||
System.out.println("ID: " + msg.getString("message_id"));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.FileAttachment;
|
||||
import org.to.telegramfinalproject.Models.Message;
|
||||
|
||||
import java.sql.*;
|
||||
@@ -12,38 +13,55 @@ import java.util.stream.Collectors;
|
||||
public class MessageDatabase {
|
||||
|
||||
|
||||
public static void save(Message message) {
|
||||
String sql = """
|
||||
INSERT INTO messages (
|
||||
message_id, sender_id, receiver_type, receiver_id, content,
|
||||
message_type, file_url, send_at, status,
|
||||
reply_to_id, is_edited, original_message_id, forwarded_by, forwarded_from
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""";
|
||||
|
||||
|
||||
|
||||
public static boolean insertMessage(UUID messageId, UUID senderId, UUID receiverId,
|
||||
String receiverType, String content, String messageType) {
|
||||
String sql = "INSERT INTO messages (message_id, sender_id, receiver_type, receiver_id, content, message_type) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?)";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
|
||||
stmt.setObject(1, message.getMessage_id());
|
||||
stmt.setObject(2, message.getSender_id());
|
||||
stmt.setString(3, message.getReceiver_type());
|
||||
stmt.setObject(4, message.getReceiver_id());
|
||||
stmt.setString(5, message.getContent());
|
||||
stmt.setString(6, message.getMessage_type());
|
||||
stmt.setString(7, message.getFile_url());
|
||||
stmt.setObject(8, message.getSend_at());
|
||||
stmt.setString(9, message.getStatus());
|
||||
stmt.setObject(10, message.getReply_to_id());
|
||||
stmt.setBoolean(11, message.isIs_edited());
|
||||
stmt.setObject(12, message.getOriginal_message_id());
|
||||
stmt.setObject(13, message.getForwarded_by());
|
||||
stmt.setObject(14, message.getForwarded_from());
|
||||
ps.setObject(1, messageId);
|
||||
ps.setObject(2, senderId);
|
||||
ps.setString(3, receiverType);
|
||||
ps.setObject(4, receiverId);
|
||||
ps.setString(5, content);
|
||||
ps.setString(6, messageType);
|
||||
|
||||
stmt.executeUpdate();
|
||||
return ps.executeUpdate() > 0;
|
||||
|
||||
} catch (SQLException e) {
|
||||
System.err.println("❌ Error saving message: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean insertAttachments(UUID messageId, List<FileAttachment> attachments) {
|
||||
String sql = "INSERT INTO message_attachments (attachment_id, message_id, file_url, file_type) " +
|
||||
"VALUES (?, ?, ?, ?)";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
|
||||
for (FileAttachment att : attachments) {
|
||||
ps.setObject(1, UUID.randomUUID());
|
||||
ps.setObject(2, messageId);
|
||||
ps.setString(3, att.getFileUrl());
|
||||
ps.setString(4, att.getFileType());
|
||||
ps.addBatch();
|
||||
}
|
||||
|
||||
ps.executeBatch();
|
||||
return true;
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +118,6 @@ public class MessageDatabase {
|
||||
UUID.fromString(rs.getString("receiver_id")),
|
||||
rs.getString("content"),
|
||||
rs.getString("message_type"),
|
||||
rs.getString("file_url"),
|
||||
rs.getTimestamp("send_at").toLocalDateTime(),
|
||||
rs.getString("status"),
|
||||
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
|
||||
@@ -118,6 +135,31 @@ public class MessageDatabase {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public static List<FileAttachment> getAttachments(UUID messageId) {
|
||||
List<FileAttachment> attachments = new ArrayList<>();
|
||||
String sql = "SELECT file_url, file_type FROM message_attachments WHERE message_id = ?";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
|
||||
stmt.setObject(1, messageId);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
attachments.add(new FileAttachment(
|
||||
rs.getString("file_url"),
|
||||
rs.getString("file_type")
|
||||
));
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static LocalDateTime getLastMessageTimeBetween(UUID user1, UUID user2, String type) {
|
||||
String sql = """
|
||||
@@ -177,7 +219,6 @@ public class MessageDatabase {
|
||||
UUID.fromString(rs.getString("receiver_id")),
|
||||
rs.getString("content"),
|
||||
rs.getString("message_type"),
|
||||
rs.getString("file_url"),
|
||||
rs.getTimestamp("send_at").toLocalDateTime(),
|
||||
rs.getString("status"),
|
||||
(UUID) rs.getObject("reply_to_id"),
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PrivateChatDatabase {
|
||||
|
||||
|
||||
public static List<UUID> getMembers(UUID privateChatId) {
|
||||
String sql = "SELECT user1, user2 FROM private_chats WHERE chat_id = ?";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setObject(1, privateChatId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
if (rs.next()) {
|
||||
UUID user1 = (UUID) rs.getObject("user1");
|
||||
UUID user2 = (UUID) rs.getObject("user2");
|
||||
return Arrays.asList(user1, user2);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -115,4 +115,6 @@ public class ChatEntry {
|
||||
this.archived = archived;
|
||||
}
|
||||
|
||||
public void setLastMessageTime(String newTime) {this.lastMessageTime = LocalDateTime.parse(newTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
public class FileAttachment {
|
||||
private String fileUrl;
|
||||
private String fileType;
|
||||
|
||||
public FileAttachment(String fileUrl, String fileType) {
|
||||
this.fileUrl = fileUrl;
|
||||
this.fileType = fileType;
|
||||
}
|
||||
|
||||
public String getFileUrl() {
|
||||
return fileUrl;
|
||||
}
|
||||
|
||||
public String getFileType() {
|
||||
return fileType;
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,6 @@ public class JsonUtil {
|
||||
obj.put("receiver_id", message.getReceiver_id().toString());
|
||||
obj.put("content", message.getContent());
|
||||
obj.put("message_type", message.getMessage_type());
|
||||
obj.put("file_url", message.getFile_url());
|
||||
obj.put("send_at", message.getSend_at().toString());
|
||||
obj.put("status", message.getStatus());
|
||||
obj.put("reply_to_id", message.getReply_to_id() != null ? message.getReply_to_id().toString() : JSONObject.NULL);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Message {
|
||||
@@ -10,7 +11,6 @@ public class Message {
|
||||
private UUID receiver_id;
|
||||
private String content;
|
||||
private String message_type; // TEXT, IMAGE, FILE, ...
|
||||
private String file_url;
|
||||
private LocalDateTime send_at;
|
||||
private String status; // SENT, DELIVERED, READ
|
||||
private UUID reply_to_id;
|
||||
@@ -18,9 +18,10 @@ public class Message {
|
||||
private UUID original_message_id;
|
||||
private UUID forwarded_by;
|
||||
private UUID forwarded_from;
|
||||
private List<FileAttachment> attachments;
|
||||
|
||||
public Message(UUID message_id, UUID sender_id, String receiver_type, UUID receiver_id, String content,
|
||||
String message_type, String file_url, LocalDateTime send_at, String status,
|
||||
String message_type, LocalDateTime send_at, String status,
|
||||
UUID reply_to_id, boolean is_edited, UUID original_message_id,
|
||||
UUID forwarded_by, UUID forwarded_from) {
|
||||
this.message_id = message_id;
|
||||
@@ -29,7 +30,6 @@ public class Message {
|
||||
this.receiver_id = receiver_id;
|
||||
this.content = content;
|
||||
this.message_type = message_type;
|
||||
this.file_url = file_url;
|
||||
this.send_at = send_at;
|
||||
this.status = status;
|
||||
this.reply_to_id = reply_to_id;
|
||||
@@ -39,6 +39,16 @@ public class Message {
|
||||
this.forwarded_from = forwarded_from;
|
||||
}
|
||||
|
||||
public Message(UUID messageId, UUID senderId, UUID receiverId, String receiverType, String content, String messageType, LocalDateTime now) {
|
||||
this.message_id = messageId;
|
||||
this.sender_id = senderId;
|
||||
this.receiver_id = receiverId;
|
||||
this.receiver_type = receiverType;
|
||||
this.content = content;
|
||||
this.message_type = messageType;
|
||||
this.send_at = now;
|
||||
}
|
||||
|
||||
|
||||
public UUID getMessage_id() {
|
||||
return message_id;
|
||||
@@ -85,14 +95,6 @@ public class Message {
|
||||
this.message_type = message_type;
|
||||
}
|
||||
|
||||
public String getFile_url() {
|
||||
return file_url;
|
||||
}
|
||||
|
||||
public void setFile_url(String file_url) {
|
||||
this.file_url = file_url;
|
||||
}
|
||||
|
||||
public LocalDateTime getSend_at() {
|
||||
return send_at;
|
||||
}
|
||||
@@ -148,4 +150,11 @@ public class Message {
|
||||
public void setForwarded_from(UUID forwarded_from) {
|
||||
this.forwarded_from = forwarded_from;
|
||||
}
|
||||
|
||||
public void setAttachments(List<FileAttachment> attachments) {
|
||||
this.attachments = attachments;
|
||||
}
|
||||
public List<FileAttachment> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1157,6 +1157,9 @@ public class ClientHandler implements Runnable {
|
||||
obj.put("receiver_type", m.getReceiver_type());
|
||||
obj.put("content", m.getContent());
|
||||
obj.put("send_at", m.getSend_at().toString());
|
||||
User senderUser = userDatabase.findByInternalUUID(m.getSender_id());
|
||||
String senderName = senderUser != null ? senderUser.getProfile_name() : "Unknown";
|
||||
obj.put("sender_name", senderName);
|
||||
messageArray.put(obj);
|
||||
}
|
||||
|
||||
@@ -1827,6 +1830,12 @@ public class ClientHandler implements Runnable {
|
||||
break;
|
||||
}
|
||||
|
||||
case "send_message" : {
|
||||
response = handleSendMessage(requestJson);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1888,4 +1897,86 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
|
||||
}
|
||||
private ResponseModel handleSendMessage(JSONObject json) {
|
||||
try {
|
||||
if (currentUser == null)
|
||||
return new ResponseModel("error", "Unauthorized. Please login first.");
|
||||
|
||||
UUID messageId = UUID.randomUUID();
|
||||
UUID senderId = currentUser.getInternal_uuid();
|
||||
UUID receiverId = UUID.fromString(json.getString("receiver_id"));
|
||||
String receiverType = json.getString("receiver_type");
|
||||
String content = json.optString("content", "");
|
||||
String messageType = json.optString("message_type", "TEXT");
|
||||
|
||||
boolean inserted = MessageDatabase.insertMessage(messageId, senderId, receiverId, receiverType, content, messageType);
|
||||
if (!inserted)
|
||||
return new ResponseModel("error", "Failed to insert message.");
|
||||
|
||||
if (json.has("attachments")) {
|
||||
JSONArray attachmentsArray = json.getJSONArray("attachments");
|
||||
List<FileAttachment> attachments = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < attachmentsArray.length(); i++) {
|
||||
JSONObject attJson = attachmentsArray.getJSONObject(i);
|
||||
attachments.add(new FileAttachment(
|
||||
attJson.getString("file_url"),
|
||||
attJson.getString("file_type")
|
||||
));
|
||||
}
|
||||
|
||||
boolean attInserted = MessageDatabase.insertAttachments(messageId, attachments);
|
||||
if (!attInserted)
|
||||
return new ResponseModel("error", "Message inserted but failed to attach files.");
|
||||
}
|
||||
|
||||
// ریلتایم (اختیاری: dispatchMessageToReceiver(messageId, receiverId, receiverType))
|
||||
|
||||
|
||||
Message msg = new Message(messageId, senderId, receiverId, receiverType, content, messageType, LocalDateTime.now());
|
||||
List<UUID> receivers = getReceiversForChat(receiverId, receiverType);
|
||||
receivers.remove(senderId);
|
||||
|
||||
RealTimeEventDispatcher.sendNewMessage(msg, receivers);
|
||||
|
||||
|
||||
JSONObject chatUpdate = new JSONObject();
|
||||
chatUpdate.put("chat_id", receiverId.toString());
|
||||
chatUpdate.put("chat_type", receiverType);
|
||||
chatUpdate.put("last_message_time", LocalDateTime.now().toString());
|
||||
|
||||
JSONObject chatPayload = new JSONObject();
|
||||
chatPayload.put("action", "chat_updated");
|
||||
chatPayload.put("data", chatUpdate);
|
||||
|
||||
for (UUID receiver : receivers) {
|
||||
RealTimeEventDispatcher.sendToUser(receiver, chatPayload);
|
||||
}
|
||||
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("message_id", messageId.toString());
|
||||
return new ResponseModel("success", "Message sent successfully.", data);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ResponseModel("error", "Exception occurred while sending message.");
|
||||
}
|
||||
}
|
||||
|
||||
private List<UUID> getReceiversForChat(UUID receiverId, String receiverType) {
|
||||
switch (receiverType) {
|
||||
case "private":
|
||||
return PrivateChatDatabase.getMembers(receiverId);
|
||||
case "group":
|
||||
return GroupDatabase.getMemberUUIDs(receiverId);
|
||||
case "channel":
|
||||
return ChannelDatabase.getSubscriberUUIDs(receiverId);
|
||||
default:
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.to.telegramfinalproject.Server;
|
||||
import org.json.JSONObject;
|
||||
import org.to.telegramfinalproject.Database.ChannelDatabase;
|
||||
import org.to.telegramfinalproject.Database.GroupDatabase;
|
||||
import org.to.telegramfinalproject.Database.userDatabase;
|
||||
import org.to.telegramfinalproject.Models.Message;
|
||||
import org.to.telegramfinalproject.Models.User;
|
||||
|
||||
@@ -151,7 +152,6 @@ public class RealTimeEventDispatcher {
|
||||
data.put("sender", sender.getUser_id());
|
||||
data.put("receiver_type", msg.getReceiver_type());
|
||||
data.put("receiver_id", msg.getReceiver_id());
|
||||
data.put("file_url", msg.getFile_url());
|
||||
data.put("file_type", msg.getMessage_type()); // IMAGE, FILE, VIDEO...
|
||||
data.put("time", msg.getSend_at().toString());
|
||||
|
||||
@@ -305,4 +305,30 @@ public class RealTimeEventDispatcher {
|
||||
broadcastToUsers(affectedUsers, event);
|
||||
}
|
||||
|
||||
|
||||
public static void sendNewMessage(Message message, List<UUID> receivers) {
|
||||
JSONObject payload = new JSONObject();
|
||||
payload.put("action", "new_message");
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("id", message.getMessage_id().toString());
|
||||
data.put("sender_id", message.getSender_id().toString());
|
||||
data.put("receiver_id", message.getReceiver_id().toString());
|
||||
data.put("receiver_type", message.getReceiver_type());
|
||||
data.put("content", message.getContent());
|
||||
data.put("send_at", message.getSend_at().toString());
|
||||
|
||||
User sender = userDatabase.findByInternalUUID(message.getSender_id());
|
||||
if (sender != null) {
|
||||
data.put("sender_name", sender.getProfile_name());
|
||||
}
|
||||
|
||||
payload.put("data", data);
|
||||
|
||||
for (UUID userId : receivers) {
|
||||
sendToUser(userId, payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user