Work on add contact to contact list
This commit is contained in:
@@ -69,20 +69,12 @@ public class ClientHandler implements Runnable {
|
||||
} else {
|
||||
|
||||
User user = authService.login(request.getUsername(), request.getPassword());
|
||||
|
||||
if (user == null){
|
||||
if (user == null) {
|
||||
response = new ResponseModel("error", "Login failed.");
|
||||
break;
|
||||
}
|
||||
this.currentUser = user;
|
||||
|
||||
if (SessionManager.contains(user.getInternal_uuid())) {
|
||||
response = new ResponseModel("error", "You are already logged in from another device.");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
SessionManager.addUser(user.getInternal_uuid(), this.socket);
|
||||
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
|
||||
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
|
||||
@@ -126,21 +118,16 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
case "logout": {
|
||||
String user_Id = requestJson.optString("user_id");
|
||||
if (user_Id != null && !user_Id.isEmpty()) {
|
||||
try {
|
||||
UUID uuid = UUID.fromString(user_Id);
|
||||
userDatabase.updateUserStatus(uuid, "offline");
|
||||
userDatabase.updateLastSeen(uuid);
|
||||
SessionManager.removeUser(uuid);
|
||||
response = new ResponseModel("success", "Logged out.");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
response = new ResponseModel("error", "Invalid UUID format for user_id.");
|
||||
}
|
||||
if (userId != null && !user_Id.isEmpty()) {
|
||||
UUID uuid = UUID.fromString(user_Id);
|
||||
userDatabase.updateUserStatus(uuid, "offline");
|
||||
userDatabase.updateLastSeen(uuid);
|
||||
SessionManager.removeUser(uuid);
|
||||
response = new ResponseModel("success", "Logged out.");
|
||||
} else {
|
||||
response = new ResponseModel("error", "Invalid user_id for logout.");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case "search": {
|
||||
@@ -154,6 +141,7 @@ public class ClientHandler implements Runnable {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("type", "user");
|
||||
obj.put("id", u.getUser_id());
|
||||
obj.put("uuid", u.getInternal_uuid().toString()); // ✅ اضافه شود
|
||||
obj.put("name", u.getProfile_name());
|
||||
results.add(obj);
|
||||
}
|
||||
@@ -161,7 +149,8 @@ public class ClientHandler implements Runnable {
|
||||
for (Group g : GroupDatabase.searchGroups(keyword)) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("type", "group");
|
||||
obj.put("id", g.getGroup_id());
|
||||
obj.put("id", g.getGroup_id()); // قابل نمایش
|
||||
obj.put("uuid", g.getInternal_uuid().toString()); // برای عملیات
|
||||
obj.put("name", g.getGroup_name());
|
||||
results.add(obj);
|
||||
}
|
||||
@@ -169,7 +158,8 @@ public class ClientHandler implements Runnable {
|
||||
for (Channel c : ChannelDatabase.searchChannels(keyword)) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("type", "channel");
|
||||
obj.put("id", c.getChannel_id());
|
||||
obj.put("id", c.getChannel_id()); // قابل نمایش
|
||||
obj.put("uuid", c.getInternal_uuid().toString()); // برای عملیات
|
||||
obj.put("name", c.getChannel_name());
|
||||
results.add(obj);
|
||||
}
|
||||
@@ -224,6 +214,40 @@ public class ClientHandler implements Runnable {
|
||||
break;
|
||||
}
|
||||
|
||||
case "add_contact": {
|
||||
UUID userUUID = new userDatabase().findByUserId(requestJson.getString("user_id")).getInternal_uuid();
|
||||
UUID contactUUID = UUID.fromString(requestJson.getString("contact_id"));
|
||||
|
||||
boolean success = ContactDatabase.addContact(userUUID, contactUUID);
|
||||
response = success
|
||||
? new ResponseModel("success", "Contact added successfully.")
|
||||
: new ResponseModel("error", "Failed to add contact. Maybe already exists.");
|
||||
break;
|
||||
}
|
||||
|
||||
case "join_group": {
|
||||
UUID userUUID = new userDatabase().findByUserId(requestJson.getString("user_id")).getInternal_uuid();
|
||||
UUID groupUUID = GroupDatabase.findInternalUUIDByGroupId(requestJson.getString("id"));
|
||||
|
||||
boolean joined = GroupDatabase.addMemberToGroup(userUUID, groupUUID);
|
||||
response = joined
|
||||
? new ResponseModel("success", "Joined group.")
|
||||
: new ResponseModel("error", "Failed to join group.");
|
||||
break;
|
||||
}
|
||||
|
||||
case "join_channel": {
|
||||
UUID userUUID = new userDatabase().findByUserId(requestJson.getString("user_id")).getInternal_uuid();
|
||||
UUID channelUUID = ChannelDatabase.findInternalUUIDByChannelId(requestJson.getString("id"));
|
||||
|
||||
boolean joined = ChannelDatabase.addSubscriberToChannel(userUUID, channelUUID);
|
||||
response = joined
|
||||
? new ResponseModel("success", "Joined channel.")
|
||||
: new ResponseModel("error", "Failed to join channel.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
response = new ResponseModel("error", "Unknown action: " + action);
|
||||
}
|
||||
@@ -236,7 +260,7 @@ public class ClientHandler implements Runnable {
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("Connection with client lost.");
|
||||
userId = (currentUser != null) ? currentUser.getInternal_uuid() : SessionManager.getUserIdBySocket(this.socket);
|
||||
userId = (currentUser != null) ? currentUser.getInternal_uuid() : SessionManager.getUserIdBySocket(this.socket);
|
||||
if (userId != null) {
|
||||
userDatabase.updateUserStatus(userId, "offline");
|
||||
userDatabase.updateLastSeen(userId);
|
||||
@@ -261,4 +285,4 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.to.telegramfinalproject.Server;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.to.telegramfinalproject.Database.userDatabase;
|
||||
import org.to.telegramfinalproject.Database.ContactDatabase;
|
||||
public class ContactService {
|
||||
public static boolean addContact(UUID userId, UUID contactId) {
|
||||
if (userId.equals(contactId)) return false;
|
||||
if (userDatabase.findByInternalUUID(contactId) == null) return false;
|
||||
if (userDatabase.findByInternalUUID(userId) == null) return false;
|
||||
if (ContactDatabase.existsContact(userId, contactId)) return false;
|
||||
|
||||
return ContactDatabase.addContact(userId, contactId);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
public class MainServer {
|
||||
private static final int PORT = 12345;
|
||||
private static final int PORT = 8000;
|
||||
|
||||
public static void main(String[] args) {
|
||||
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
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.Models.Message;
|
||||
import org.to.telegramfinalproject.Models.User;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RealTimeEventDispatcher {
|
||||
|
||||
public static void sendToUser(UUID userId, JSONObject data) {
|
||||
Socket socket = SessionManager.getUserSocket(userId);
|
||||
|
||||
|
||||
if (socket != null && !socket.isClosed()) {
|
||||
try {
|
||||
|
||||
|
||||
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
|
||||
out.println(data.toString());
|
||||
} catch (IOException e) {
|
||||
System.err.println("❌ Error sending to user: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
System.out.println("⚠️ User " + userId + " is offline. Skipping real-time send.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void broadcastToUsers(List<UUID> userIds, JSONObject data) {
|
||||
for (UUID userId : userIds) {
|
||||
sendToUser(userId, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static JSONObject buildEvent(String action, JSONObject payload) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("action", action);
|
||||
json.put("data", payload);
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
public static void notifyNewMessage(Message msg, User sender) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("sender", sender.getUser_id());
|
||||
data.put("receiver_type", msg.getReceiver_type());
|
||||
data.put("receiver_id", msg.getReceiver_id());
|
||||
data.put("content", msg.getContent());
|
||||
data.put("time", msg.getSend_at().toString());
|
||||
|
||||
JSONObject event = buildEvent("new_message", data);
|
||||
|
||||
switch (msg.getReceiver_type()) {
|
||||
case "private" -> RealTimeEventDispatcher.sendToUser(msg.getReceiver_id(), event);
|
||||
case "group" -> {
|
||||
List<UUID> memberIds = GroupDatabase.getMemberUUIDs(msg.getReceiver_id());
|
||||
memberIds.remove(sender.getInternal_uuid());
|
||||
RealTimeEventDispatcher.broadcastToUsers(memberIds, event);
|
||||
}
|
||||
case "channel" -> {
|
||||
List<UUID> subscriberIds = ChannelDatabase.getSubscriberUUIDs(msg.getReceiver_id());
|
||||
subscriberIds.remove(sender.getInternal_uuid());
|
||||
subscriberIds.remove(sender.getInternal_uuid());
|
||||
RealTimeEventDispatcher.broadcastToUsers(subscriberIds, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void notifyMessageEdited(UUID messageId, String newContent, List<UUID> receivers) {
|
||||
|
||||
String editTime = LocalDateTime.now().toString();
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("message_id", messageId.toString());
|
||||
data.put("new_content", newContent);
|
||||
data.put("edited_at", editTime);
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "edit_message");
|
||||
event.put("data", data);
|
||||
|
||||
broadcastToUsers(receivers, event);
|
||||
}
|
||||
|
||||
|
||||
public static void notifyMessageDeleted(UUID messageId, List<UUID> receivers) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("message_id", messageId.toString());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "delete_message");
|
||||
event.put("data", data);
|
||||
|
||||
broadcastToUsers(receivers, event);
|
||||
}
|
||||
|
||||
public static void notifyUserUpdated(UUID userId, String newProfileName, String newImageUrl, List<UUID> contactIds) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("user_id", userId.toString());
|
||||
data.put("new_name", newProfileName);
|
||||
data.put("new_image_url", newImageUrl);
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "update_user");
|
||||
event.put("data", data);
|
||||
|
||||
broadcastToUsers(contactIds, event);
|
||||
}
|
||||
|
||||
public static void notifyChatDeleted(String type, UUID id, List<UUID> affectedUsers) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("chat_type", type); // private, group, channel
|
||||
data.put("chat_id", id.toString());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "chat_deleted");
|
||||
event.put("data", data);
|
||||
|
||||
broadcastToUsers(affectedUsers, event);
|
||||
}
|
||||
|
||||
public static void notifyGroupOrChannelUpdated(String type, UUID id, String newName, String newImageUrl, List<UUID> affectedUsers) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("chat_type", type); // "group" or "channel"
|
||||
data.put("chat_id", id.toString());
|
||||
data.put("new_name", newName);
|
||||
data.put("new_image_url", newImageUrl);
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "update_group_or_channel");
|
||||
event.put("data", data);
|
||||
|
||||
broadcastToUsers(affectedUsers, event);
|
||||
}
|
||||
|
||||
public static void notifyMediaMessage(Message msg, User sender) {
|
||||
JSONObject data = new JSONObject();
|
||||
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());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "new_media");
|
||||
event.put("data", data);
|
||||
|
||||
switch (msg.getReceiver_type()) {
|
||||
case "private" -> sendToUser(msg.getReceiver_id(), event);
|
||||
case "group" -> {
|
||||
List<UUID> members = GroupDatabase.getMemberUUIDs(msg.getReceiver_id());
|
||||
members.remove(sender.getInternal_uuid());
|
||||
broadcastToUsers(members, event);
|
||||
}
|
||||
case "channel" -> {
|
||||
List<UUID> subs = ChannelDatabase.getSubscriberUUIDs(msg.getReceiver_id());
|
||||
subs.remove(sender.getInternal_uuid());
|
||||
broadcastToUsers(subs, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyAddedToChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("chat_type", type); // group یا channel
|
||||
data.put("chat_id", chatId.toString());
|
||||
data.put("chat_name", chatName);
|
||||
data.put("image_url", imageUrl);
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", type.equals("group") ? "added_to_group" : "added_to_channel");
|
||||
event.put("data", data);
|
||||
|
||||
sendToUser(userId, event);
|
||||
}
|
||||
|
||||
public static void notifyRemovedFromChat(String type, UUID chatId, UUID userId) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("chat_type", type);
|
||||
data.put("chat_id", chatId.toString());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", type.equals("group") ? "removed_from_group" : "removed_from_channel");
|
||||
event.put("data", data);
|
||||
|
||||
sendToUser(userId, event);
|
||||
}
|
||||
public static void notifyMessageSeen(UUID messageId, UUID senderId) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("message_id", messageId.toString());
|
||||
data.put("seen_at", LocalDateTime.now().toString());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "message_seen");
|
||||
event.put("data", data);
|
||||
|
||||
sendToUser(senderId, event);
|
||||
}
|
||||
|
||||
|
||||
public static void notifyBlocked(UUID blockerId, UUID blockedUserId) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("blocker_id", blockerId.toString());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "blocked_by_user");
|
||||
event.put("data", data);
|
||||
|
||||
sendToUser(blockedUserId, event);
|
||||
}
|
||||
|
||||
|
||||
public static void notifyUnblocked(UUID unblockerId, UUID unblockedUserId) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("unblocker_id", unblockerId.toString());
|
||||
|
||||
JSONObject event = new JSONObject();
|
||||
event.put("action", "unblocked_by_user");
|
||||
event.put("data", data);
|
||||
|
||||
sendToUser(unblockedUserId, event);
|
||||
}
|
||||
|
||||
public static void notifyUserStatusChanged(UUID userId, String status, List<UUID> contacts) {
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("user_id", userId.toString());
|
||||
data.put("status", status); // online | offline
|
||||
data.put("time", LocalDateTime.now().toString());
|
||||
|
||||
JSONObject event = buildEvent("user_status_changed", data);
|
||||
|
||||
broadcastToUsers(contacts, event);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user