diff --git a/src/main/java/org/to/telegramfinalproject/Client/SidebarHandler.java b/src/main/java/org/to/telegramfinalproject/Client/SidebarHandler.java index 04ffb0f..258d9f5 100644 --- a/src/main/java/org/to/telegramfinalproject/Client/SidebarHandler.java +++ b/src/main/java/org/to/telegramfinalproject/Client/SidebarHandler.java @@ -1,17 +1,29 @@ package org.to.telegramfinalproject.Client; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.to.telegramfinalproject.Models.Message; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; +import java.util.UUID; + +import static org.to.telegramfinalproject.Client.ActionHandler.sendWithResponse; public class SidebarHandler { private final Scanner scanner; private final ActionHandler actionHandler; + private final String userUUID; public SidebarHandler(Scanner scanner, ActionHandler actionHandler) { this.scanner = scanner; this.actionHandler = actionHandler; + this.userUUID = Session.getUserUUID(); + } public void handleSidebarAction(SidebarAction action) { @@ -29,7 +41,7 @@ public class SidebarHandler { showContacts(); break; case SAVED_MESSAGES: - showSavedMessages(); + getSavedMessagesData(userUUID); break; case SETTINGS: openSettings(); @@ -48,7 +60,7 @@ public class SidebarHandler { JSONObject request = new JSONObject(); request.put("action", "get_user_profile"); - JSONObject response = ActionHandler.sendWithResponse(request); + JSONObject response = sendWithResponse(request); if (response == null || !response.optString("status", "fail").equals("success")) { System.out.println("Failed to load profile information."); return; @@ -127,7 +139,7 @@ public class SidebarHandler { request.put("new_profile_name", newProfileName); // Step 3: Send request and receive response - JSONObject response = ActionHandler.sendWithResponse(request); + JSONObject response = sendWithResponse(request); // Step 4: Handle response if (response == null || !response.optString("status", "fail").equals("success")) { @@ -161,7 +173,7 @@ public class SidebarHandler { JSONObject request = new JSONObject(); request.put("action", "edit_user_id"); request.put("new_user_id", newUserId); - JSONObject response = ActionHandler.sendWithResponse(request); + JSONObject response = sendWithResponse(request); if (response.getString("status").equals("success")) { System.out.println("User ID updated successfully."); @@ -187,7 +199,7 @@ public class SidebarHandler { request.put("action", "edit_bio"); request.put("new_bio", newBio); - JSONObject response = ActionHandler.sendWithResponse(request); + JSONObject response = sendWithResponse(request); if (response.getString("status").equals("success")) { System.out.println("Bio updated successfully."); @@ -214,7 +226,7 @@ public class SidebarHandler { JSONObject request = new JSONObject(); request.put("action", "edit_profile_picture"); request.put("new_image_url", newImageUrl); - JSONObject response = ActionHandler.sendWithResponse(request); + JSONObject response = sendWithResponse(request); if (response.getString("status").equals("success")) { System.out.println("Bio updated successfully."); @@ -237,8 +249,139 @@ public class SidebarHandler { System.out.println("📇 Showing contacts..."); } - private void showSavedMessages() { - System.out.println("💾 Showing saved messages..."); + public void getSavedMessagesData(String userId) { + try { + // Step 1: Create the request + JSONObject request = new JSONObject(); + request.put("action", "get_saved_messages"); + request.put("user_id", userId); + + // Step 2: Send request and wait for response + JSONObject response = ActionHandler.sendWithResponse(request); + + // Step 3: Check the response + if (!response.optString("status", "fail").equals("success")) { + System.out.println("Failed to open Saved Messages chat: " + response.optString("message", "Unknown error")); + return; + } + + // Step 4: Extract "data" object + JSONObject data = response.getJSONObject("data"); + UUID chatId = UUID.fromString(data.getString("chat_id")); + JSONArray messagesArray = data.getJSONArray("messages"); + + // Step 5: Parse messages + List messages = new ArrayList<>(); + if (!messagesArray.isEmpty()) { + for (int i = 0; i < messagesArray.length(); i++) { + JSONObject msgJson = messagesArray.getJSONObject(i); + + // Safely extract optional UUIDs + UUID replyToId = null; + String replyToIdStr = msgJson.optString("reply_to_id", null); + if (replyToIdStr != null && !replyToIdStr.equals("null")) { + replyToId = UUID.fromString(replyToIdStr); + } + + UUID originalMessageId = null; + String originalMessageIdStr = msgJson.optString("original_message_id", null); + if (originalMessageIdStr != null && !originalMessageIdStr.equals("null")) { + originalMessageId = UUID.fromString(originalMessageIdStr); + } + + UUID forwardedBy = null; + String forwardedByStr = msgJson.optString("forwarded_by", null); + if (forwardedByStr != null && !forwardedByStr.equals("null")) { + forwardedBy = UUID.fromString(forwardedByStr); + } + + UUID forwardedFrom = null; + String forwardedFromStr = msgJson.optString("forwarded_from", null); + if (forwardedFromStr != null && !forwardedFromStr.equals("null")) { + forwardedFrom = UUID.fromString(forwardedFromStr); + } + + Message msg = new Message( + UUID.fromString(msgJson.getString("message_id")), + UUID.fromString(msgJson.getString("sender_id")), + msgJson.getString("receiver_type"), + UUID.fromString(msgJson.getString("receiver_id")), + msgJson.getString("content"), + msgJson.getString("message_type"), + msgJson.optString("file_url", null), + LocalDateTime.parse(msgJson.getString("send_at").replace(" ", "T")), + msgJson.getString("status"), + replyToId, + msgJson.getBoolean("is_edited"), + originalMessageId, + forwardedBy, + forwardedFrom + ); + + messages.add(msg); + } + } + + // Step 6: Show chat + showSavedMessages(chatId, messages); + + } catch (Exception e) { + System.out.println("An error occurred while retrieving Saved Messages."); + e.printStackTrace(); + } + } + + private void showSavedMessages(UUID chatId, List messages) { + Scanner scanner = new Scanner(System.in); + + System.out.println("==== Saved Messages ===="); + + // Show previous messages + if (messages.isEmpty()) { + System.out.println("No messages yet."); + } else { + for (Message msg : messages) { + System.out.println("[" + msg.getSend_at() + "] " + msg.getContent()); + } + } + + System.out.println("\n(Type your message below, or type 0 to exit)"); + + while (true) { + System.out.print("You: "); + String content = scanner.nextLine().trim(); + + if (content.equals("0")) { + System.out.println("Exiting Saved Messages."); + break; + } + + // Prepare the request JSON + JSONObject request = new JSONObject(); + request.put("action", "send_message"); + request.put("message_id", UUID.randomUUID().toString()); + request.put("sender_id", userUUID); + request.put("receiver_type", "private"); + request.put("receiver_id", userUUID); // saved messages = to yourself + request.put("content", content); + request.put("message_type", "TEXT"); + request.put("file_url", JSONObject.NULL); + request.put("status", "READ"); + request.put("reply_to_id", JSONObject.NULL); + request.put("is_edited", false); + request.put("original_message_id", JSONObject.NULL); + request.put("forwarded_by", JSONObject.NULL); + request.put("forwarded_from", JSONObject.NULL); + + // Send the message and wait for response + JSONObject response = ActionHandler.sendWithResponse(request); + + if (!response.optString("status", "fail").equals("success")) { + System.out.println("Failed to send message: " + response.optString("message", "Unknown error")); + } else { + System.out.println("Message sent."); + } + } } private void openSettings() { diff --git a/src/main/java/org/to/telegramfinalproject/Database/PrivateChatDatabase.java b/src/main/java/org/to/telegramfinalproject/Database/PrivateChatDatabase.java new file mode 100644 index 0000000..2114f4a --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Database/PrivateChatDatabase.java @@ -0,0 +1,38 @@ +package org.to.telegramfinalproject.Database; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +public class PrivateChatDatabase { + + public static UUID getOrCreateSavedMessagesChat(UUID userId) { + String query = "SELECT chat_id FROM private_chat WHERE user1_id = ? AND user2_id = ?"; + try (Connection conn = ConnectionDb.connect()) { + PreparedStatement stmt = conn.prepareStatement(query); + stmt.setObject(1, userId); + stmt.setObject(2, userId); // Saved Messages is self-chat + + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return (UUID) rs.getObject("chat_id"); // Chat already exists + } else { + // Create a new chat + UUID chatId = UUID.randomUUID(); + String insert = "INSERT INTO private_chat (chat_id, user1_id, user2_id) VALUES (?, ?, ?)"; + try (PreparedStatement insertStmt = conn.prepareStatement(insert)) { + insertStmt.setObject(1, chatId); + insertStmt.setObject(2, userId); + insertStmt.setObject(3, userId); + insertStmt.executeUpdate(); + return chatId; + } + } + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/to/telegramfinalproject/Models/Message.java b/src/main/java/org/to/telegramfinalproject/Models/Message.java index eb7688a..00e5764 100644 --- a/src/main/java/org/to/telegramfinalproject/Models/Message.java +++ b/src/main/java/org/to/telegramfinalproject/Models/Message.java @@ -4,7 +4,7 @@ import java.time.LocalDateTime; import java.util.UUID; public class Message { - private UUID message_id; + private final UUID message_id; private UUID sender_id; private String receiver_type; // private, group, channel private UUID receiver_id; diff --git a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java index 99bd97c..32f7274 100644 --- a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java +++ b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java @@ -1778,6 +1778,17 @@ public class ClientHandler implements Runnable { break; } + case "get_saved_messages": { + UUID user_Id = UUID.fromString(requestJson.getString("user_id")); + response = SidebarService.handleGetSavedMessages(user_Id); + break; + } + + case "send_message": { + response = SidebarService.handleSendMessage(requestJson); + break; + } + default: response = new ResponseModel("error", "Unknown action: " + action); } diff --git a/src/main/java/org/to/telegramfinalproject/Server/SidebarService.java b/src/main/java/org/to/telegramfinalproject/Server/SidebarService.java index e81f24b..a63c05b 100644 --- a/src/main/java/org/to/telegramfinalproject/Server/SidebarService.java +++ b/src/main/java/org/to/telegramfinalproject/Server/SidebarService.java @@ -1,10 +1,16 @@ package org.to.telegramfinalproject.Server; +import org.json.JSONArray; import org.json.JSONObject; +import org.to.telegramfinalproject.Database.MessageDatabase; +import org.to.telegramfinalproject.Database.PrivateChatDatabase; import org.to.telegramfinalproject.Database.userDatabase; +import org.to.telegramfinalproject.Models.Message; import org.to.telegramfinalproject.Models.ResponseModel; import org.to.telegramfinalproject.Models.User; +import java.time.LocalDateTime; +import java.util.List; import java.util.Objects; import java.util.UUID; @@ -150,6 +156,81 @@ public class SidebarService { } } + // Get saved messages data + public static ResponseModel handleGetSavedMessages(UUID userId) { + try { + + UUID chatId = PrivateChatDatabase.getOrCreateSavedMessagesChat(userId); + if (chatId == null) { + return new ResponseModel("error", "Failed to create or find saved messages chat."); + } + + List messages = MessageDatabase.privateChatHistory(userId, userId); + + JSONArray messageArray = new JSONArray(); + if (!messages.isEmpty()) { + for (Message msg : messages) { + JSONObject msgJson = new JSONObject(); + msgJson.put("message_id", msg.getMessage_id().toString()); + msgJson.put("sender_id", msg.getSender_id().toString()); + msgJson.put("receiver_type", msg.getReceiver_type()); + msgJson.put("receiver_id", msg.getReceiver_id().toString()); + msgJson.put("content", msg.getContent()); + msgJson.put("message_type", msg.getMessage_type()); + msgJson.put("file_url", msg.getFile_url() != null ? msg.getFile_url() : JSONObject.NULL); + msgJson.put("send_at", msg.getSend_at().toString()); // LocalDateTime + msgJson.put("status", msg.getStatus()); + msgJson.put("reply_to_id", msg.getReply_to_id() != null ? msg.getReply_to_id().toString() : JSONObject.NULL); + msgJson.put("is_edited", msg.isIs_edited()); + msgJson.put("original_message_id", msg.getOriginal_message_id() != null ? msg.getOriginal_message_id().toString() : JSONObject.NULL); + msgJson.put("forwarded_by", msg.getForwarded_by() != null ? msg.getForwarded_by().toString() : JSONObject.NULL); + msgJson.put("forwarded_from", msg.getForwarded_from() != null ? msg.getForwarded_from().toString() : JSONObject.NULL); + + messageArray.put(msgJson); + } + } + + JSONObject data = new JSONObject(); + data.put("chat_id", chatId.toString()); + data.put("messages", messageArray); + + return new ResponseModel("success", "Saved messages retrieved successfully", data); + + } catch (Exception e) { + e.printStackTrace(); + return new ResponseModel("error", "Unexpected server error."); + } + } + + // Save messages to DB + public static ResponseModel handleSendMessage(JSONObject requestJson) { + try { + Message message = new Message( + UUID.fromString(requestJson.getString("message_id")), + UUID.fromString(requestJson.getString("sender_id")), + requestJson.getString("receiver_type"), + UUID.fromString(requestJson.getString("receiver_id")), + requestJson.optString("content", null), + requestJson.optString("message_type", "TEXT"), + requestJson.isNull("file_url") ? null : requestJson.getString("file_url"), + LocalDateTime.now(), // send_at + requestJson.optString("status", "SEND"), + requestJson.isNull("reply_to_id") ? null : UUID.fromString(requestJson.getString("reply_to_id")), + requestJson.optBoolean("is_edited", false), + requestJson.isNull("original_message_id") ? null : UUID.fromString(requestJson.getString("original_message_id")), + requestJson.isNull("forwarded_by") ? null : UUID.fromString(requestJson.getString("forwarded_by")), + requestJson.isNull("forwarded_from") ? null : UUID.fromString(requestJson.getString("forwarded_from")) + ); + + MessageDatabase.save(message); + return new ResponseModel("success", "Message saved successfully."); + + } catch (Exception e) { + e.printStackTrace(); + return new ResponseModel("error", "Unexpected server error."); + } + } + // Changes username public static boolean updateUserName(String userId, String newUserName) { return false;