From 4b11ee51a33c3e10d0645cfe121519ef045fa6ae Mon Sep 17 00:00:00 2001 From: Asal Lotfi Date: Thu, 4 Sep 2025 19:26:26 +0330 Subject: [PATCH] My Profile Backend connected to UI. --- .../UI/EditProfileController.java | 91 ++++++++++++++++++- .../UI/MainController.java | 6 +- .../UI/MyProfileController.java | 20 ++-- .../UI/SidebarMenuController.java | 46 +++++++++- 4 files changed, 148 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/to/telegramfinalproject/UI/EditProfileController.java b/src/main/java/org/to/telegramfinalproject/UI/EditProfileController.java index de8eba8..8df3ad3 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/EditProfileController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/EditProfileController.java @@ -1,9 +1,11 @@ package org.to.telegramfinalproject.UI; +import javafx.animation.PauseTransition; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Node; +import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextField; @@ -13,6 +15,10 @@ import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; +import javafx.util.Duration; +import org.json.JSONObject; +import org.to.telegramfinalproject.Client.ActionHandler; +import org.to.telegramfinalproject.Client.Session; import java.io.File; import java.io.IOException; @@ -43,11 +49,18 @@ public class EditProfileController { )); // close on background click - overlayBackground.setOnMouseClicked(e -> closeEdit()); + overlayBackground.setOnMouseClicked(e -> { + saveChangesAndClose(); + closeEdit(); + }); - closeButton.setOnAction(e -> closeEdit()); + closeButton.setOnAction(e -> { + saveChangesAndClose(); + closeEdit(); + }); backButton.setOnAction(e -> { + saveChangesAndClose(); MainController.getInstance().goBack(overlayBackground); }); @@ -112,4 +125,78 @@ public class EditProfileController { usernameField.setText(userId); profileImageView.setImage(profileImage); } + + private void saveChangesAndClose() { + JSONObject currentUser = Session.currentUser; + + String newBio = bioField.getText().trim(); + String newName = nameField.getText().trim(); + String newUserId = usernameField.getText().trim(); + + boolean anyError = false; + + // --- Update bio --- + String oldBio = currentUser.optString("bio", ""); + if (!newBio.equals(oldBio)) { + JSONObject req = new JSONObject().put("action", "edit_bio").put("new_bio", newBio); + JSONObject resp = ActionHandler.sendWithResponse(req); + if (resp == null || !"success".equals(resp.optString("status"))) { + anyError = true; + showAlert("Error", resp != null ? resp.optString("message", "Unknown error") : "Unknown error", Alert.AlertType.ERROR); + } else { + currentUser.put("bio", newBio); + } + } + + // --- Update profile name --- + String oldName = currentUser.optString("profile_name", ""); + if (!newName.equals(oldName)) { + JSONObject req = new JSONObject().put("action", "edit_profile_name").put("new_profile_name", newName); + JSONObject resp = ActionHandler.sendWithResponse(req); + if (resp == null || !"success".equals(resp.optString("status"))) { + anyError = true; + showAlert("Error", resp != null ? resp.optString("message", "Unknown error") : "Unknown error", Alert.AlertType.ERROR); + } else { + currentUser.put("profile_name", newName); + } + } + + // --- Update user ID (username) --- + String oldUserId = currentUser.optString("user_id", ""); + if (!newUserId.equals(oldUserId)) { + JSONObject req = new JSONObject().put("action", "edit_user_id").put("new_user_id", newUserId); + JSONObject resp = ActionHandler.sendWithResponse(req); + if (resp == null || !"success".equals(resp.optString("status"))) { + anyError = true; + showAlert("Error", resp != null ? resp.optString("message", "Unknown error") : "Unknown error", Alert.AlertType.ERROR); + } else { + currentUser.put("user_id", newUserId); + } + } + + if (!anyError) { + MyProfileController.getInstance().setProfileData( + currentUser.optString("profile_name"), + "online", + currentUser.optString("bio"), + currentUser.optString("user_id"), + currentUser.optString("image_url", "/org/to/telegramfinalproject/Avatars/default_user_profile.png") + ); + MainController.getInstance().closeOverlay(bioField.getParent().getParent()); + } + } + + private void showAlert(String title, String message, Alert.AlertType type) { + Alert alert = new Alert(type); + alert.setTitle(title); + alert.setHeaderText(null); // no big header, just the message + alert.setContentText(message); + + // optional: style it to fit your dark/light theme + if (alert.getDialogPane().getScene() != null) { + ThemeManager.getInstance().registerScene(alert.getDialogPane().getScene()); + } + + alert.showAndWait(); + } } diff --git a/src/main/java/org/to/telegramfinalproject/UI/MainController.java b/src/main/java/org/to/telegramfinalproject/UI/MainController.java index ad1252a..38f2236 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/MainController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/MainController.java @@ -1,5 +1,6 @@ package org.to.telegramfinalproject.UI; +import javafx.animation.PauseTransition; import javafx.animation.TranslateTransition; import javafx.application.Platform; import javafx.fxml.FXML; @@ -643,6 +644,7 @@ public class MainController { private enum SRType { USER, GROUP, CHANNEL, MESSAGE } + // Inner class private static class SearchResult { final SRType type; final String title; // name / sender_name / ... @@ -1136,8 +1138,4 @@ public class MainController { getChatPageController().showChat(entry); } } - - - - } \ No newline at end of file diff --git a/src/main/java/org/to/telegramfinalproject/UI/MyProfileController.java b/src/main/java/org/to/telegramfinalproject/UI/MyProfileController.java index 1ff67b2..52a82b8 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/MyProfileController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/MyProfileController.java @@ -28,7 +28,14 @@ public class MyProfileController { @FXML private VBox profileCard; @FXML private VBox bioBlock; - private final ThemeManager themeManager = ThemeManager.getInstance(); + private String userID; + private static MyProfileController instance; + + public MyProfileController() { + instance = this; + } + + public static MyProfileController getInstance() { return instance;} @FXML private void initialize() { @@ -77,11 +84,12 @@ public class MyProfileController { bioBlock.setManaged(false); } else { userBio.setText(bio); - userBio.setVisible(true); - userBio.setManaged(true); + bioBlock.setVisible(true); + bioBlock.setManaged(true); } - this.userId.setText(userId); + this.userId.setText("@" + userId); + userID = userId; if (imageUrl != null && !imageUrl.isEmpty()) { profileImage.setImage(new Image(imageUrl)); @@ -111,8 +119,8 @@ public class MyProfileController { controller.setProfileData( profileName.getText(), profileStatus.getText(), - userBio.isVisible() ? userBio.getText() : null, - userId.getText(), + bioBlock.isVisible() ? userBio.getText() : null, + userID, profileImage.getImage() ); diff --git a/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java b/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java index 696529d..267a0ff 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java @@ -1,11 +1,13 @@ package org.to.telegramfinalproject.UI; +import javafx.animation.PauseTransition; import javafx.animation.TranslateTransition; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.Parent; +import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.image.Image; @@ -15,6 +17,7 @@ import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.util.Duration; import org.json.JSONObject; +import org.to.telegramfinalproject.Client.ActionHandler; import org.to.telegramfinalproject.Client.AvatarLocalResolver; @@ -182,17 +185,42 @@ public class SidebarMenuController { // Sidebar actions private void openMyProfile() { try { - FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/Fxml/my_profile.fxml")); + // 1. Ask server for profile info + JSONObject request = new JSONObject().put("action", "get_user_profile"); + JSONObject response = ActionHandler.sendWithResponse(request); + + if (response == null || !"success".equals(response.optString("status"))) { + showAlert("Error", "Failed to load profile", Alert.AlertType.ERROR); + return; + } + + JSONObject profile = response.optJSONObject("data"); + if (profile == null) { + showAlert("Error", "Malformed profile data", Alert.AlertType.ERROR); + return; + } + + // Extract fields + String profileName = profile.optString("profile_name", "Unknown"); + String bio = profile.optString("bio", ""); + String userId = profile.optString("user_id", ""); + String imageUrl = profile.optString("profile_picture_url", null); + + // 2. Load overlay FXML + FXMLLoader loader = new FXMLLoader(getClass().getResource( + "/org/to/telegramfinalproject/Fxml/my_profile.fxml")); Node profileOverlay = loader.load(); + // 3. Pass real data to controller MyProfileController controller = loader.getController(); - controller.setProfileData("Asal", "online", "Pass me that lovely little gun♡.", "@Whales_suicide", null); + controller.setProfileData(profileName, "online", bio, userId, imageUrl); - // Show the overlay on top of mainRoot + // 4. Show overlay MainController.getInstance().showOverlay(profileOverlay); } catch (IOException e) { e.printStackTrace(); + showAlert("Error", "Error opening profile", Alert.AlertType.ERROR); } } @@ -309,5 +337,17 @@ public class SidebarMenuController { } } + private void showAlert(String title, String message, Alert.AlertType type) { + Alert alert = new Alert(type); + alert.setTitle(title); + alert.setHeaderText(null); // no big header, just the message + alert.setContentText(message); + // optional: style it to fit your dark/light theme + if (alert.getDialogPane().getScene() != null) { + ThemeManager.getInstance().registerScene(alert.getDialogPane().getScene()); + } + + alert.showAndWait(); + } }