My Profile UI implemented.
This commit is contained in:
@@ -277,4 +277,13 @@ public class MainController {
|
|||||||
private void updateLabelsForLightMode() {
|
private void updateLabelsForLightMode() {
|
||||||
//myLabel.setStyle("-fx-text-fill: black;");
|
//myLabel.setStyle("-fx-text-fill: black;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === Overlay Handling ===
|
||||||
|
public void showOverlay(Node overlayNode) {
|
||||||
|
mainRoot.getChildren().add(overlayNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeOverlay(Node overlayNode) {
|
||||||
|
mainRoot.getChildren().remove(overlayNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,96 @@
|
|||||||
package org.to.telegramfinalproject.UI;
|
package org.to.telegramfinalproject.UI;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import org.to.telegramfinalproject.Models.User;
|
import javafx.scene.layout.Pane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.shape.Circle;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MyProfileController {
|
public class MyProfileController {
|
||||||
|
|
||||||
|
@FXML private Pane overlayBackground;
|
||||||
|
@FXML private Button closeButton;
|
||||||
|
@FXML private Button editButton;
|
||||||
@FXML private ImageView profileImage;
|
@FXML private ImageView profileImage;
|
||||||
@FXML private Label displayName;
|
@FXML private Label profileName;
|
||||||
@FXML private Label status;
|
@FXML private Label profileStatus;
|
||||||
@FXML private Label bio;
|
@FXML private Label userBio;
|
||||||
@FXML private Label userId;
|
@FXML private Label userId;
|
||||||
|
@FXML private VBox profileCard;
|
||||||
|
@FXML private VBox bioBlock;
|
||||||
|
|
||||||
|
private final ThemeManager themeManager = ThemeManager.getInstance();
|
||||||
|
|
||||||
// public void initialize() {
|
@FXML
|
||||||
// // Load data from your logged-in user object
|
private void initialize() {
|
||||||
// // Example:
|
overlayBackground.setOnMouseClicked(e -> closeProfile());
|
||||||
// displayName.setText(CurrentUser.getName());
|
closeButton.setOnAction(e -> closeProfile());
|
||||||
// status.setText(CurrentUser.isOnline() ? "online" : "offline");
|
|
||||||
// bio.setText(CurrentUser.getBio());
|
// Round profile picture
|
||||||
// userId.setText(CurrentUser.getUserId());
|
profileImage.setClip(new Circle(40, 40, 40));
|
||||||
//
|
|
||||||
// if (CurrentUser.getProfileImagePath() != null) {
|
// Default avatar
|
||||||
// profileImage.setImage(new Image(CurrentUser.getProfileImagePath()));
|
profileImage.setImage(new Image(
|
||||||
// }
|
Objects.requireNonNull(getClass().getResourceAsStream(
|
||||||
// }
|
"/org/to/telegramfinalproject/Avatars/default_profile.png"))
|
||||||
|
));
|
||||||
|
|
||||||
|
// Register scene for ThemeManager → stylesheet swap will handle colors/icons
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
if (profileCard.getScene() != null) {
|
||||||
|
ThemeManager.getInstance().registerScene(profileCard.getScene());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listener for theme change
|
||||||
|
ThemeManager.getInstance().darkModeProperty().addListener((obs, oldVal, newVal) -> {
|
||||||
|
updateEditIcon(newVal);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set initial state
|
||||||
|
updateEditIcon(ThemeManager.getInstance().isDarkMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeProfile() {
|
||||||
|
MainController.getInstance().closeOverlay(profileCard.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate user data from DB or active session
|
||||||
|
public void setProfileData(String name, String status, String bio, String userId, String imageUrl) {
|
||||||
|
profileName.setText(name);
|
||||||
|
profileStatus.setText(status);
|
||||||
|
|
||||||
|
if (bio == null || bio.isBlank()) {
|
||||||
|
bioBlock.setVisible(false);
|
||||||
|
bioBlock.setManaged(false);
|
||||||
|
} else {
|
||||||
|
userBio.setText(bio);
|
||||||
|
userBio.setVisible(true);
|
||||||
|
userBio.setManaged(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.userId.setText(userId);
|
||||||
|
|
||||||
|
if (imageUrl != null && !imageUrl.isEmpty()) {
|
||||||
|
profileImage.setImage(new Image(imageUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Theme-specific updates ===
|
||||||
|
private void updateEditIcon(boolean darkMode) {
|
||||||
|
String iconPath = darkMode
|
||||||
|
? "/org/to/telegramfinalproject/Icons/edit_light.png"
|
||||||
|
: "/org/to/telegramfinalproject/Icons/edit_dark.png";
|
||||||
|
|
||||||
|
ImageView icon = new ImageView(new Image(getClass().getResourceAsStream(iconPath)));
|
||||||
|
icon.setFitWidth(16);
|
||||||
|
icon.setFitHeight(16);
|
||||||
|
editButton.setGraphic(icon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,9 @@ package org.to.telegramfinalproject.UI;
|
|||||||
import javafx.animation.TranslateTransition;
|
import javafx.animation.TranslateTransition;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
@@ -12,6 +15,7 @@ import javafx.scene.layout.Region;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
public class SidebarMenuController {
|
public class SidebarMenuController {
|
||||||
@@ -167,8 +171,24 @@ public class SidebarMenuController {
|
|||||||
return iv;
|
return iv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sidebar actions
|
||||||
|
private void openMyProfile() {
|
||||||
|
try {
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/Fxml/my_profile.fxml"));
|
||||||
|
Node profileOverlay = loader.load();
|
||||||
|
|
||||||
|
MyProfileController controller = loader.getController();
|
||||||
|
controller.setProfileData("Asal", "online", "Pass me that lovely little gun♡.", "@Whales_suicide", null);
|
||||||
|
|
||||||
|
// Show the overlay on top of mainRoot
|
||||||
|
MainController.getInstance().showOverlay(profileOverlay);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Example button actions
|
// Example button actions
|
||||||
private void openMyProfile() { System.out.println("Opening My Profile..."); }
|
|
||||||
private void createNewGroup() { System.out.println("Creating New Group..."); }
|
private void createNewGroup() { System.out.println("Creating New Group..."); }
|
||||||
private void createNewChannel() { System.out.println("Creating New Channel..."); }
|
private void createNewChannel() { System.out.println("Creating New Channel..."); }
|
||||||
private void openContacts() { System.out.println("Opening Contacts..."); }
|
private void openContacts() { System.out.println("Opening Contacts..."); }
|
||||||
|
|||||||
@@ -294,3 +294,75 @@
|
|||||||
-fx-background-radius: 10;
|
-fx-background-radius: 10;
|
||||||
-fx-font-weight: bold;
|
-fx-font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== Overlay ===== */
|
||||||
|
.overlay-root {
|
||||||
|
-fx-alignment: CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay-background {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-pref-width: 100%;
|
||||||
|
-fx-pref-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Profile Card ===== */
|
||||||
|
.profile-card {
|
||||||
|
-fx-background-color: #0f1c26;
|
||||||
|
-fx-background-radius: 10;
|
||||||
|
-fx-padding: 16;
|
||||||
|
-fx-max-width: 320;
|
||||||
|
-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.6), 12, 0, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Header ===== */
|
||||||
|
.profile-title {
|
||||||
|
-fx-font-size: 16px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-text-fill: #eee;
|
||||||
|
}
|
||||||
|
.icon-button {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-padding: 4;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
-fx-text-fill: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Text Styles ===== */
|
||||||
|
.profile-name {
|
||||||
|
-fx-font-size: 18px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-text-fill: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-status {
|
||||||
|
-fx-font-size: 12px;
|
||||||
|
-fx-text-fill: #2196f3; /* online */
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-bio {
|
||||||
|
-fx-font-size: 13px;
|
||||||
|
-fx-text-fill: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-id {
|
||||||
|
-fx-font-size: 13px;
|
||||||
|
-fx-text-fill: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section separators */
|
||||||
|
.section-separator {
|
||||||
|
-fx-background-color: #223446;
|
||||||
|
-fx-pref-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Info text */
|
||||||
|
.profile-info-main {
|
||||||
|
-fx-font-size: 14px;
|
||||||
|
-fx-text-fill: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-info-sub {
|
||||||
|
-fx-font-size: 11px;
|
||||||
|
-fx-text-fill: #999;
|
||||||
|
}
|
||||||
|
|||||||
@@ -293,3 +293,74 @@
|
|||||||
-fx-background-radius: 10;
|
-fx-background-radius: 10;
|
||||||
-fx-font-weight: bold;
|
-fx-font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== Overlay ===== */
|
||||||
|
.overlay-root {
|
||||||
|
-fx-alignment: CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay-background {
|
||||||
|
-fx-background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
-fx-pref-width: 100%;
|
||||||
|
-fx-pref-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Profile Card ===== */
|
||||||
|
.profile-card {
|
||||||
|
-fx-background-color: white;
|
||||||
|
-fx-background-radius: 10;
|
||||||
|
-fx-padding: 16;
|
||||||
|
-fx-max-width: 320;
|
||||||
|
-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.35), 12, 0, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Header ===== */
|
||||||
|
.profile-title {
|
||||||
|
-fx-font-size: 16px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
}
|
||||||
|
.icon-button {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-padding: 4;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
-fx-text-fill: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Text Styles ===== */
|
||||||
|
.profile-name {
|
||||||
|
-fx-font-size: 18px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-text-fill: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-status {
|
||||||
|
-fx-font-size: 12px;
|
||||||
|
-fx-text-fill: #2196f3; /* online */
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-bio {
|
||||||
|
-fx-font-size: 13px;
|
||||||
|
-fx-text-fill: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-id {
|
||||||
|
-fx-font-size: 13px;
|
||||||
|
-fx-text-fill: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section separators */
|
||||||
|
.section-separator {
|
||||||
|
-fx-background-color: #ddd;
|
||||||
|
-fx-pref-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Info text */
|
||||||
|
.profile-info-main {
|
||||||
|
-fx-font-size: 14px;
|
||||||
|
-fx-text-fill: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-info-sub {
|
||||||
|
-fx-font-size: 11px;
|
||||||
|
-fx-text-fill: #888;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
.my-profile-root {
|
|
||||||
-fx-background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-image {
|
|
||||||
-fx-clip-radius: 40; /* Rounded image */
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-name {
|
|
||||||
-fx-font-size: 18px;
|
|
||||||
-fx-font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-status {
|
|
||||||
-fx-text-fill: green;
|
|
||||||
-fx-font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-label {
|
|
||||||
-fx-font-weight: bold;
|
|
||||||
-fx-text-fill: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-value {
|
|
||||||
-fx-text-fill: #555;
|
|
||||||
}
|
|
||||||
@@ -1,40 +1,63 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.image.ImageView?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.text.Text?>
|
|
||||||
|
|
||||||
<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="org.to.telegramfinalproject.UI.MyProfileController"
|
<?import javafx.scene.image.Image?>
|
||||||
prefWidth="400" prefHeight="600"
|
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||||
styleClass="my-profile-root">
|
fx:controller="org.to.telegramfinalproject.UI.MyProfileController"
|
||||||
|
styleClass="overlay-root">
|
||||||
|
|
||||||
<VBox spacing="15" padding="20">
|
<!-- Background (click to close) -->
|
||||||
|
<Pane fx:id="overlayBackground" styleClass="overlay-background"/>
|
||||||
|
|
||||||
<!-- Top Bar -->
|
<!-- Profile card -->
|
||||||
|
<VBox fx:id="profileCard" styleClass="profile-card" spacing="16"
|
||||||
|
prefWidth="360" maxWidth="360"
|
||||||
|
prefHeight="480" maxHeight="480">
|
||||||
|
|
||||||
|
<!-- ===== Header: My Profile (left) + actions (right) ===== -->
|
||||||
<HBox alignment="CENTER_LEFT" spacing="10">
|
<HBox alignment="CENTER_LEFT" spacing="10">
|
||||||
<ImageView fx:id="profileImage" fitHeight="80" fitWidth="80"
|
<Label text="My Profile" styleClass="profile-title" HBox.hgrow="ALWAYS"/>
|
||||||
styleClass="profile-image"/>
|
<Pane HBox.hgrow="ALWAYS"/> <!-- pushes buttons to right -->
|
||||||
<VBox>
|
|
||||||
<Label fx:id="displayName" text="Display Name" styleClass="profile-name"/>
|
<Button fx:id="editButton" styleClass="icon-button"/>
|
||||||
<Label fx:id="status" text="online" styleClass="profile-status"/>
|
<Button fx:id="closeButton" styleClass="icon-button" text="✕"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<!-- ===== Profile section: picture + name/status ===== -->
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="12">
|
||||||
|
<ImageView fx:id="profileImage" fitWidth="80" fitHeight="80" preserveRatio="true"
|
||||||
|
styleClass="profile-picture"/>
|
||||||
|
<VBox alignment="CENTER_LEFT" spacing="4">
|
||||||
|
<Label fx:id="profileName" text="User Name" styleClass="profile-name"/>
|
||||||
|
<Label fx:id="profileStatus" text="online" styleClass="profile-status"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<Separator/>
|
<Separator styleClass="section-separator"/>
|
||||||
|
|
||||||
<!-- Bio -->
|
<!-- User info blocks (shifted to align under profile image) -->
|
||||||
<HBox spacing="10" alignment="CENTER_LEFT">
|
<HBox alignment="TOP_LEFT">
|
||||||
<Label text="Bio:" styleClass="field-label"/>
|
<Pane prefWidth="30"/>
|
||||||
<Label fx:id="bio" text="This is the bio..." wrapText="true" styleClass="field-value"/>
|
|
||||||
|
<VBox spacing="16">
|
||||||
|
|
||||||
|
<!-- Bio -->
|
||||||
|
<VBox fx:id="bioBlock" spacing="2">
|
||||||
|
<Label fx:id="userBio" wrapText="true" styleClass="profile-info-main"/>
|
||||||
|
<Label text="Bio" styleClass="profile-info-sub"/>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
<!-- Username -->
|
||||||
|
<VBox spacing="2">
|
||||||
|
<Label fx:id="userId" styleClass="profile-info-main"/>
|
||||||
|
<Label text="Username" styleClass="profile-info-sub"/>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
</VBox>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<!-- User ID -->
|
|
||||||
<HBox spacing="10" alignment="CENTER_LEFT">
|
|
||||||
<Label text="User ID:" styleClass="field-label"/>
|
|
||||||
<Label fx:id="userId" text="@user_id" styleClass="field-value"/>
|
|
||||||
</HBox>
|
|
||||||
|
|
||||||
</VBox>
|
</VBox>
|
||||||
</AnchorPane>
|
</StackPane>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 549 B |
Binary file not shown.
|
After Width: | Height: | Size: 541 B |
Reference in New Issue
Block a user