Blocked Users UI implemented.
This commit is contained in:
@@ -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<HBox> 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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* دقیقاً فقط روی این دو دکمه اعمال میشود */
|
||||
#joinAction, #addContactAction {
|
||||
-fx-background-color: transparent, transparent, transparent, transparent;
|
||||
-fx-background-insets: 0,0,0,0;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* رنگها */
|
||||
/* Colors */
|
||||
:root {
|
||||
-tg-bg: #ffffff;
|
||||
-tg-sheet: #ffffff;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
||||
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.to.telegramfinalproject.UI.BlockedUsersController"
|
||||
styleClass="overlay-root">
|
||||
|
||||
<!-- Dimmed background -->
|
||||
<Pane fx:id="overlayBackground" styleClass="overlay-background"/>
|
||||
|
||||
<!-- Card -->
|
||||
<VBox fx:id="blockedCard" styleClass="blocked-card" spacing="8"
|
||||
prefWidth="380" maxWidth="380"
|
||||
prefHeight="500" maxHeight="500">
|
||||
|
||||
<!-- ===== Header ===== -->
|
||||
<HBox alignment="CENTER_LEFT" spacing="10" styleClass="blocked-header">
|
||||
<Button fx:id="backButton" styleClass="icon-button"/>
|
||||
<Label text="Blocked users" styleClass="blocked-title"/>
|
||||
<Pane HBox.hgrow="ALWAYS"/>
|
||||
<Button fx:id="closeButton" styleClass="icon-button" text="✕"/>
|
||||
</HBox>
|
||||
|
||||
<Separator/>
|
||||
|
||||
<Label text="Blocked users can't send you messages or add you to groups.
|
||||
They will not see your profile photos, online and last seen status."
|
||||
wrapText="true"
|
||||
prefHeight="160"
|
||||
maxHeight="160"
|
||||
styleClass="blocked-info-label"/>
|
||||
|
||||
<!-- ===== List of blocked users ===== -->
|
||||
<Label fx:id="countLabel" text="0 blocked users" styleClass="blocked-count"/>
|
||||
|
||||
<ListView fx:id="blockedList" styleClass="blocked-list" VBox.vgrow="ALWAYS"/>
|
||||
</VBox>
|
||||
</StackPane>
|
||||
Reference in New Issue
Block a user