Block backend connected to UI.
This commit is contained in:
@@ -14,7 +14,7 @@ public final class AvatarFX {
|
|||||||
|
|
||||||
Circle c = new Circle();
|
Circle c = new Circle();
|
||||||
c.radiusProperty().bind(Bindings.min(iv.fitWidthProperty(), iv.fitHeightProperty()).divide(2));
|
c.radiusProperty().bind(Bindings.min(iv.fitWidthProperty(), iv.fitHeightProperty()).divide(2));
|
||||||
c.centerXProperty().bind(iv.fitWidthProperty().divide(2));
|
c.centerXProperty().bind(iv.fitWidthProperty().divide(3));
|
||||||
c.centerYProperty().bind(iv.fitHeightProperty().divide(2));
|
c.centerYProperty().bind(iv.fitHeightProperty().divide(2));
|
||||||
iv.setClip(c);
|
iv.setClip(c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -842,7 +842,7 @@ public class ChatPageController {
|
|||||||
} else {
|
} else {
|
||||||
setDefaultHeaderAvatarByType(entry.getType());
|
setDefaultHeaderAvatarByType(entry.getType());
|
||||||
}
|
}
|
||||||
AvatarFX.circleClip(userAvatar, 36);
|
AvatarFX.circleClip(userAvatar, 40);
|
||||||
|
|
||||||
|
|
||||||
// حالت اولیه (بدون انتظار هدر)
|
// حالت اولیه (بدون انتظار هدر)
|
||||||
@@ -863,11 +863,13 @@ public class ChatPageController {
|
|||||||
|
|
||||||
// === (3-dot menu + header click) ===
|
// === (3-dot menu + header click) ===
|
||||||
configureHeaderActions(entry);
|
configureHeaderActions(entry);
|
||||||
|
|
||||||
|
requestBlockStatusByChat(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void requestBlockStatusByChat(ChatEntry entry) {
|
public void requestBlockStatusByChat(ChatEntry entry) {
|
||||||
if (entry == null || !"private".equalsIgnoreCase(entry.getType())) return;
|
if (entry == null || !"private".equalsIgnoreCase(entry.getType())) return;
|
||||||
|
|
||||||
String viewerId = Session.getUserUUID(); // internal_uuid کاربر فعلی
|
String viewerId = Session.getUserUUID(); // internal_uuid کاربر فعلی
|
||||||
@@ -890,7 +892,7 @@ public class ChatPageController {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyBlockUi(boolean blockedByMe, boolean blockedMe) {
|
public void applyBlockUi(boolean blockedByMe, boolean blockedMe) {
|
||||||
this.blockedByMeFlag = blockedByMe;
|
this.blockedByMeFlag = blockedByMe;
|
||||||
this.blockedMeFlag = blockedMe;
|
this.blockedMeFlag = blockedMe;
|
||||||
|
|
||||||
@@ -945,6 +947,8 @@ public class ChatPageController {
|
|||||||
|
|
||||||
// Wire up menu + header click
|
// Wire up menu + header click
|
||||||
configureHeaderActions(entry);
|
configureHeaderActions(entry);
|
||||||
|
|
||||||
|
requestBlockStatusByChat(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureHeaderActions(ChatEntry entry) {
|
private void configureHeaderActions(ChatEntry entry) {
|
||||||
@@ -983,6 +987,7 @@ public class ChatPageController {
|
|||||||
|
|
||||||
private void openInfoScene(ChatEntry entry) {
|
private void openInfoScene(ChatEntry entry) {
|
||||||
JSONObject req = new JSONObject();
|
JSONObject req = new JSONObject();
|
||||||
|
String targetId = null; // 👈 capture it here for the private case
|
||||||
|
|
||||||
switch (entry.getType().toLowerCase()) {
|
switch (entry.getType().toLowerCase()) {
|
||||||
case "private" -> {
|
case "private" -> {
|
||||||
@@ -1003,7 +1008,7 @@ public class ChatPageController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String targetId = targetResp.optJSONObject("data").optString("target_id", null);
|
targetId = targetResp.optJSONObject("data").optString("target_id", null);
|
||||||
if (targetId == null || targetId.isBlank()) {
|
if (targetId == null || targetId.isBlank()) {
|
||||||
Platform.runLater(() ->
|
Platform.runLater(() ->
|
||||||
MainController.getInstance().showAlert(
|
MainController.getInstance().showAlert(
|
||||||
@@ -1038,6 +1043,8 @@ public class ChatPageController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String finalTargetId = targetId; // 👈 capture for use in the FX thread
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
JSONObject resp = ActionHandler.sendWithResponse(req);
|
JSONObject resp = ActionHandler.sendWithResponse(req);
|
||||||
if (resp == null || !"success".equalsIgnoreCase(resp.optString("status"))) {
|
if (resp == null || !"success".equalsIgnoreCase(resp.optString("status"))) {
|
||||||
@@ -1074,7 +1081,8 @@ public class ChatPageController {
|
|||||||
"/org/to/telegramfinalproject/Fxml/user_info.fxml"));
|
"/org/to/telegramfinalproject/Fxml/user_info.fxml"));
|
||||||
overlay = loader.load();
|
overlay = loader.load();
|
||||||
UserInfoController c = loader.getController();
|
UserInfoController c = loader.getController();
|
||||||
c.setProfileDataFromJson(entry, data);
|
// 👇 pass targetId so UserInfoController gets the real UUID
|
||||||
|
c.setProfileDataFromJson(entry, data, finalTargetId);
|
||||||
}
|
}
|
||||||
case "group" -> {
|
case "group" -> {
|
||||||
loader = new FXMLLoader(getClass().getResource(
|
loader = new FXMLLoader(getClass().getResource(
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class UserInfoController {
|
|||||||
@FXML private ImageView usernameIcon;
|
@FXML private ImageView usernameIcon;
|
||||||
|
|
||||||
private String otherUserId; // internal_uuid of the other user
|
private String otherUserId; // internal_uuid of the other user
|
||||||
|
private ChatEntry entry;
|
||||||
|
|
||||||
private static final String ICON_PATH = "/org/to/telegramfinalproject/Icons/";
|
private static final String ICON_PATH = "/org/to/telegramfinalproject/Icons/";
|
||||||
|
|
||||||
@@ -73,8 +74,8 @@ public class UserInfoController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
deleteChatItem.setOnAction(e -> handleDeleteChat());
|
deleteChatItem.setOnAction(e -> handleDeleteChat());
|
||||||
blockItem.setOnAction(e -> handleBlock());
|
blockItem.setOnAction(e -> handleToggleBlock(entry));
|
||||||
unblockItem.setOnAction(e -> handleUnblock());
|
unblockItem.setOnAction(e -> handleToggleBlock(entry));
|
||||||
|
|
||||||
// Register scene for ThemeManager → stylesheet swap will handle colors/icons
|
// Register scene for ThemeManager → stylesheet swap will handle colors/icons
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
@@ -93,7 +94,11 @@ public class UserInfoController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Backend JSON → UI */
|
/** Backend JSON → UI */
|
||||||
public void setProfileDataFromJson(ChatEntry entry, JSONObject data) {
|
public void setProfileDataFromJson(ChatEntry entry, JSONObject data, String targetUuid) {
|
||||||
|
// save the correct UUID
|
||||||
|
this.otherUserId = targetUuid;
|
||||||
|
this.entry = entry;
|
||||||
|
|
||||||
// --- Profile name ---
|
// --- Profile name ---
|
||||||
String name = data.optString("profile_name", entry.getName());
|
String name = data.optString("profile_name", entry.getName());
|
||||||
profileName.setText(name);
|
profileName.setText(name);
|
||||||
@@ -141,9 +146,6 @@ public class UserInfoController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Other user ID (needed for block/delete) ---
|
|
||||||
this.otherUserId = data.optString("other_user_id", entry.getId().toString());
|
|
||||||
|
|
||||||
// --- Block/Unblock ---
|
// --- Block/Unblock ---
|
||||||
boolean blocked = data.optBoolean("blocked", false)
|
boolean blocked = data.optBoolean("blocked", false)
|
||||||
|| data.optBoolean("is_blocked", false)
|
|| data.optBoolean("is_blocked", false)
|
||||||
@@ -163,28 +165,55 @@ public class UserInfoController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleBlock() {
|
private void handleToggleBlock(ChatEntry entry) {
|
||||||
|
if (otherUserId == null) return;
|
||||||
|
|
||||||
|
// 1) Send toggle request
|
||||||
JSONObject req = new JSONObject()
|
JSONObject req = new JSONObject()
|
||||||
.put("action", "block_user")
|
.put("action", "toggle_block")
|
||||||
.put("target_id", otherUserId)
|
.put("user_id", Session.getUserUUID())
|
||||||
.put("viewer_id", Session.getUserUUID());
|
.put("target_id", otherUserId);
|
||||||
|
|
||||||
JSONObject resp = ActionHandler.sendWithResponse(req);
|
JSONObject resp = ActionHandler.sendWithResponse(req);
|
||||||
if (resp != null && "success".equalsIgnoreCase(resp.optString("status"))) {
|
if (resp == null) {
|
||||||
updateBlockMenu(true);
|
MainController.getInstance().showAlert("Error", "No response from server.", Alert.AlertType.ERROR);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void handleUnblock() {
|
if (!"success".equalsIgnoreCase(resp.optString("status"))) {
|
||||||
JSONObject req = new JSONObject()
|
MainController.getInstance().showAlert("Error",
|
||||||
.put("action", "unblock_user")
|
resp.optString("message", "Failed to toggle block"),
|
||||||
.put("target_id", otherUserId)
|
Alert.AlertType.ERROR);
|
||||||
.put("viewer_id", Session.getUserUUID());
|
return;
|
||||||
|
|
||||||
JSONObject resp = ActionHandler.sendWithResponse(req);
|
|
||||||
if (resp != null && "success".equalsIgnoreCase(resp.optString("status"))) {
|
|
||||||
updateBlockMenu(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2) Immediately re-check block state from server
|
||||||
|
JSONObject checkReq = new JSONObject()
|
||||||
|
.put("action", "check_block_status_by_chat")
|
||||||
|
.put("viewer_id", Session.getUserUUID())
|
||||||
|
.put("chat_id", entry.getId().toString());
|
||||||
|
|
||||||
|
JSONObject checkResp = ActionHandler.sendWithResponse(checkReq);
|
||||||
|
if (checkResp == null || !"success".equalsIgnoreCase(checkResp.optString("status"))) {
|
||||||
|
System.err.println("⚠️ Failed to refresh block status after toggle.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject data = checkResp.optJSONObject("data");
|
||||||
|
boolean blockedByMe = data != null && data.optBoolean("blocked_by_me", false);
|
||||||
|
boolean blockedMe = data != null && data.optBoolean("blocked_me", false);
|
||||||
|
|
||||||
|
// 3) Update UI on FX thread
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
// update overlay (block/unblock menu)
|
||||||
|
updateBlockMenu(blockedByMe);
|
||||||
|
|
||||||
|
// update chat page input bar
|
||||||
|
ChatPageController c = ChatPageController.getInstance();
|
||||||
|
if (c != null) {
|
||||||
|
c.applyBlockUi(blockedByMe, blockedMe);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBlockMenu(boolean isBlocked) {
|
private void updateBlockMenu(boolean isBlocked) {
|
||||||
|
|||||||
@@ -35,15 +35,6 @@
|
|||||||
<contextMenu>
|
<contextMenu>
|
||||||
<ContextMenu fx:id="infoMoreMenu">
|
<ContextMenu fx:id="infoMoreMenu">
|
||||||
<items>
|
<items>
|
||||||
<MenuItem fx:id="deleteChatItem" text="Delete chat" style="-fx-text-fill: red;">
|
|
||||||
<graphic>
|
|
||||||
<ImageView fitWidth="16" fitHeight="16" preserveRatio="true">
|
|
||||||
<image>
|
|
||||||
<Image url="@/org/to/telegramfinalproject/Icons/delete_red.png"/>
|
|
||||||
</image>
|
|
||||||
</ImageView>
|
|
||||||
</graphic>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem fx:id="blockItem" text="Block" style="-fx-text-fill: red;">
|
<MenuItem fx:id="blockItem" text="Block" style="-fx-text-fill: red;">
|
||||||
<graphic>
|
<graphic>
|
||||||
<ImageView fitWidth="16" fitHeight="16" preserveRatio="true">
|
<ImageView fitWidth="16" fitHeight="16" preserveRatio="true">
|
||||||
@@ -62,6 +53,15 @@
|
|||||||
</ImageView>
|
</ImageView>
|
||||||
</graphic>
|
</graphic>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem fx:id="deleteChatItem" text="Delete chat" style="-fx-text-fill: red;">
|
||||||
|
<graphic>
|
||||||
|
<ImageView fitWidth="16" fitHeight="16" preserveRatio="true">
|
||||||
|
<image>
|
||||||
|
<Image url="@/org/to/telegramfinalproject/Icons/delete_red.png"/>
|
||||||
|
</image>
|
||||||
|
</ImageView>
|
||||||
|
</graphic>
|
||||||
|
</MenuItem>
|
||||||
</items>
|
</items>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
</contextMenu>
|
</contextMenu>
|
||||||
|
|||||||
Reference in New Issue
Block a user