Handle message interact in UI with RealTime
This commit is contained in:
@@ -89,16 +89,24 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
|
|
||||||
private boolean isRealTimeEvent(String action) {
|
private boolean isRealTimeEvent(String action) {
|
||||||
return switch (action) {
|
return switch (action) {
|
||||||
case "new_message", "message_edited", "message_deleted_global",
|
case "new_message",
|
||||||
"user_status_changed", "added_to_group", "added_to_channel",
|
"message_edited",
|
||||||
|
"message_deleted_global", "message_deleted_one_sided", "message_deleted",
|
||||||
|
"message_reacted", "message_unreacted",
|
||||||
|
"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",
|
"blocked_by_user", "unblocked_by_user", "message_seen",
|
||||||
"removed_from_group", "removed_from_channel",
|
"removed_from_group", "removed_from_channel",
|
||||||
"became_admin", "removed_admin", "ownership_transferred","admin_permissions_updated","created_private_chat" , "message_reacted" , "message_unreacted","chat_updated" -> true;
|
"became_admin", "removed_admin", "ownership_transferred",
|
||||||
|
"admin_permissions_updated",
|
||||||
|
"created_private_chat",
|
||||||
|
"chat_updated" -> true;
|
||||||
default -> false;
|
default -> false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void handleRealTimeEvent(JSONObject response) throws IOException {
|
void handleRealTimeEvent(JSONObject response) throws IOException {
|
||||||
String action = response.getString("action");
|
String action = response.getString("action");
|
||||||
JSONObject msg = response.has("data") ? response.getJSONObject("data") : new JSONObject();
|
JSONObject msg = response.has("data") ? response.getJSONObject("data") : new JSONObject();
|
||||||
@@ -166,6 +174,35 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "message_edited" -> {
|
||||||
|
JSONObject ui = normalizeMessageId(msg);
|
||||||
|
// (اختیاری) اگر ایونت زمان و چت را هم میدهد، میتوانی چتلیست را آپدیت کنی
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
var mc = MainController.getInstance();
|
||||||
|
var chatCtl = (mc != null) ? mc.getChatPageController() : null;
|
||||||
|
if (chatCtl != null) chatCtl.onRealTimeMessageEdited(ui);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
case "message_deleted_global", "message_deleted_one_sided", "message_deleted" -> {
|
||||||
|
JSONObject ui = normalizeMessageId(msg);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
var mc = MainController.getInstance();
|
||||||
|
var chatCtl = (mc != null) ? mc.getChatPageController() : null;
|
||||||
|
if (chatCtl != null) chatCtl.onRealTimeMessageDeleted(ui);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
case "message_reacted", "message_unreacted" -> {
|
||||||
|
JSONObject ui = normalizeMessageId(msg);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
var mc = MainController.getInstance();
|
||||||
|
var chatCtl = (mc != null) ? mc.getChatPageController() : null;
|
||||||
|
if (chatCtl != null) chatCtl.onRealTimeReaction(ui);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case "chat_updated" -> {
|
case "chat_updated" -> {
|
||||||
var data = response.getJSONObject("data");
|
var data = response.getJSONObject("data");
|
||||||
@@ -189,8 +226,7 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
case "message_edited", "message_deleted_global", "message_reacted", "message_unreacted"
|
case "blocked_by_user", "unblocked_by_user", "message_seen" -> {
|
||||||
, "blocked_by_user", "unblocked_by_user", "message_seen" -> {
|
|
||||||
displayRealTimeMessage(action, msg);
|
displayRealTimeMessage(action, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,4 +514,16 @@ public class IncomingMessageListener implements Runnable {
|
|||||||
} catch (Exception e) { System.err.println("[RT] bumpChatListFromMessage: " + e.getMessage()); }
|
} catch (Exception e) { System.err.println("[RT] bumpChatListFromMessage: " + e.getMessage()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- add this helper ---
|
||||||
|
private static JSONObject normalizeMessageId(JSONObject j) {
|
||||||
|
if (j == null) return new JSONObject();
|
||||||
|
if (!j.has("message_id") && j.has("id")) {
|
||||||
|
JSONObject copy = new JSONObject(j.toString());
|
||||||
|
copy.put("message_id", copy.optString("id", ""));
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2474,8 +2474,8 @@ public class ClientHandler implements Runnable {
|
|||||||
.put("excerpt", excerpt));
|
.put("excerpt", excerpt));
|
||||||
|
|
||||||
List<UUID> receivers = Receivers.resolveFor(receiverType, receiverId, senderId);
|
List<UUID> receivers = Receivers.resolveFor(receiverType, receiverId, senderId);
|
||||||
//RealTimeEventDispatcher.sendNewMessage(message, receivers, "reply", meta);
|
receivers = Receivers.resolveFor(receiverType, receiverId, /*exclude*/ null);
|
||||||
RealTimeEventDispatcher.sendNewMessageFiltered(message, receivers, senderId, "reply", meta);
|
RealTimeEventDispatcher.sendNewMessage(message, receivers, "reply", meta);
|
||||||
|
|
||||||
|
|
||||||
response = saved ?
|
response = saved ?
|
||||||
@@ -2532,12 +2532,8 @@ public class ClientHandler implements Runnable {
|
|||||||
.put("sender_id", original.getSender_id().toString())
|
.put("sender_id", original.getSender_id().toString())
|
||||||
.put("sender_name", userDatabase.findByInternalUUID(original.getSender_id()).getProfile_name()));
|
.put("sender_name", userDatabase.findByInternalUUID(original.getSender_id()).getProfile_name()));
|
||||||
|
|
||||||
List<UUID> receivers = Receivers.resolveFor(targetChatType, targetChatId, currentUser.getInternal_uuid());
|
List<UUID> receivers = Receivers.resolveFor(targetChatType, targetChatId, /*exclude*/ null);
|
||||||
//RealTimeEventDispatcher.sendNewMessage(forwarded, receivers, "forward", meta);
|
RealTimeEventDispatcher.sendNewMessage(forwarded, receivers, "forward", meta);
|
||||||
RealTimeEventDispatcher.sendNewMessageFiltered(forwarded, receivers, senderId, "forward", meta);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
response = new ResponseModel("error", "Failed to forward message.");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
|||||||
|
/* رنگها */
|
||||||
|
:root {
|
||||||
|
-tg-bg: #ffffff;
|
||||||
|
-tg-sheet: #ffffff;
|
||||||
|
-tg-shadow: rgba(0,0,0,.25);
|
||||||
|
-tg-sep: rgba(0,0,0,.06);
|
||||||
|
-tg-text: #0f141a;
|
||||||
|
-tg-subtext: #6e7b87;
|
||||||
|
-tg-danger: #e53935;
|
||||||
|
-tg-primary: #2481cc;
|
||||||
|
-tg-chip-bg: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ACTION SHEET */
|
||||||
|
.tg-action-sheet {
|
||||||
|
-fx-background-color: -tg-sheet;
|
||||||
|
-fx-background-radius: 16;
|
||||||
|
-fx-effect: dropshadow(gaussian, -tg-shadow, 24, 0.26, 0, 4);
|
||||||
|
-fx-padding: 0;
|
||||||
|
-fx-border-radius: 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-reaction-bar {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-spacing: 12;
|
||||||
|
}
|
||||||
|
.tg-reaction {
|
||||||
|
-fx-font-size: 22px;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
-fx-padding: 2 4 2 4;
|
||||||
|
-fx-background-radius: 12;
|
||||||
|
}
|
||||||
|
.tg-reaction:hover {
|
||||||
|
-fx-background-color: -tg-chip-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-menu { -fx-background-color: transparent; }
|
||||||
|
|
||||||
|
.tg-item {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-background-radius: 12;
|
||||||
|
}
|
||||||
|
.tg-item:hover {
|
||||||
|
-fx-background-color: -tg-chip-bg;
|
||||||
|
}
|
||||||
|
.tg-item .tg-label {
|
||||||
|
-fx-text-fill: -tg-text;
|
||||||
|
-fx-font-size: 16px;
|
||||||
|
}
|
||||||
|
.tg-item.danger .tg-label {
|
||||||
|
-fx-text-fill: -tg-danger;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-sep {
|
||||||
|
-fx-background-color: -tg-sep;
|
||||||
|
-fx-min-height: 1px;
|
||||||
|
-fx-pref-height: 1px;
|
||||||
|
-fx-max-height: 1px;
|
||||||
|
-fx-background-insets: 0 14 0 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DELETE SHEET */
|
||||||
|
.tg-delete-sheet {
|
||||||
|
-fx-background-color: -tg-bg;
|
||||||
|
-fx-background-radius: 16;
|
||||||
|
-fx-effect: dropshadow(gaussian, -tg-shadow, 28, 0.28, 0, 4);
|
||||||
|
}
|
||||||
|
.tg-delete-title {
|
||||||
|
-fx-font-size: 18px;
|
||||||
|
-fx-text-fill: -tg-text;
|
||||||
|
}
|
||||||
|
.tg-delete-check {
|
||||||
|
-fx-text-fill: -tg-text;
|
||||||
|
-fx-font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.tg-btn-secondary {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-text-fill: -tg-primary;
|
||||||
|
-fx-font-size: 14px;
|
||||||
|
-fx-padding: 8 14 8 14;
|
||||||
|
-fx-background-radius: 10;
|
||||||
|
}
|
||||||
|
.tg-btn-secondary:hover {
|
||||||
|
-fx-background-color: -tg-chip-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tg-btn-danger {
|
||||||
|
-fx-background-color: -tg-danger;
|
||||||
|
-fx-text-fill: white;
|
||||||
|
-fx-font-size: 14px;
|
||||||
|
-fx-padding: 8 16 8 16;
|
||||||
|
-fx-background-radius: 10;
|
||||||
|
}
|
||||||
|
.tg-btn-danger:hover { -fx-opacity: .9; }
|
||||||
|
|
||||||
|
/* دارکمود (اگر CSS سوییچ داری، این کلس را به Scene اضافه کن) */
|
||||||
|
.root.dark .tg-action-sheet,
|
||||||
|
.root.dark .tg-delete-sheet { -fx-background-color: #1f2a33; }
|
||||||
|
.root.dark {
|
||||||
|
-tg-bg: #1f2a33;
|
||||||
|
-tg-sheet: #22303a;
|
||||||
|
-tg-text: #e8f1f8;
|
||||||
|
-tg-subtext: #9bb2c3;
|
||||||
|
-tg-sep: rgba(255,255,255,.08);
|
||||||
|
-tg-chip-bg: rgba(255,255,255,.06);
|
||||||
|
-tg-shadow: rgba(0,0,0,.45);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user