From fcd8b1b6c082db8b2d69036743dfb6e9085192f5 Mon Sep 17 00:00:00 2001 From: Asal Lotfi Date: Thu, 4 Sep 2025 10:01:18 +0330 Subject: [PATCH 1/5] Blocked Users UI implemented. --- .../UI/BlockedUsersController.java | 142 ++++++++++++++++++ .../UI/PrivacySecurityController.java | 13 +- .../org/to/telegramfinalproject/CSS/chat.css | 1 - .../telegramfinalproject/CSS/dark_theme.css | 79 ++++++++++ .../telegramfinalproject/CSS/light_theme.css | 71 +++++++++ .../telegramfinalproject/CSS/scrollpane.css | 17 +++ .../CSS/telegram-action.css | 2 +- .../Fxml/blocked_users.fxml | 42 ++++++ 8 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/to/telegramfinalproject/UI/BlockedUsersController.java create mode 100644 src/main/resources/org/to/telegramfinalproject/Fxml/blocked_users.fxml diff --git a/src/main/java/org/to/telegramfinalproject/UI/BlockedUsersController.java b/src/main/java/org/to/telegramfinalproject/UI/BlockedUsersController.java new file mode 100644 index 0000000..c7c5486 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/BlockedUsersController.java @@ -0,0 +1,142 @@ +package org.to.telegramfinalproject.UI; + +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.shape.Circle; + +public class BlockedUsersController { + + @FXML private Pane overlayBackground; + @FXML private Button backButton; + @FXML private Button closeButton; + @FXML private Label countLabel; + @FXML private ListView blockedList; + @FXML private VBox blockedCard; + + @FXML + public void initialize() { + // Back button icon + backButton.setGraphic(makeIcon("/org/to/telegramfinalproject/Icons/back_button_dark.png")); + + // Example blocked users (replace with server data) + addBlockedUser("Asal", "@Whales_suicide", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Replies", "@replies", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Asal", "@Whales_suicide", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Replies", "@replies", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Asal", "@Whales_suicide", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Replies", "@replies", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Asal", "@Whales_suicide", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Replies", "@replies", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Asal", "@Whales_suicide", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + addBlockedUser("Replies", "@replies", "/org/to/telegramfinalproject/Avatars/default_user_profile.png"); + + updateCount(); + + closeButton.setOnAction(e -> MainController.getInstance().closeOverlay(overlayBackground.getParent())); + backButton.setOnAction(e -> MainController.getInstance().goBack((StackPane) overlayBackground.getParent())); + + overlayBackground.setOnMouseClicked(e -> MainController.getInstance().closeOverlay(blockedCard.getParent())); + + // Register scene for ThemeManager → stylesheet swap will handle colors/icons + Platform.runLater(() -> { + if (blockedCard.getScene() != null) { + ThemeManager.getInstance().registerScene(blockedCard.getScene()); + } + }); + + // Listener for theme change + ThemeManager.getInstance().darkModeProperty().addListener((obs, oldVal, newVal) -> { + updateBackIcon(newVal); + }); + + // Set initial state + updateBackIcon(ThemeManager.getInstance().isDarkMode()); + + // Add CSS + blockedList.getStylesheets().add( + getClass().getResource("/org/to/telegramfinalproject/CSS/scrollpane.css").toExternalForm() + ); + + // Wait until skin is ready + blockedList.skinProperty().addListener((obs, oldSkin, newSkin) -> { + if (newSkin != null) { + // Look up vertical scrollbar inside the ListView + ScrollBar vBar = (ScrollBar) blockedList.lookup(".scroll-bar:vertical"); + if (vBar != null) { + blockedList.setOnScroll(event -> { + double deltaY = event.getDeltaY() * 0.003; // smaller = smoother + double newValue = vBar.getValue() - deltaY; + vBar.setValue(Math.max(0, Math.min(newValue, 1))); // clamp between 0–1 + }); + } + } + }); + } + + private void addBlockedUser(String name, String id, String avatarPath) { + // Avatar + ImageView avatar = new ImageView(new Image(getClass().getResourceAsStream(avatarPath))); + avatar.setFitWidth(60); + avatar.setFitHeight(60); + avatar.setPreserveRatio(true); + avatar.setSmooth(true); + avatar.setCache(true); + + // round mask + Circle clip = new Circle(20, 20, 40); // x, y, radius (same as half of fit size) + avatar.setClip(clip); + + // Name + ID + VBox info = new VBox(2); + Label nameLabel = new Label(name); + nameLabel.getStyleClass().add("blocked-name"); + Label idLabel = new Label(id); + idLabel.getStyleClass().add("blocked-id"); + info.getChildren().addAll(nameLabel, idLabel); + + // Unblock button + Button unblockBtn = new Button("Unblock"); + unblockBtn.getStyleClass().add("unblock-button"); + unblockBtn.setOnAction(e -> { + blockedList.getItems().removeIf(h -> h.getChildren().contains(avatar)); + updateCount(); + }); + + // Row + HBox row = new HBox(10, avatar, info, unblockBtn); + row.setSpacing(12); + row.getStyleClass().add("blocked-row"); + HBox.setHgrow(info, javafx.scene.layout.Priority.ALWAYS); + + blockedList.getItems().add(row); + } + + private void updateCount() { + countLabel.setText(blockedList.getItems().size() + " blocked users"); + } + + private void updateBackIcon(boolean darkMode) { + String iconPath = darkMode + ? "/org/to/telegramfinalproject/Icons/back_button_light.png" + : "/org/to/telegramfinalproject/Icons/back_button_dark.png"; + + ImageView icon = new ImageView(new Image(getClass().getResourceAsStream(iconPath))); + icon.setFitWidth(16); + icon.setFitHeight(16); + backButton.setGraphic(icon); + } + + private ImageView makeIcon(String path) { + ImageView iv = new ImageView(new Image(getClass().getResourceAsStream(path))); + iv.setFitWidth(20); + iv.setFitHeight(20); + return iv; + } +} diff --git a/src/main/java/org/to/telegramfinalproject/UI/PrivacySecurityController.java b/src/main/java/org/to/telegramfinalproject/UI/PrivacySecurityController.java index e76ac5c..13b3229 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/PrivacySecurityController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/PrivacySecurityController.java @@ -41,8 +41,17 @@ public class PrivacySecurityController { // Blocked users management blockedUsersButton.setOnAction(e -> { - // TODO: open Blocked Users scene - System.out.println("Open blocked users management"); + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource( + "/org/to/telegramfinalproject/Fxml/blocked_users.fxml")); + Node overlay = loader.load(); + + // Show new overlay + MainController.getInstance().showOverlay(overlay); + + } catch (IOException ex) { + ex.printStackTrace(); + } }); // Close diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/chat.css b/src/main/resources/org/to/telegramfinalproject/CSS/chat.css index 5def59d..97d0747 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/chat.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/chat.css @@ -1,4 +1,3 @@ -/* دقیقاً فقط روی این دو دکمه اعمال می‌شود */ #joinAction, #addContactAction { -fx-background-color: transparent, transparent, transparent, transparent; -fx-background-insets: 0,0,0,0; diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css b/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css index c9d899e..8e75311 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css @@ -989,3 +989,82 @@ -fx-padding: 0 6 0 6; -fx-font-size: 14px; } + +.blocked-card { + -fx-background-color: #1f2a36; + -fx-background-radius: 10; + -fx-padding: 12; +} + +.blocked-header { + -fx-padding: 8; +} +.blocked-title { + -fx-font-size: 16px; + -fx-font-weight: bold; + -fx-text-fill: white; +} + +.blocked-count { + -fx-font-size: 13px; + -fx-text-fill: #999; + -fx-padding: 4 0; +} + +.blocked-list { + -fx-background-color: #253544; +} + +.blocked-row { + -fx-padding: 8; + -fx-background-color: transparent; +} +.blocked-row:hover { + -fx-background-color: #253544; +} + +.blocked-name { + -fx-font-size: 13px; + -fx-font-weight: bold; + -fx-text-fill: white; +} +.blocked-id { + -fx-font-size: 12px; + -fx-text-fill: #aaa; +} + +.unblock-button { + -fx-background-color: transparent; + -fx-text-fill: #3a86ff; + -fx-cursor: hand; +} + +.unblock-button:hover { + -fx-text-fill: #66aaff; +} + +.blocked-info-label { + -fx-background-color: #2c3e50; /* darker banner background */ + -fx-text-fill: #bbb; /* lighter muted text */ + -fx-font-size: 12px; + -fx-wrap-text: true; + -fx-padding: 5; + -fx-background-radius: 4; +} + +.blocked-list .thumb { + -fx-background-color: rgba(200, 200, 200, 0.5); /* lighter for dark bg */ +} + +/* Each list cell */ +.blocked-list .list-cell { + -fx-background-color: #1f2a36; + -fx-text-fill: #eeeeee; + -fx-padding: 8 12; + -fx-border-color: #2f2f2f; + -fx-border-width: 0 0 1 0; +} + +.blocked-list .list-cell:hover { + -fx-background-color: #2a3a4a; +} \ No newline at end of file diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css b/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css index 48d8e32..bed18c0 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css @@ -989,3 +989,74 @@ -fx-padding: 0 6 0 6; -fx-font-size: 14px; } + +/* Blocked Users card */ +.blocked-card { + -fx-background-color: white; + -fx-background-radius: 10; + -fx-padding: 12; +} + +/* Header */ +.blocked-header { + -fx-padding: 8; +} +.blocked-title { + -fx-font-size: 16px; + -fx-font-weight: bold; + -fx-text-fill: black; +} + +/* Count */ +.blocked-count { + -fx-font-size: 13px; + -fx-text-fill: #888; + -fx-padding: 4 0; +} + +/* List */ +.blocked-list { + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +/* Row */ +.blocked-row { + -fx-padding: 8; + -fx-background-color: transparent; +} +.blocked-row:hover { + -fx-background-color: #f5f5f5; +} + +/* Labels */ +.blocked-name { + -fx-font-size: 13px; + -fx-font-weight: bold; + -fx-text-fill: black; +} +.blocked-id { + -fx-font-size: 12px; + -fx-text-fill: #666; +} + +/* Button */ +.unblock-button { + -fx-background-color: transparent; + -fx-text-fill: #2196f3; + -fx-cursor: hand; +} + +.unblock-button:hover { + -fx-text-fill: #66aaff; +} + +.blocked-info-label { + -fx-background-color: #f5f5f5; /* light gray background */ + -fx-text-fill: #555; /* muted text */ + -fx-font-size: 12px; + -fx-wrap-text: true; + -fx-padding: 5; /* space inside like a banner */ + -fx-background-radius: 4; /* soft rounded edges */ +} + diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/scrollpane.css b/src/main/resources/org/to/telegramfinalproject/CSS/scrollpane.css index b6f1ffe..7c00d54 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/scrollpane.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/scrollpane.css @@ -20,3 +20,20 @@ -fx-background-color: rgba(100, 100, 100, 0.5); /* Semi-transparent thumb */ -fx-background-radius: 3px; } + + +.blocked-list .scroll-bar { + -fx-background-color: transparent; + -fx-opacity: 0; + -fx-pref-width: 6px; + -fx-background-radius: 3px; +} + +.blocked-list:hover .scroll-bar { + -fx-opacity: 0.6; +} + +.blocked-list .thumb { + -fx-background-color: rgba(100, 100, 100, 0.5); + -fx-background-radius: 3px; +} diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/telegram-action.css b/src/main/resources/org/to/telegramfinalproject/CSS/telegram-action.css index 68a71e6..e9fe509 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/telegram-action.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/telegram-action.css @@ -1,4 +1,4 @@ -/* رنگ‌ها */ +/* Colors */ :root { -tg-bg: #ffffff; -tg-sheet: #ffffff; diff --git a/src/main/resources/org/to/telegramfinalproject/Fxml/blocked_users.fxml b/src/main/resources/org/to/telegramfinalproject/Fxml/blocked_users.fxml new file mode 100644 index 0000000..11f4644 --- /dev/null +++ b/src/main/resources/org/to/telegramfinalproject/Fxml/blocked_users.fxml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + +