Manage block list

This commit is contained in:
2025-09-05 01:17:52 +03:30
parent dde64fd8aa
commit 297696fba1
4 changed files with 117 additions and 2 deletions
@@ -127,6 +127,37 @@ public class ContactDatabase {
return out; return out;
} }
public static UUID findOtherUserInPrivateChat(UUID chatId, UUID viewerId) {
if (chatId == null || viewerId == null) return null;
final String sql = """
SELECT user1_id, user2_id
FROM private_chat
WHERE chat_id = ?
""";
try (Connection cn = getConnection();
PreparedStatement ps = cn.prepareStatement(sql)) {
ps.setObject(1, chatId);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return null;
UUID u1 = (UUID) rs.getObject("user1_id");
UUID u2 = (UUID) rs.getObject("user2_id");
if (viewerId.equals(u1)) return u2;
if (viewerId.equals(u2)) return u1;
// اگر viewer عضو این چت نیست
return null;
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public boolean unblockContact(UUID user_id, UUID contact_id) { public boolean unblockContact(UUID user_id, UUID contact_id) {
String sql = "UPDATE contacts SET is_blocked = FALSE WHERE user_id = ? AND contact_id = ?"; String sql = "UPDATE contacts SET is_blocked = FALSE WHERE user_id = ? AND contact_id = ?";
try (Connection connection = getConnection()) { try (Connection connection = getConnection()) {
@@ -2972,6 +2972,33 @@ public class ClientHandler implements Runnable {
break; break;
} }
case "check_block_status_by_chat": {
try {
UUID viewerId = UUID.fromString(requestJson.getString("viewer_id"));
UUID chatId = UUID.fromString(requestJson.getString("chat_id"));
UUID otherId = ContactDatabase.findOtherUserInPrivateChat(chatId, viewerId);
if (otherId == null) {
response = new ResponseModel("error", "Chat not found or not private.");
break;
}
boolean blockedByMe = ContactDatabase.isBlocked(viewerId, otherId);
boolean blockedMe = ContactDatabase.isBlocked(otherId, viewerId);
org.json.JSONObject data = new org.json.JSONObject()
.put("other_id", otherId.toString())
.put("blocked_by_me", blockedByMe)
.put("blocked_me", blockedMe);
response = new ResponseModel("success", "ok", data);
} catch (Exception e) {
response = new ResponseModel("error", "Invalid parameters.");
}
break;
}
default: default:
response = new ResponseModel("error", "Unknown action: " + action); response = new ResponseModel("error", "Unknown action: " + action);
@@ -112,6 +112,10 @@ public class ChatPageController {
private static final DateTimeFormatter FMT_DATE_TIME = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); private static final DateTimeFormatter FMT_DATE_TIME = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
private static final String YESTERDAY_LABEL = "Yesterday"; private static final String YESTERDAY_LABEL = "Yesterday";
private boolean blockedByMeFlag = false;
private boolean blockedMeFlag = false;
// ===== state ===== // ===== state =====
private String chatName; private String chatName;
private final ThemeManager themeManager = ThemeManager.getInstance(); private final ThemeManager themeManager = ThemeManager.getInstance();
@@ -809,6 +813,7 @@ public void showChat(ChatEntry entry) {
} }
AvatarFX.circleClip(userAvatar, 36); AvatarFX.circleClip(userAvatar, 36);
// حالت اولیه (بدون انتظار هدر) // حالت اولیه (بدون انتظار هدر)
if ("channel".equalsIgnoreCase(entry.getType())) { if ("channel".equalsIgnoreCase(entry.getType())) {
boolean canPostLocal = entry.isOwner() || entry.isAdmin() boolean canPostLocal = entry.isOwner() || entry.isAdmin()
@@ -824,10 +829,56 @@ public void showChat(ChatEntry entry) {
// حالا هدر بیاد، دوباره نهایی‌اش می‌کنیم // حالا هدر بیاد، دوباره نهایی‌اش می‌کنیم
fetchAndRenderHeader(entry); fetchAndRenderHeader(entry);
} }
private void requestBlockStatusByChat(ChatEntry entry) {
if (entry == null || !"private".equalsIgnoreCase(entry.getType())) return;
String viewerId = Session.getUserUUID(); // internal_uuid کاربر فعلی
if (viewerId == null || viewerId.isBlank()) return;
JSONObject req = new JSONObject()
.put("action", "check_block_status_by_chat")
.put("viewer_id", viewerId)
.put("chat_id", entry.getId().toString());
new Thread(() -> {
JSONObject res = ActionHandler.sendWithResponse(req);
if (res == null || !"success".equalsIgnoreCase(res.optString("status"))) return;
JSONObject data = res.optJSONObject("data");
boolean blockedByMe = data != null && data.optBoolean("blocked_by_me", false);
boolean blockedMe = data != null && data.optBoolean("blocked_me", false);
Platform.runLater(() -> applyBlockUi(blockedByMe, blockedMe));
}).start();
}
private void applyBlockUi(boolean blockedByMe, boolean blockedMe) {
this.blockedByMeFlag = blockedByMe;
this.blockedMeFlag = blockedMe;
if (blockedByMe) {
// من طرف مقابل را بلاک کرده‌ام → فقط دکمه UNBLOCK نمایش بده
if (readOnlyLabel != null) readOnlyLabel.setText("");
applyMode(ChatViewMode.BLOCKED);
return;
}
if (blockedMe) {
// طرف مقابل من را بلاک کرده → متن read-only مخصوص
if (readOnlyLabel != null) readOnlyLabel.setText("YOU ARE BLOCKED");
applyMode(ChatViewMode.READ_ONLY);
return;
}
// هیچ‌کس بلاک نکرده
applyMode(ChatViewMode.NORMAL);
}
public void showChat(ChatEntry entry, ChatViewMode mode) { public void showChat(ChatEntry entry, ChatViewMode mode) {
this.currentChat = entry; this.currentChat = entry;
@@ -1798,7 +1849,7 @@ private void addBubble(
if (online) return "online"; if (online) return "online";
LocalDateTime ts = parseWhen(lastSeenIso); LocalDateTime ts = parseWhen(lastSeenIso);
if (ts == null) return "Last seen recently"; if (ts == null) return "last seen recently";
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
LocalDate d = ts.toLocalDate(); LocalDate d = ts.toLocalDate();
@@ -1811,7 +1862,7 @@ private void addBubble(
if (days > 30) { if (days > 30) {
return "Last seen long time ago"; return "Last seen long time ago";
} }
return "Last seen recently"; return "last seen recently";
} }
private void setDefaultHeaderAvatarByType(String type){ private void setDefaultHeaderAvatarByType(String type){
@@ -2537,4 +2588,6 @@ private void addBubble(
} }
@@ -38,6 +38,9 @@ public class MainController {
@FXML private ScrollPane globalSearchScroll; @FXML private ScrollPane globalSearchScroll;
@FXML private VBox globalSearchResultsContainer; @FXML private VBox globalSearchResultsContainer;
private boolean blockedByMeFlag = false;
private boolean blockedMeFlag = false;
@@ -1154,4 +1157,5 @@ public class MainController {
} }