added search in contact list.
This commit is contained in:
@@ -3,6 +3,7 @@ package org.to.telegramfinalproject.Client;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Database.PrivateChatDatabase;
|
import org.to.telegramfinalproject.Database.PrivateChatDatabase;
|
||||||
|
import org.to.telegramfinalproject.Database.ContactDatabase;
|
||||||
import org.to.telegramfinalproject.Models.ChatEntry;
|
import org.to.telegramfinalproject.Models.ChatEntry;
|
||||||
import org.to.telegramfinalproject.Models.ContactEntry;
|
import org.to.telegramfinalproject.Models.ContactEntry;
|
||||||
import org.to.telegramfinalproject.Models.SearchRequestModel;
|
import org.to.telegramfinalproject.Models.SearchRequestModel;
|
||||||
@@ -558,9 +559,13 @@ public class ActionHandler {
|
|||||||
ContactEntry entry = new ContactEntry(
|
ContactEntry entry = new ContactEntry(
|
||||||
UUID.fromString(c.getString("contact_id")),
|
UUID.fromString(c.getString("contact_id")),
|
||||||
c.getString("user_id"),
|
c.getString("user_id"),
|
||||||
|
c.getString("contact_displayId"),
|
||||||
c.getString("profile_name"),
|
c.getString("profile_name"),
|
||||||
c.optString("image_url", ""),
|
c.optString("image_url", ""),
|
||||||
c.optBoolean("is_blocked", false)
|
c.optBoolean("is_blocked", false),
|
||||||
|
c.isNull("last_seen")
|
||||||
|
? null
|
||||||
|
: LocalDateTime.parse(c.getString("last_seen"))
|
||||||
);
|
);
|
||||||
Session.contactEntries.add(entry);
|
Session.contactEntries.add(entry);
|
||||||
}
|
}
|
||||||
@@ -838,10 +843,118 @@ public class ActionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public void showContactList() {
|
||||||
|
// List<ContactEntry> contacts = Session.contactEntries;
|
||||||
|
// if (contacts.isEmpty()) {
|
||||||
|
// System.out.println("📭 You have no contacts.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// System.out.println("👥 Your Contacts:");
|
||||||
|
// for (int i = 0; i < contacts.size(); i++) {
|
||||||
|
// System.out.println((i + 1) + ". " + contacts.get(i));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// System.out.print("Select a contact (0 to go back): ");
|
||||||
|
// int choice = scanner.nextInt();
|
||||||
|
// scanner.nextLine();
|
||||||
|
//
|
||||||
|
// if (choice == 0) return;
|
||||||
|
// if (choice < 1 || choice > contacts.size()) {
|
||||||
|
// System.out.println("❌ Invalid choice.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ContactEntry selected = contacts.get(choice - 1);
|
||||||
|
// System.out.println("\n📇 What do you want to do with " + selected.getProfileName() + "?");
|
||||||
|
// System.out.println("1. View Profile");
|
||||||
|
// System.out.println("2. Send Message");
|
||||||
|
// System.out.print("Enter your choice: ");
|
||||||
|
// int action = scanner.nextInt();
|
||||||
|
// scanner.nextLine();
|
||||||
|
//
|
||||||
|
// switch (action) {
|
||||||
|
// case 1 -> viewProfile(selected.getContactId());
|
||||||
|
// case 2 -> startPrivateChat(selected);
|
||||||
|
// default -> System.out.println("❌ Invalid option.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public void showContactList() {
|
public void showContactList() {
|
||||||
List<ContactEntry> contacts = Session.contactEntries;
|
System.out.println("1. View All Contacts");
|
||||||
|
System.out.println("2. Search Contacts");
|
||||||
|
System.out.println("Choose an option: (0 to go back)");
|
||||||
|
int option = scanner.nextInt();
|
||||||
|
scanner.nextLine();
|
||||||
|
|
||||||
|
// Handle invalid input
|
||||||
|
while (option < 0 || option > 2) {
|
||||||
|
System.out.println("Invalid choice. Try again: ");
|
||||||
|
option = scanner.nextInt();
|
||||||
|
scanner.nextLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ContactEntry> contacts;
|
||||||
|
|
||||||
|
if (option == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (option == 1) {
|
||||||
|
contacts = Session.contactEntries;
|
||||||
|
|
||||||
|
} else if (option == 2) {
|
||||||
|
contacts = new ArrayList<>();
|
||||||
|
|
||||||
|
System.out.print("Enter name or user ID to search: ");
|
||||||
|
String searchTerm = scanner.nextLine();
|
||||||
|
|
||||||
|
// Handle invalid input
|
||||||
|
while (searchTerm.isEmpty()) {
|
||||||
|
System.out.print("Search key can not be empty. Try again: ");
|
||||||
|
searchTerm = scanner.nextLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a request to server
|
||||||
|
JSONObject request = new JSONObject();
|
||||||
|
request.put("action", "search_contacts");
|
||||||
|
request.put("user_id", Session.getUserUUID());
|
||||||
|
request.put("search_term", searchTerm);
|
||||||
|
|
||||||
|
JSONObject response = ActionHandler.sendWithResponse(request);
|
||||||
|
|
||||||
|
if (!response.optString("status", "fail").equals("success")) {
|
||||||
|
System.out.println("Failed to search contacts: " + response.optString("message", "Unknown error"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject data = response.getJSONObject("data");
|
||||||
|
JSONArray contactsJson = data.getJSONArray("contacts");
|
||||||
|
|
||||||
|
for (int i = 0; i < contactsJson.length(); i++) {
|
||||||
|
JSONObject contact = contactsJson.getJSONObject(i);
|
||||||
|
|
||||||
|
UUID contactId = UUID.fromString(contact.getString("contact_id"));
|
||||||
|
String userId = contact.getString("user_id");
|
||||||
|
String contact_displayId = contact.getString("contact_display_id");
|
||||||
|
String profileName = contact.getString("profile_name");
|
||||||
|
String imageUrl = contact.optString("image_url", "");
|
||||||
|
boolean isBlocked = contact.getBoolean("is_blocked");
|
||||||
|
String lastSeenString = contact.getString("last_seen");
|
||||||
|
LocalDateTime lastSeen = null;
|
||||||
|
if (lastSeenString != null) {
|
||||||
|
lastSeen = LocalDateTime.parse(lastSeenString);
|
||||||
|
}
|
||||||
|
|
||||||
|
contacts.add(new ContactEntry(contactId, userId, contact_displayId, profileName, imageUrl, isBlocked, lastSeen));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("❌ Invalid choice.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (contacts.isEmpty()) {
|
if (contacts.isEmpty()) {
|
||||||
System.out.println("📭 You have no contacts.");
|
System.out.println("📭 No contacts found.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,6 +977,7 @@ public class ActionHandler {
|
|||||||
System.out.println("\n📇 What do you want to do with " + selected.getProfileName() + "?");
|
System.out.println("\n📇 What do you want to do with " + selected.getProfileName() + "?");
|
||||||
System.out.println("1. View Profile");
|
System.out.println("1. View Profile");
|
||||||
System.out.println("2. Send Message");
|
System.out.println("2. Send Message");
|
||||||
|
System.out.println("3. Remove Contact");
|
||||||
System.out.print("Enter your choice: ");
|
System.out.print("Enter your choice: ");
|
||||||
int action = scanner.nextInt();
|
int action = scanner.nextInt();
|
||||||
scanner.nextLine();
|
scanner.nextLine();
|
||||||
@@ -871,10 +985,29 @@ public class ActionHandler {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case 1 -> viewProfile(selected.getContactId());
|
case 1 -> viewProfile(selected.getContactId());
|
||||||
case 2 -> startPrivateChat(selected);
|
case 2 -> startPrivateChat(selected);
|
||||||
|
case 3 -> {
|
||||||
|
// Send a request to server
|
||||||
|
JSONObject request = new JSONObject();
|
||||||
|
request.put("action", "remove_contact");
|
||||||
|
request.put("user_id", Session.getUserUUID()); // Current user
|
||||||
|
request.put("contact_id", selected.getContactId().toString()); // Contact to remove
|
||||||
|
|
||||||
|
JSONObject response = ActionHandler.sendWithResponse(request);
|
||||||
|
|
||||||
|
if ("success".equals(response.optString("status"))) {
|
||||||
|
System.out.println("✅ Contact removed successfully.");
|
||||||
|
Session.contactEntries.remove(selected); // Remove from local session list
|
||||||
|
} else {
|
||||||
|
System.out.println("❌ Failed to remove contact: " +
|
||||||
|
response.optString("message", "Unknown error"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default -> System.out.println("❌ Invalid option.");
|
default -> System.out.println("❌ Invalid option.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void viewProfile(UUID targetId) {
|
private void viewProfile(UUID targetId) {
|
||||||
JSONObject req = new JSONObject();
|
JSONObject req = new JSONObject();
|
||||||
req.put("action", "view_profile");
|
req.put("action", "view_profile");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.to.telegramfinalproject.Models;
|
package org.to.telegramfinalproject.Models;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ContactEntry {
|
public class ContactEntry {
|
||||||
@@ -8,6 +9,9 @@ public class ContactEntry {
|
|||||||
private String profileName;
|
private String profileName;
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
private boolean isBlocked;
|
private boolean isBlocked;
|
||||||
|
private LocalDateTime lastSeenTime;
|
||||||
|
private String contact_displayId;
|
||||||
|
|
||||||
|
|
||||||
public ContactEntry(UUID contactId, String userId, String profileName, String imageUrl, boolean isBlocked) {
|
public ContactEntry(UUID contactId, String userId, String profileName, String imageUrl, boolean isBlocked) {
|
||||||
this.contactId = contactId;
|
this.contactId = contactId;
|
||||||
@@ -17,6 +21,16 @@ public class ContactEntry {
|
|||||||
this.isBlocked = isBlocked;
|
this.isBlocked = isBlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ContactEntry(UUID contactId, String userId,String contact_displayId , String profileName, String imageUrl, boolean isBlocked, LocalDateTime lastSeenTime){
|
||||||
|
this.contactId = contactId;
|
||||||
|
this.userId = userId;
|
||||||
|
this.contact_displayId = contact_displayId;
|
||||||
|
this.profileName = profileName;
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
this.isBlocked = isBlocked;
|
||||||
|
this.lastSeenTime = lastSeenTime;
|
||||||
|
}
|
||||||
|
|
||||||
public UUID getContactId() {
|
public UUID getContactId() {
|
||||||
return contactId;
|
return contactId;
|
||||||
}
|
}
|
||||||
@@ -37,8 +51,24 @@ public class ContactEntry {
|
|||||||
return isBlocked;
|
return isBlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getLastSeenTime() {
|
||||||
|
return lastSeenTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSeenTime(LocalDateTime lastSeenTime) {
|
||||||
|
this.lastSeenTime = lastSeenTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContact_displayId() {
|
||||||
|
return contact_displayId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContact_displayId(String contact_displayId) {
|
||||||
|
this.contact_displayId = contact_displayId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return profileName + " (" + userId + ")" + (isBlocked ? " [Blocked]" : "");
|
return profileName + " (@" + contact_displayId + ")" + (isBlocked ? " [Blocked]" : "") + " Last Seen:" + (lastSeenTime != null ? " " + lastSeenTime.toString() : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.to.telegramfinalproject.Server;
|
package org.to.telegramfinalproject.Server;
|
||||||
|
|
||||||
|
import javafx.geometry.Side;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.to.telegramfinalproject.Database.*;
|
import org.to.telegramfinalproject.Database.*;
|
||||||
@@ -111,10 +112,13 @@ public class ClientHandler implements Runnable {
|
|||||||
JSONObject c = new JSONObject();
|
JSONObject c = new JSONObject();
|
||||||
c.put("user_id", contact.getUser_id().toString());
|
c.put("user_id", contact.getUser_id().toString());
|
||||||
c.put("contact_id", contact.getContact_id().toString());
|
c.put("contact_id", contact.getContact_id().toString());
|
||||||
|
User Contact = userDatabase.findByInternalUUID(contact.getContact_id());
|
||||||
|
c.put("contact_displayId", Contact.getUser_id());
|
||||||
c.put("is_blocked", contact.getIs_blocked());
|
c.put("is_blocked", contact.getIs_blocked());
|
||||||
|
|
||||||
c.put("profile_name", target.getProfile_name());
|
c.put("profile_name", target.getProfile_name());
|
||||||
c.put("image_url", target.getImage_url());
|
c.put("image_url", target.getImage_url());
|
||||||
|
c.put("last_seen", Contact.getLast_seen());
|
||||||
|
|
||||||
contactList.put(c);
|
contactList.put(c);
|
||||||
}
|
}
|
||||||
@@ -2122,6 +2126,22 @@ public class ClientHandler implements Runnable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "search_contacts": {
|
||||||
|
String user_id = requestJson.getString("user_id");
|
||||||
|
String search_term = requestJson.getString("search_term");
|
||||||
|
|
||||||
|
response = SidebarService.handleSearchContacts(user_id, search_term);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "remove_contact": {
|
||||||
|
UUID user_id = UUID.fromString(requestJson.getString("user_id"));
|
||||||
|
UUID contactId = UUID.fromString(requestJson.getString("contact_id"));
|
||||||
|
|
||||||
|
response = SidebarService.handleRemoveContact(user_id, contactId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
response = new ResponseModel("error", "Unknown action: " + action);
|
response = new ResponseModel("error", "Unknown action: " + action);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package org.to.telegramfinalproject.Server;
|
|||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.to.telegramfinalproject.Database.ContactDatabase;
|
||||||
import org.to.telegramfinalproject.Database.MessageDatabase;
|
import org.to.telegramfinalproject.Database.MessageDatabase;
|
||||||
import org.to.telegramfinalproject.Database.PrivateChatDatabase;
|
import org.to.telegramfinalproject.Database.PrivateChatDatabase;
|
||||||
import org.to.telegramfinalproject.Database.userDatabase;
|
import org.to.telegramfinalproject.Database.userDatabase;
|
||||||
|
import org.to.telegramfinalproject.Models.ContactEntry;
|
||||||
import org.to.telegramfinalproject.Models.Message;
|
import org.to.telegramfinalproject.Models.Message;
|
||||||
import org.to.telegramfinalproject.Models.ResponseModel;
|
import org.to.telegramfinalproject.Models.ResponseModel;
|
||||||
import org.to.telegramfinalproject.Models.User;
|
import org.to.telegramfinalproject.Models.User;
|
||||||
@@ -12,6 +14,7 @@ import org.to.telegramfinalproject.Models.User;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -158,6 +161,56 @@ public class SidebarService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search in user's contact list
|
||||||
|
public static ResponseModel handleSearchContacts(String userUUID, String searchTerm) {
|
||||||
|
if (searchTerm == null || searchTerm.trim().isEmpty()) {
|
||||||
|
return new ResponseModel("error", "Search term cannot be empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ContactEntry> searchResult = ContactDatabase.searchContacts(UUID.fromString(userUUID), searchTerm);
|
||||||
|
|
||||||
|
if (searchResult.isEmpty()) {
|
||||||
|
return new ResponseModel("error", "No contacts found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
JSONArray contacts = new JSONArray();
|
||||||
|
|
||||||
|
for (ContactEntry entry : searchResult) {
|
||||||
|
contacts.put(new JSONObject()
|
||||||
|
.put("contact_id", entry.getContactId())
|
||||||
|
.put("user_id", entry.getUserId())
|
||||||
|
.put("contact_display_id", entry.getContact_displayId())
|
||||||
|
.put("profile_name", entry.getProfileName())
|
||||||
|
.put("image_url", entry.getImageUrl())
|
||||||
|
.put("is_blocked", entry.isBlocked())
|
||||||
|
.put("last_seen", entry.getLastSeenTime())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
data.put("contacts", contacts);
|
||||||
|
|
||||||
|
if (searchResult.isEmpty()) {
|
||||||
|
return new ResponseModel("error", "No contacts found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResponseModel("success", "Search contacts successfully.", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a contact in user's contact list
|
||||||
|
public static ResponseModel handleRemoveContact(UUID userUUID, UUID contactId) {
|
||||||
|
if (userUUID == null || contactId == null) {
|
||||||
|
return new ResponseModel("error", "Invalid input.");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean removed = ContactDatabase.removeContact(userUUID, contactId);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
return new ResponseModel("success", "Contact removed successfully.");
|
||||||
|
} else {
|
||||||
|
return new ResponseModel("error", "Contact not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get saved messages data
|
// Get saved messages data
|
||||||
public static ResponseModel handleGetSavedMessages(UUID userId) {
|
public static ResponseModel handleGetSavedMessages(UUID userId) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user