RealTime Action (Server)
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
package org.to.telegramfinalproject.Client;
|
package org.to.telegramfinalproject.Client;
|
||||||
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@@ -46,7 +45,9 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
case "new_message", "message_edited", "message_deleted",
|
case "new_message", "message_edited", "message_deleted",
|
||||||
"user_status_changed", "added_to_group", "added_to_channel",
|
"user_status_changed", "added_to_group", "added_to_channel",
|
||||||
"update_group_or_channel", "chat_deleted",
|
"update_group_or_channel", "chat_deleted",
|
||||||
"blocked_by_user", "unblocked_by_user", "message_seen" -> true;
|
"blocked_by_user", "unblocked_by_user", "message_seen",
|
||||||
|
"removed_from_group", "removed_from_channel",
|
||||||
|
"became_admin", "removed_admin" -> true;
|
||||||
default -> false;
|
default -> false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -111,6 +112,22 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
System.out.println("Seen at: " + msg.getString("seen_at"));
|
System.out.println("Seen at: " + msg.getString("seen_at"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "removed_from_group" -> {
|
||||||
|
System.out.println("\n🚫 You were removed from group: " + msg.getString("chat_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "removed_from_channel" -> {
|
||||||
|
System.out.println("\n🚫 You were removed from channel: " + msg.getString("chat_id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "became_admin" -> {
|
||||||
|
System.out.println("\n⭐ You are now an admin in: " + msg.getString("chat_name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "removed_admin" -> {
|
||||||
|
System.out.println("\n⚠️ You are no longer an admin in: " + msg.getString("chat_name"));
|
||||||
|
}
|
||||||
|
|
||||||
default -> {
|
default -> {
|
||||||
System.out.println("\n❓ Unknown real-time action: " + action);
|
System.out.println("\n❓ Unknown real-time action: " + action);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -601,4 +601,19 @@ public class ChannelDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<UUID> getChannelSubscriberUUIDs(UUID channelId) {
|
||||||
|
List<UUID> subscriberIds = new ArrayList<>();
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement("SELECT user_id FROM channel_subscribers WHERE channel_id = ?")) {
|
||||||
|
stmt.setObject(1, channelId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
subscriberIds.add(UUID.fromString(rs.getString("user_id")));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return subscriberIds;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ public class ContactDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<UUID> getContactUUIDs(UUID userId) {
|
||||||
|
List<Contact> contacts = getContacts(userId);
|
||||||
|
List<UUID> contactIds = new ArrayList<>();
|
||||||
|
for (Contact c : contacts) {
|
||||||
|
contactIds.add(c.getContact_id());
|
||||||
|
}
|
||||||
|
return contactIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean removeContact(UUID user_id, UUID contact_id) {
|
public boolean removeContact(UUID user_id, UUID contact_id) {
|
||||||
|
|||||||
@@ -600,4 +600,19 @@ public class GroupDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<UUID> getGroupMemberUUIDs(UUID groupId) {
|
||||||
|
List<UUID> memberIds = new ArrayList<>();
|
||||||
|
try (Connection conn = ConnectionDb.connect();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement("SELECT user_id FROM group_members WHERE group_id = ?")) {
|
||||||
|
stmt.setObject(1, groupId);
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
memberIds.add(UUID.fromString(rs.getString("user_id")));
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return memberIds;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -79,6 +79,10 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
SessionManager.addUser(user.getInternal_uuid(), this.socket);
|
SessionManager.addUser(user.getInternal_uuid(), this.socket);
|
||||||
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
|
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
|
||||||
|
//RealTime
|
||||||
|
List<UUID> contactIds = ContactDatabase.getContactUUIDs(user.getInternal_uuid());
|
||||||
|
RealTimeEventDispatcher.notifyUserStatusChanged(user.getInternal_uuid(), "online", contactIds);
|
||||||
|
|
||||||
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
|
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
|
||||||
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
|
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
|
||||||
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
||||||
@@ -158,10 +162,17 @@ public class ClientHandler implements Runnable {
|
|||||||
String user_Id = requestJson.optString("user_id");
|
String user_Id = requestJson.optString("user_id");
|
||||||
if (user_Id != null && !user_Id.isEmpty()) {
|
if (user_Id != null && !user_Id.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
UUID uuid = UUID.fromString(user_Id);
|
userId = UUID.fromString(user_Id);
|
||||||
userDatabase.updateUserStatus(uuid, "offline");
|
|
||||||
userDatabase.updateLastSeen(uuid);
|
userDatabase.updateUserStatus(userId, "offline");
|
||||||
SessionManager.removeUser(uuid);
|
|
||||||
|
// Real-Time
|
||||||
|
List<UUID> contacts = ContactDatabase.getContactUUIDs(userId);
|
||||||
|
RealTimeEventDispatcher.notifyUserStatusChanged(userId, "offline", contacts);
|
||||||
|
|
||||||
|
userDatabase.updateLastSeen(userId);
|
||||||
|
SessionManager.removeUser(userId);
|
||||||
|
|
||||||
response = new ResponseModel("success", "Logged out.");
|
response = new ResponseModel("success", "Logged out.");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
response = new ResponseModel("error", "Invalid UUID format.");
|
response = new ResponseModel("error", "Invalid UUID format.");
|
||||||
@@ -320,6 +331,18 @@ public class ClientHandler implements Runnable {
|
|||||||
UUID contactUUID = UUID.fromString(requestJson.getString("contact_id"));
|
UUID contactUUID = UUID.fromString(requestJson.getString("contact_id"));
|
||||||
|
|
||||||
boolean success = ContactDatabase.addContact(userUUID, contactUUID);
|
boolean success = ContactDatabase.addContact(userUUID, contactUUID);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
RealTimeEventDispatcher.notifyAddedToChat(
|
||||||
|
"private",
|
||||||
|
userUUID,
|
||||||
|
currentUser.getProfile_name(),
|
||||||
|
currentUser.getImage_url(),
|
||||||
|
contactUUID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Contact added successfully.")
|
? new ResponseModel("success", "Contact added successfully.")
|
||||||
: new ResponseModel("error", "Failed to add contact. Maybe already exists.");
|
: new ResponseModel("error", "Failed to add contact. Maybe already exists.");
|
||||||
@@ -336,6 +359,13 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
boolean joined = GroupDatabase.addMemberToGroup(userUUID, group.getInternal_uuid());
|
boolean joined = GroupDatabase.addMemberToGroup(userUUID, group.getInternal_uuid());
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (joined) {
|
||||||
|
List<UUID> members = GroupDatabase.getMemberUUIDs(group.getInternal_uuid());
|
||||||
|
RealTimeEventDispatcher.sendGroupOrChannelUpdate("group", group.getInternal_uuid(), group.getGroup_name(), group.getImage_url(), group.getDescription(), members);
|
||||||
|
}
|
||||||
|
|
||||||
response = joined
|
response = joined
|
||||||
? new ResponseModel("success", "Joined group.")
|
? new ResponseModel("success", "Joined group.")
|
||||||
: new ResponseModel("error", "Failed to join group.");
|
: new ResponseModel("error", "Failed to join group.");
|
||||||
@@ -352,6 +382,13 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
boolean joined = ChannelDatabase.addSubscriberToChannel(userUUID, channel.getInternal_uuid());
|
boolean joined = ChannelDatabase.addSubscriberToChannel(userUUID, channel.getInternal_uuid());
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (joined) {
|
||||||
|
List<UUID> members = ChannelDatabase.getChannelSubscriberUUIDs(channel.getInternal_uuid());
|
||||||
|
RealTimeEventDispatcher.sendGroupOrChannelUpdate("channel", channel.getInternal_uuid(), channel.getChannel_name(), channel.getImage_url(), channel.getDescription(), members);
|
||||||
|
}
|
||||||
|
|
||||||
response = joined
|
response = joined
|
||||||
? new ResponseModel("success", "Joined channel.")
|
? new ResponseModel("success", "Joined channel.")
|
||||||
: new ResponseModel("error", "Failed to join channel.");
|
: new ResponseModel("error", "Failed to join channel.");
|
||||||
@@ -620,6 +657,20 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean success = ChannelDatabase.addAdminToChannel(channelId, targetUserId, permissions);
|
boolean success = ChannelDatabase.addAdminToChannel(channelId, targetUserId, permissions);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
Channel channel = ChannelDatabase.findByInternalUUID(channelId);
|
||||||
|
if (channel != null) {
|
||||||
|
RealTimeEventDispatcher.notifyBecameAdmin(
|
||||||
|
"channel",
|
||||||
|
channel.getInternal_uuid(),
|
||||||
|
channel.getChannel_name(),
|
||||||
|
channel.getImage_url(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Admin added to channel.")
|
? new ResponseModel("success", "Admin added to channel.")
|
||||||
: new ResponseModel("error", "Failed to add admin.");
|
: new ResponseModel("error", "Failed to add admin.");
|
||||||
@@ -673,9 +724,11 @@ public class ClientHandler implements Runnable {
|
|||||||
? new ResponseModel("success", "Group info updated successfully.")
|
? new ResponseModel("success", "Group info updated successfully.")
|
||||||
: new ResponseModel("error", "Failed to update group info.");
|
: new ResponseModel("error", "Failed to update group info.");
|
||||||
|
|
||||||
//if (updated) {
|
//RealTime
|
||||||
//RealTimeEventDispatcher.sendGroupOrChannelUpdate(groupUUID, "group", name);
|
if (updated) {
|
||||||
//}
|
List<UUID> members = GroupDatabase.getMemberUUIDs(groupUUID);
|
||||||
|
RealTimeEventDispatcher.sendGroupOrChannelUpdate("group", groupUUID, name, imageUrl, description, members);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
response = new ResponseModel("error", "Error updating group: " + e.getMessage());
|
response = new ResponseModel("error", "Error updating group: " + e.getMessage());
|
||||||
@@ -689,10 +742,6 @@ public class ClientHandler implements Runnable {
|
|||||||
case "view_channel_admins": {
|
case "view_channel_admins": {
|
||||||
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
||||||
|
|
||||||
//if (!ChannelPermissionUtil.canAddAdmins(channelId, currentUser.getInternal_uuid())) {
|
|
||||||
// response = new ResponseModel("error", "You are not allowed to add admins to the channel.");
|
|
||||||
//break;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
List<JSONObject> admins = ChannelDatabase.getChannelAdminsAndOwner(channelId);
|
List<JSONObject> admins = ChannelDatabase.getChannelAdminsAndOwner(channelId);
|
||||||
@@ -716,6 +765,20 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
boolean success = GroupDatabase.addAdminToGroup(groupId, targetUserId, permissions);
|
boolean success = GroupDatabase.addAdminToGroup(groupId, targetUserId, permissions);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
Group group = GroupDatabase.findByInternalUUID(groupId);
|
||||||
|
if (group != null) {
|
||||||
|
RealTimeEventDispatcher.notifyBecameAdmin(
|
||||||
|
"group",
|
||||||
|
group.getInternal_uuid(),
|
||||||
|
group.getGroup_name(),
|
||||||
|
group.getImage_url(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Admin added to group.")
|
? new ResponseModel("success", "Admin added to group.")
|
||||||
: new ResponseModel("error", "Failed to add admin.");
|
: new ResponseModel("error", "Failed to add admin.");
|
||||||
@@ -764,6 +827,21 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean success = ChannelDatabase.demoteAdminToSubscriber(channelId, targetUserUUID);
|
boolean success = ChannelDatabase.demoteAdminToSubscriber(channelId, targetUserUUID);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
Channel channel = ChannelDatabase.findByInternalUUID(channelId);
|
||||||
|
if (channel != null) {
|
||||||
|
RealTimeEventDispatcher.notifyRemovedAdminFromChat(
|
||||||
|
"channel",
|
||||||
|
channel.getInternal_uuid(),
|
||||||
|
channel.getChannel_name(),
|
||||||
|
channel.getImage_url(),
|
||||||
|
targetUserUUID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Admin removed successfully.")
|
? new ResponseModel("success", "Admin removed successfully.")
|
||||||
: new ResponseModel("error", "Failed to remove admin.");
|
: new ResponseModel("error", "Failed to remove admin.");
|
||||||
@@ -786,10 +864,25 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean success = GroupDatabase.addMemberToGroup(targetUserId, groupId);
|
boolean success = GroupDatabase.addMemberToGroup(targetUserId, groupId);
|
||||||
|
|
||||||
|
Group group = GroupDatabase.findByInternalUUID(groupId);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success && group != null) {
|
||||||
|
RealTimeEventDispatcher.notifyAddedToChat(
|
||||||
|
"group",
|
||||||
|
group.getInternal_uuid(),
|
||||||
|
group.getGroup_name(),
|
||||||
|
group.getImage_url(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Member added to group.")
|
? new ResponseModel("success", "Member added to group.")
|
||||||
: new ResponseModel("error", "Failed to add member.");
|
: new ResponseModel("error", "Failed to add member.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -813,7 +906,18 @@ public class ClientHandler implements Runnable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//RealTime
|
||||||
boolean success = GroupDatabase.removeMemberFromGroup(groupId, targetUserId);
|
boolean success = GroupDatabase.removeMemberFromGroup(groupId, targetUserId);
|
||||||
|
if (success) {
|
||||||
|
Group group = GroupDatabase.findByInternalUUID(groupId);
|
||||||
|
if (group != null) {
|
||||||
|
RealTimeEventDispatcher.notifyRemovedFromChat(
|
||||||
|
"group",
|
||||||
|
group.getInternal_uuid(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Member removed from group.")
|
? new ResponseModel("success", "Member removed from group.")
|
||||||
: new ResponseModel("error", "Failed to remove member.");
|
: new ResponseModel("error", "Failed to remove member.");
|
||||||
@@ -911,6 +1015,14 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
boolean isBlocked = ContactDatabase.toggleBlock(userUUID, targetUUID);
|
boolean isBlocked = ContactDatabase.toggleBlock(userUUID, targetUUID);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (isBlocked) {
|
||||||
|
RealTimeEventDispatcher.notifyBlocked(userUUID, targetUUID);
|
||||||
|
} else {
|
||||||
|
RealTimeEventDispatcher.notifyUnblocked(userUUID, targetUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String message = isBlocked ? "🔒 User blocked successfully." : "🔓 User unblocked successfully.";
|
String message = isBlocked ? "🔒 User blocked successfully." : "🔓 User unblocked successfully.";
|
||||||
response = new ResponseModel("success", message);
|
response = new ResponseModel("success", message);
|
||||||
|
|
||||||
@@ -944,6 +1056,13 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
boolean success = GroupDatabase.transferOwnership(groupId, newOwner.getInternal_uuid());
|
boolean success = GroupDatabase.transferOwnership(groupId, newOwner.getInternal_uuid());
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
List<UUID> members = GroupDatabase.getMemberUUIDs(groupId);
|
||||||
|
RealTimeEventDispatcher.sendGroupOrChannelUpdate("group", groupId, groupId.toString(), "", "", members);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Ownership transferred.")
|
? new ResponseModel("success", "Ownership transferred.")
|
||||||
: new ResponseModel("error", "Failed to transfer ownership.");
|
: new ResponseModel("error", "Failed to transfer ownership.");
|
||||||
@@ -972,6 +1091,14 @@ public class ClientHandler implements Runnable {
|
|||||||
case "delete_private_chat" : {
|
case "delete_private_chat" : {
|
||||||
UUID targetId = UUID.fromString(requestJson.getString("target_id"));
|
UUID targetId = UUID.fromString(requestJson.getString("target_id"));
|
||||||
boolean both = requestJson.getBoolean("both");
|
boolean both = requestJson.getBoolean("both");
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (both) {
|
||||||
|
RealTimeEventDispatcher.notifyChatDeleted("private", targetId, List.of(currentUser.getInternal_uuid()));
|
||||||
|
RealTimeEventDispatcher.notifyChatDeleted("private", currentUser.getInternal_uuid(), List.of(targetId));
|
||||||
|
} else {
|
||||||
|
RealTimeEventDispatcher.notifyChatDeleted("private", targetId, List.of(currentUser.getInternal_uuid()));
|
||||||
|
}
|
||||||
response = PrivateChatService.deletePrivateChat(currentUser.getInternal_uuid(), targetId, both);
|
response = PrivateChatService.deletePrivateChat(currentUser.getInternal_uuid(), targetId, both);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -995,6 +1122,9 @@ public class ClientHandler implements Runnable {
|
|||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (chatType) {
|
switch (chatType) {
|
||||||
case "group" -> success = GroupDatabase.removeMemberFromGroup(chatId, userId);
|
case "group" -> success = GroupDatabase.removeMemberFromGroup(chatId, userId);
|
||||||
case "channel" -> success = ChannelDatabase.removeSubscriberFromChannel(chatId, userId);
|
case "channel" -> success = ChannelDatabase.removeSubscriberFromChannel(chatId, userId);
|
||||||
@@ -1004,6 +1134,15 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
if (chatType.equals("group")) {
|
||||||
|
RealTimeEventDispatcher.notifyRemovedFromChat("group", chatId, userId);
|
||||||
|
} else if (chatType.equals("channel")) {
|
||||||
|
RealTimeEventDispatcher.notifyRemovedFromChat("channel", chatId, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Left the " + chatType + " successfully.")
|
? new ResponseModel("success", "Left the " + chatType + " successfully.")
|
||||||
@@ -1022,11 +1161,17 @@ public class ClientHandler implements Runnable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<UUID> memberIds = GroupDatabase.getGroupMemberUUIDs(groupId);
|
||||||
|
|
||||||
boolean success = GroupDatabase.deleteGroup(groupId);
|
boolean success = GroupDatabase.deleteGroup(groupId);
|
||||||
|
|
||||||
response = success
|
//RealTime
|
||||||
? new ResponseModel("success", "Group deleted successfully.")
|
if (success) {
|
||||||
: new ResponseModel("error", "Failed to delete group.");
|
RealTimeEventDispatcher.notifyChatDeleted("group", groupId, memberIds);
|
||||||
|
response = new ResponseModel("success", "Group deleted successfully.");
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Failed to delete group.");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1085,6 +1230,20 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean success = ChannelDatabase.addSubscriberToChannel(targetUserId, channelId);
|
boolean success = ChannelDatabase.addSubscriberToChannel(targetUserId, channelId);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
Channel channel = ChannelDatabase.findByInternalUUID(channelId);
|
||||||
|
if (channel != null) {
|
||||||
|
RealTimeEventDispatcher.notifyAddedToChat(
|
||||||
|
"channel",
|
||||||
|
channel.getInternal_uuid(),
|
||||||
|
channel.getChannel_name(),
|
||||||
|
channel.getImage_url(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Subscriber added to channel.")
|
? new ResponseModel("success", "Subscriber added to channel.")
|
||||||
: new ResponseModel("error", "Failed to add subscriber.");
|
: new ResponseModel("error", "Failed to add subscriber.");
|
||||||
@@ -1112,6 +1271,18 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean success = ChannelDatabase.removeSubscriberFromChannel(channelId, targetUserId);
|
boolean success = ChannelDatabase.removeSubscriberFromChannel(channelId, targetUserId);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
Channel channel = ChannelDatabase.findByInternalUUID(channelId);
|
||||||
|
if (channel != null) {
|
||||||
|
RealTimeEventDispatcher.notifyRemovedFromChat(
|
||||||
|
"channel",
|
||||||
|
channel.getInternal_uuid(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
response = success
|
response = success
|
||||||
? new ResponseModel("success", "Subscriber removed from channel.")
|
? new ResponseModel("success", "Subscriber removed from channel.")
|
||||||
: new ResponseModel("error", "Failed to remove subscriber.");
|
: new ResponseModel("error", "Failed to remove subscriber.");
|
||||||
@@ -1140,6 +1311,13 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean updated = ChannelDatabase.updateChannelInfo(channelUUID, newChannelId, name, description, imageUrl);
|
boolean updated = ChannelDatabase.updateChannelInfo(channelUUID, newChannelId, name, description, imageUrl);
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (updated) {
|
||||||
|
List<UUID> subscribers = ChannelDatabase.getChannelSubscriberUUIDs(channelUUID);
|
||||||
|
RealTimeEventDispatcher.sendGroupOrChannelUpdate("channel", channelUUID, name, imageUrl, description, subscribers);
|
||||||
|
}
|
||||||
|
|
||||||
response = updated
|
response = updated
|
||||||
? new ResponseModel("success", "Channel info updated successfully.")
|
? new ResponseModel("success", "Channel info updated successfully.")
|
||||||
: new ResponseModel("error", "Failed to update channel info.");
|
: new ResponseModel("error", "Failed to update channel info.");
|
||||||
@@ -1159,14 +1337,70 @@ public class ClientHandler implements Runnable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<UUID> subscriberIds = ChannelDatabase.getChannelSubscriberUUIDs(channelId);
|
||||||
|
|
||||||
boolean success = ChannelDatabase.deleteChannel(channelId);
|
boolean success = ChannelDatabase.deleteChannel(channelId);
|
||||||
response = success
|
|
||||||
? new ResponseModel("success", "Channel deleted successfully.")
|
//RealTime
|
||||||
: new ResponseModel("error", "Failed to delete channel.");
|
if (success) {
|
||||||
|
RealTimeEventDispatcher.notifyChatDeleted("channel", channelId, subscriberIds);
|
||||||
|
response = new ResponseModel("success", "Channel deleted successfully.");
|
||||||
|
} else {
|
||||||
|
response = new ResponseModel("error", "Failed to delete channel.");
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "remove_admin_from_group": {
|
||||||
|
UUID groupId = UUID.fromString(requestJson.getString("group_id"));
|
||||||
|
UUID targetUserId = UUID.fromString(requestJson.getString("target_user_id"));
|
||||||
|
|
||||||
|
if (!GroupPermissionUtil.canRemoveAdmins(groupId, currentUser.getInternal_uuid())) {
|
||||||
|
response = new ResponseModel("error", "You are not allowed to remove admins.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String targetRole = GroupDatabase.getGroupRole(groupId, targetUserId);
|
||||||
|
if (targetRole == null) {
|
||||||
|
response = new ResponseModel("error", "User is not a member of the group.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetRole.equals("owner")) {
|
||||||
|
response = new ResponseModel("error", "You cannot remove the owner.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetRole.equals("admin")) {
|
||||||
|
response = new ResponseModel("error", "Target user is not an admin.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = GroupDatabase.demoteAdminToMember(groupId, targetUserId);
|
||||||
|
|
||||||
|
// RealTime
|
||||||
|
if (success) {
|
||||||
|
Group group = GroupDatabase.findByInternalUUID(groupId);
|
||||||
|
if (group != null) {
|
||||||
|
RealTimeEventDispatcher.notifyRemovedAdminFromChat(
|
||||||
|
"group",
|
||||||
|
group.getInternal_uuid(),
|
||||||
|
group.getGroup_name(),
|
||||||
|
group.getImage_url(),
|
||||||
|
targetUserId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = success
|
||||||
|
? new ResponseModel("success", "Admin removed successfully.")
|
||||||
|
: new ResponseModel("error", "Failed to remove admin.");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case "transfer_channel_ownership": {
|
case "transfer_channel_ownership": {
|
||||||
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
UUID channelId = UUID.fromString(requestJson.getString("channel_id"));
|
||||||
String newOwnerUserIdStr = requestJson.getString("new_owner_user_id");
|
String newOwnerUserIdStr = requestJson.getString("new_owner_user_id");
|
||||||
@@ -1183,7 +1417,15 @@ public class ClientHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean success = ChannelDatabase.transferOwnership(channelId, newOwner.getInternal_uuid());
|
boolean success = ChannelDatabase.transferOwnership(channelId, newOwner.getInternal_uuid());
|
||||||
|
|
||||||
|
//RealTime
|
||||||
|
if (success) {
|
||||||
|
List<UUID> subscribers = ChannelDatabase.getChannelSubscriberUUIDs(channelId);
|
||||||
|
RealTimeEventDispatcher.sendGroupOrChannelUpdate("channel", channelId, channelId.toString(), "", "", subscribers);
|
||||||
|
}
|
||||||
|
|
||||||
response = success
|
response = success
|
||||||
|
|
||||||
? new ResponseModel("success", "Ownership transferred successfully.")
|
? new ResponseModel("success", "Ownership transferred successfully.")
|
||||||
: new ResponseModel("error", "Failed to transfer ownership.");
|
: new ResponseModel("error", "Failed to transfer ownership.");
|
||||||
break;
|
break;
|
||||||
@@ -1212,12 +1454,17 @@ public class ClientHandler implements Runnable {
|
|||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (currentUser != null) {
|
if (currentUser != null) {
|
||||||
|
//RealTime
|
||||||
userId = currentUser.getInternal_uuid();
|
userId = currentUser.getInternal_uuid();
|
||||||
|
List<UUID> contacts = ContactDatabase.getContactUUIDs(userId);
|
||||||
|
RealTimeEventDispatcher.notifyUserStatusChanged(userId, "offline", contacts);
|
||||||
|
|
||||||
System.out.println("🔚 Client disconnected. Cleaning up user " + userId);
|
System.out.println("🔚 Client disconnected. Cleaning up user " + userId);
|
||||||
userDatabase.updateUserStatus(userId, "offline");
|
userDatabase.updateUserStatus(userId, "offline");
|
||||||
userDatabase.updateLastSeen(userId);
|
userDatabase.updateLastSeen(userId);
|
||||||
SessionManager.removeUser(userId);
|
SessionManager.removeUser(userId);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
System.out.println("❗ currentUser is null, couldn't set offline.");
|
System.out.println("❗ currentUser is null, couldn't set offline.");
|
||||||
}
|
}
|
||||||
socket.close();
|
socket.close();
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ public class RealTimeEventDispatcher {
|
|||||||
|
|
||||||
public static void notifyAddedToChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
public static void notifyAddedToChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
data.put("chat_type", type); // group یا channel
|
data.put("chat_type", type);
|
||||||
data.put("chat_id", chatId.toString());
|
data.put("chat_id", chatId.toString());
|
||||||
data.put("chat_name", chatName);
|
data.put("chat_name", chatName);
|
||||||
data.put("image_url", imageUrl);
|
data.put("image_url", imageUrl);
|
||||||
@@ -246,5 +246,49 @@ public class RealTimeEventDispatcher {
|
|||||||
broadcastToUsers(contacts, event);
|
broadcastToUsers(contacts, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendGroupOrChannelUpdate(String type, UUID chatId, String name, String imageUrl, String description, List<UUID> affectedUsers) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("chat_type", type);
|
||||||
|
data.put("chat_id", chatId.toString());
|
||||||
|
data.put("name", name);
|
||||||
|
data.put("image_url", imageUrl);
|
||||||
|
data.put("description", description != null ? description : "");
|
||||||
|
|
||||||
|
JSONObject event = new JSONObject();
|
||||||
|
event.put("action", "chat_updated");
|
||||||
|
event.put("data", data);
|
||||||
|
|
||||||
|
broadcastToUsers(affectedUsers, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void notifyBecameAdmin(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", "became_admin");
|
||||||
|
event.put("data", data);
|
||||||
|
|
||||||
|
sendToUser(userId, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void notifyRemovedAdminFromChat(String type, UUID chatId, String chatName, String imageUrl, UUID userId) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
data.put("chat_type", type);
|
||||||
|
data.put("chat_id", chatId.toString());
|
||||||
|
data.put("chat_name", chatName);
|
||||||
|
data.put("image_url", imageUrl);
|
||||||
|
|
||||||
|
JSONObject event = new JSONObject();
|
||||||
|
event.put("action", "removed_admin");
|
||||||
|
event.put("data", data);
|
||||||
|
|
||||||
|
sendToUser(userId, event);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class LoginForm {
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
connection = new ClientConnection("localhost", 12345);
|
connection = new ClientConnection("localhost", 8000);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Could not connect to server: " + e.getMessage());
|
System.out.println("Could not connect to server: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user