work on archived chats

This commit is contained in:
2025-07-24 21:48:49 +03:30
parent c11092c7c6
commit 5b9e02bbdf
8 changed files with 271 additions and 11 deletions
@@ -582,6 +582,40 @@ public class ActionHandler {
} }
} }
} }
//
// public void showChatListAndSelect() {
// if (Session.chatList == null || Session.chatList.isEmpty()) {
// System.out.println("No chats available.");
// return;
// }
//
// System.out.println("\nYour Chats:");
// for (int i = 0; i < Session.chatList.size(); i++) {
// ChatEntry entry = Session.chatList.get(i);
// String time = (entry.getLastMessageTime() == null)
// ? "No messages yet"
// : entry.getLastMessageTime().toString();
// System.out.println((i + 1) + ". [" + entry.getType() + "] " +
// entry.getName() + " - Last: " + time);
// }
//
// System.out.print("Select a chat by number: ");
// int choice = Integer.parseInt(scanner.nextLine()) - 1;
//
// if(choice == -1){
// System.out.println("Exit...");
// return;
// }
// if (choice < -1 || choice >= Session.chatList.size()) {
// System.out.println("Invalid selection.");
// return;
// }
//
// ChatEntry selected = Session.chatList.get(choice);
// openChat(selected);
// }
public void showChatListAndSelect() { public void showChatListAndSelect() {
if (Session.chatList == null || Session.chatList.isEmpty()) { if (Session.chatList == null || Session.chatList.isEmpty()) {
@@ -589,9 +623,15 @@ public class ActionHandler {
return; return;
} }
List<ChatEntry> activeChats = Session.chatList.stream()
.filter(c -> !c.isArchived())
.toList();
System.out.println("\nYour Chats:"); System.out.println("\nYour Chats:");
for (int i = 0; i < Session.chatList.size(); i++) { System.out.println("0. 📦 Archived Chats");
ChatEntry entry = Session.chatList.get(i);
for (int i = 0; i < activeChats.size(); i++) {
ChatEntry entry = activeChats.get(i);
String time = (entry.getLastMessageTime() == null) String time = (entry.getLastMessageTime() == null)
? "No messages yet" ? "No messages yet"
: entry.getLastMessageTime().toString(); : entry.getLastMessageTime().toString();
@@ -600,23 +640,28 @@ public class ActionHandler {
} }
System.out.print("Select a chat by number: "); System.out.print("Select a chat by number: ");
int choice = Integer.parseInt(scanner.nextLine()) - 1; int choice = Integer.parseInt(scanner.nextLine());
if(choice == -1){ if (choice == 0) {
System.out.println("Exit..."); showArchivedChats();
return; return;
} }
if (choice < -1 || choice >= Session.chatList.size()) {
int index = choice - 1;
if (index < 0 || index >= activeChats.size()) {
System.out.println("Invalid selection."); System.out.println("Invalid selection.");
return; return;
} }
ChatEntry selected = Session.chatList.get(choice); ChatEntry selected = activeChats.get(index);
openChat(selected); openChat(selected);
} }
private void openChat(ChatEntry chat) { private void openChat(ChatEntry chat) {
JSONObject req = new JSONObject(); JSONObject req = new JSONObject();
req.put("action", "get_messages"); req.put("action", "get_messages");
@@ -640,6 +685,42 @@ public class ActionHandler {
} }
private void showArchivedChats() {
List<ChatEntry> archived = Session.chatList.stream()
.filter(ChatEntry::isArchived)
.toList();
if (archived.isEmpty()) {
System.out.println("📭 No archived chats.");
return;
}
System.out.println("\n📦 Archived Chats:");
for (int i = 0; i < archived.size(); i++) {
ChatEntry entry = archived.get(i);
String time = (entry.getLastMessageTime() == null)
? "No messages yet"
: entry.getLastMessageTime().toString();
System.out.println((i + 1) + ". [" + entry.getType() + "] " +
entry.getName() + " - Last: " + time);
}
System.out.print("Select a chat by number (or 0 to return): ");
int choice = Integer.parseInt(scanner.nextLine());
if (choice == 0) {
System.out.println("🔙 Returning to main chat list...");
return;
}
if (choice < 1 || choice > archived.size()) {
System.out.println("❌ Invalid selection.");
return;
}
ChatEntry selected = archived.get(choice - 1);
openChat(selected);
}
@@ -1920,4 +2001,50 @@ public class ActionHandler {
return null; return null;
} }
} }
private void archiveChat(UUID chatId, String chatType) {
JSONObject req = new JSONObject();
req.put("action", "archive_chat");
req.put("chat_id", chatId.toString());
req.put("chat_type", chatType);
JSONObject res = sendWithResponse(req);
if (res != null) System.out.println(res.getString("message"));
}
private void unarchiveChat(UUID chatId, String chatType) {
JSONObject req = new JSONObject();
req.put("action", "unarchive_chat");
req.put("chat_id", chatId.toString());
req.put("chat_type", chatType);
JSONObject res = sendWithResponse(req);
if (res != null) System.out.println(res.getString("message"));
}
// private void toggleArchiveChat(ChatEntry chat) {
// JSONObject req = new JSONObject();
// if (chat.isArchived()) {
// req.put("action", "unarchive_chat");
// } else {
// req.put("action", "archive_chat");
// }
// req.put("chat_id", chat.getId().toString());
// req.put("chat_type", chat.getType());
//
// JSONObject res = sendWithResponse(req);
// if (res != null) {
// System.out.println(res.getString("message"));
//
// // تغییر وضعیت آرشیو به‌صورت لوکالی
// chat.setArchived(!chat.isArchived());
//
// // اگر در لیست اصلی یا آرشیو بود، بعد از تغییر منو رو ببند
// System.out.println("🔄 Returning to chat list...");
// forceExitChat = true; // از منو خارج بشیم
// }
} }
@@ -3,13 +3,17 @@ package org.to.telegramfinalproject.Client;
import org.json.JSONObject; import org.json.JSONObject;
import org.to.telegramfinalproject.Models.ChatEntry; import org.to.telegramfinalproject.Models.ChatEntry;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
// method for save data from server response // method for save data from server response
public class Session { public class Session {
public static JSONObject currentUser; public static JSONObject currentUser;
public static List<ChatEntry> chatList; public static List<ChatEntry> chatList;
public static List<UUID> archivedChatIds = new ArrayList<>();
public static String getUserUUID() { public static String getUserUUID() {
if (currentUser.has("uuid")) return currentUser.getString("uuid"); if (currentUser.has("uuid")) return currentUser.getString("uuid");
@@ -0,0 +1,72 @@
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.List;
import java.util.UUID;
public class ArchivedChatDatabase {
public static boolean archiveChat(UUID userId, UUID chatId, String chatType) {
String sql = "INSERT INTO archived_chats (user_id, chat_id, chat_type) VALUES (?, ?, ?) ON CONFLICT DO NOTHING";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, userId);
ps.setObject(2, chatId);
ps.setString(3, chatType);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static boolean unarchiveChat(UUID userId, UUID chatId) {
String sql = "DELETE FROM archived_chats WHERE user_id = ? AND chat_id = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, userId);
ps.setObject(2, chatId);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static boolean isChatArchived(UUID userId, UUID chatId) {
String sql = "SELECT 1 FROM archived_chats WHERE user_id = ? AND chat_id = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, userId);
ps.setObject(2, chatId);
ResultSet rs = ps.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static List<UUID> getArchivedChats(UUID userId) {
List<UUID> list = new ArrayList<>();
String sql = "SELECT chat_id FROM archived_chats WHERE user_id = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, userId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
list.add(UUID.fromString(rs.getString("chat_id")));
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
@@ -7,7 +7,7 @@ import java.sql.SQLException;
public class ConnectionDb { public class ConnectionDb {
private static final String JDBC_URL = "jdbc:postgresql://localhost:5432/Telegram"; private static final String JDBC_URL = "jdbc:postgresql://localhost:5432/Telegram";
private static final String USERNAME = "postgres"; private static final String USERNAME = "postgres";
private static final String PASSWORD = "124postpass"; private static final String PASSWORD = "Partow@1384";
public ConnectionDb() { public ConnectionDb() {
} }
@@ -444,7 +444,7 @@ public class GroupDatabase {
stmt.setObject(2, userId); stmt.setObject(2, userId);
ResultSet rs = stmt.executeQuery(); ResultSet rs = stmt.executeQuery();
return rs.next(); // اگر رکوردی پیدا شد یعنی owner است return rs.next();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -460,7 +460,7 @@ public class GroupDatabase {
ResultSet rs = stmt.executeQuery(); ResultSet rs = stmt.executeQuery();
if (rs.next()) { if (rs.next()) {
String role = rs.getString("role"); String role = rs.getString("role");
return "admin".equals(role) || "owner".equals(role); // owner هم admin هست return "admin".equals(role) || "owner".equals(role);
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
@@ -508,7 +508,7 @@ public class GroupDatabase {
while (rs.next()) { while (rs.next()) {
JSONObject member = new JSONObject(); JSONObject member = new JSONObject();
member.put("profile_name", rs.getString("profile_name")); member.put("profile_name", rs.getString("profile_name"));
member.put("user_id", rs.getString("user_id")); // آیدی قابل نمایش member.put("user_id", rs.getString("user_id"));
member.put("internal_uuid", rs.getObject("internal_uuid").toString()); member.put("internal_uuid", rs.getObject("internal_uuid").toString());
member.put("role", rs.getString("role")); member.put("role", rs.getString("role"));
@@ -264,6 +264,8 @@ public class userDatabase {
return null; return null;
} }
public List<User> searchUsers(String keyword, UUID currentUserId) { public List<User> searchUsers(String keyword, UUID currentUserId) {
String query = """ String query = """
SELECT * FROM users SELECT * FROM users
@@ -87,4 +87,15 @@ public class ChatEntry {
public void setPermissions(JSONObject permissions) { public void setPermissions(JSONObject permissions) {
this.permissions = permissions; this.permissions = permissions;
} }
private boolean archived = false;
public boolean isArchived() {
return archived;
}
public void setArchived(boolean archived) {
this.archived = archived;
}
} }
@@ -1189,6 +1189,50 @@ public class ClientHandler implements Runnable {
break; break;
} }
case "archive_chat": {
UUID chatId = UUID.fromString(requestJson.getString("chat_id"));
String chatType = requestJson.getString("chat_type");
boolean success = ArchivedChatDatabase.archiveChat(currentUser.getInternal_uuid(), chatId, chatType);
response = success
? new ResponseModel("success", "Chat archived successfully.")
: new ResponseModel("error", "Failed to archive chat.");
break;
}
case "unarchive_chat": {
UUID chatId = UUID.fromString(requestJson.getString("chat_id"));
boolean success = ArchivedChatDatabase.unarchiveChat(currentUser.getInternal_uuid(), chatId);
response = success
? new ResponseModel("success", "Chat unarchived successfully.")
: new ResponseModel("error", "Failed to unarchive chat.");
break;
}
case "get_archived_chats": {
if (currentUser == null) {
response = new ResponseModel("error", "Unauthorized. Please login first.");
break;
}
List<UUID> archived = ArchivedChatDatabase.getArchivedChats(currentUser.getInternal_uuid());
boolean success = archived != null;
response = success
? new ResponseModel(
"success",
"Archived chat list fetched successfully.",
new JSONObject().put("archived", new JSONArray(archived.stream().map(UUID::toString).toList()))
)
: new ResponseModel("error", "Failed to fetch archived chats.");
break;
}
default: default: