Edit profile and username/Password from setting
This commit is contained in:
@@ -4,13 +4,16 @@ import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.json.JSONObject;
|
||||
import org.to.telegramfinalproject.Client.ActionHandler;
|
||||
import org.to.telegramfinalproject.Client.Session;
|
||||
|
||||
public class ChangeCredentialsController {
|
||||
|
||||
@FXML private VBox credentialsCard;
|
||||
@FXML private Pane overlayBackground;
|
||||
|
||||
@FXML private TextField usernameField;
|
||||
@FXML private Label usernameLabel;
|
||||
|
||||
@@ -31,22 +34,21 @@ public class ChangeCredentialsController {
|
||||
private boolean passwordVisible = false;
|
||||
private boolean confirmVisible = false;
|
||||
|
||||
// ↓↓↓ متدی که از CheckPasswordController مقدار میگیرد
|
||||
private String currentPassword;
|
||||
public void setCurrentPassword(String p) { this.currentPassword = p; }
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
// Toggle password visibility
|
||||
togglePasswordBtn.setOnAction(e -> togglePasswordVisibility());
|
||||
toggleConfirmBtn.setOnAction(e -> toggleConfirmVisibility());
|
||||
|
||||
saveButton.setOnAction(e -> validateAndSave());
|
||||
|
||||
// Close the overlay
|
||||
closeButton.setOnAction(e ->
|
||||
MainController.getInstance().closeOverlay(credentialsCard.getParent()));
|
||||
cancelButton.setOnAction(e ->
|
||||
MainController.getInstance().closeOverlay(credentialsCard.getParent()));
|
||||
overlayBackground.setOnMouseClicked(e ->
|
||||
MainController.getInstance().closeOverlay(credentialsCard.getParent())
|
||||
);
|
||||
// «ذخیره و بستن» مثل ادیت پروفایل
|
||||
saveButton.setOnAction(e -> saveAndClose());
|
||||
closeButton.setOnAction(e -> saveAndClose());
|
||||
cancelButton.setOnAction(e -> saveAndClose());
|
||||
overlayBackground.setOnMouseClicked(e -> saveAndClose());
|
||||
|
||||
// Reset error when typing
|
||||
usernameField.textProperty().addListener((obs, o, n) -> removeError(usernameField, usernameLabel));
|
||||
@@ -73,10 +75,19 @@ public class ChangeCredentialsController {
|
||||
removeError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||
});
|
||||
|
||||
// Auto_focus password field when overlay opens
|
||||
Platform.runLater(() -> usernameField.requestFocus());
|
||||
}
|
||||
|
||||
// ← از CheckPasswordController بلافاصله بعد از load صدا بزن
|
||||
public void prefillFromSession() {
|
||||
var u = Session.currentUser;
|
||||
if (u == null) return;
|
||||
String handle = u.optString("user_id",
|
||||
u.optString("username",
|
||||
u.optString("display_id","")));
|
||||
usernameField.setText(handle);
|
||||
}
|
||||
|
||||
private void togglePasswordVisibility() {
|
||||
passwordVisible = !passwordVisible;
|
||||
visiblePasswordField.setText(passwordField.getText());
|
||||
@@ -101,47 +112,68 @@ public class ChangeCredentialsController {
|
||||
toggleConfirmBtn.setText(confirmVisible ? "👁" : "👁");
|
||||
}
|
||||
|
||||
private void validateAndSave() {
|
||||
boolean hasError = false;
|
||||
// ارسال تغییرات (در صورت پر بودن/تغییر) و بستن
|
||||
private void saveAndClose() {
|
||||
boolean anyError = false;
|
||||
boolean sentSomething = false;
|
||||
|
||||
// --- Username check ---
|
||||
if (usernameField.getText().trim().isEmpty()) {
|
||||
addError(usernameField, usernameLabel);
|
||||
hasError = true;
|
||||
} else {
|
||||
removeError(usernameField, usernameLabel);
|
||||
// 1) یوزرنیم
|
||||
var cu = Session.currentUser;
|
||||
String oldUsername = cu != null ? cu.optString("user_id",
|
||||
cu.optString("username",
|
||||
cu.optString("display_id",""))) : "";
|
||||
|
||||
String newUsername = usernameField.getText().trim();
|
||||
if (!newUsername.isEmpty() && !newUsername.equals(oldUsername)) {
|
||||
sentSomething = true;
|
||||
|
||||
JSONObject req = new JSONObject()
|
||||
.put("action", "update_username")
|
||||
.put("current_password", currentPassword) // با اینکه سرور فعلاً چک نمیکند، میفرستیم
|
||||
.put("new_username", newUsername);
|
||||
|
||||
JSONObject resp = ActionHandler.sendWithResponse(req);
|
||||
if (resp == null || !"success".equalsIgnoreCase(resp.optString("status"))) {
|
||||
anyError = true;
|
||||
showError("Changing username failed",
|
||||
resp != null ? resp.optString("message","Unknown error") : "No response");
|
||||
} else {
|
||||
if (cu != null) cu.put("user_id", newUsername);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Password check ---
|
||||
String pwd = passwordVisible ? visiblePasswordField.getText().trim() : passwordField.getText().trim();
|
||||
if (pwd.isEmpty()) {
|
||||
addError(passwordField, passwordLabel);
|
||||
addError(visiblePasswordField, passwordLabel);
|
||||
hasError = true;
|
||||
} else {
|
||||
removeError(passwordField, passwordLabel);
|
||||
removeError(visiblePasswordField, passwordLabel);
|
||||
// 2) پسورد
|
||||
String newPwd = (passwordVisible ? visiblePasswordField.getText() : passwordField.getText()).trim();
|
||||
String confirm = (confirmVisible ? visibleConfirmPasswordField.getText() : confirmPasswordField.getText()).trim();
|
||||
|
||||
if (!newPwd.isEmpty()) {
|
||||
if (confirm.isEmpty() || !confirm.equals(newPwd)) {
|
||||
addError(confirmPasswordField, confirmPasswordLabel);
|
||||
addError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||
return; // نذار بسته شه تا کاربر درست کنه
|
||||
}
|
||||
|
||||
sentSomething = true;
|
||||
|
||||
JSONObject req = new JSONObject()
|
||||
.put("action", "update_password")
|
||||
.put("current_password", currentPassword)
|
||||
.put("new_password", newPwd);
|
||||
|
||||
JSONObject resp = ActionHandler.sendWithResponse(req);
|
||||
if (resp == null || !"success".equalsIgnoreCase(resp.optString("status"))) {
|
||||
anyError = true;
|
||||
showError("Changing password failed",
|
||||
resp != null ? resp.optString("message","Unknown error") : "No response");
|
||||
}
|
||||
}
|
||||
|
||||
// --- Confirm password check ---
|
||||
String confirm = confirmVisible ? visibleConfirmPasswordField.getText().trim() : confirmPasswordField.getText().trim();
|
||||
if (confirm.isEmpty()) {
|
||||
addError(confirmPasswordField, confirmPasswordLabel);
|
||||
addError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||
hasError = true;
|
||||
} else if (!confirm.equals(pwd)) {
|
||||
addError(confirmPasswordField, confirmPasswordLabel);
|
||||
addError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||
hasError = true;
|
||||
} else {
|
||||
removeError(confirmPasswordField, confirmPasswordLabel);
|
||||
removeError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||
// اگر چیزی نفرستادیم یا همهچیز OK بود → ببند و رفرش Settings
|
||||
if (!sentSomething || !anyError) {
|
||||
var sc = SettingsController.getInstance();
|
||||
if (sc != null) sc.populateFromSession();
|
||||
MainController.getInstance().closeOverlay(credentialsCard.getParent());
|
||||
}
|
||||
|
||||
if (hasError) return;
|
||||
|
||||
// TODO: send to server
|
||||
System.out.println("Saving new credentials...");
|
||||
}
|
||||
|
||||
private void addError(TextField field, Label label) {
|
||||
@@ -157,4 +189,15 @@ public class ChangeCredentialsController {
|
||||
field.getStyleClass().remove("error-input");
|
||||
label.getStyleClass().remove("error-label");
|
||||
}
|
||||
|
||||
private void showError(String title, String msg) {
|
||||
Alert a = new Alert(Alert.AlertType.ERROR);
|
||||
a.setTitle(title);
|
||||
a.setHeaderText(null);
|
||||
a.setContentText(msg);
|
||||
if (a.getDialogPane().getScene()!=null) {
|
||||
ThemeManager.getInstance().registerScene(a.getDialogPane().getScene());
|
||||
}
|
||||
a.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,26 +98,38 @@ public class CheckPasswordController {
|
||||
}
|
||||
|
||||
private void validatePassword() {
|
||||
String entered = passwordField.getText().trim();
|
||||
String correct = "12345"; // demo only
|
||||
String entered = (passwordVisible ? visiblePasswordField.getText() : passwordField.getText()).trim();
|
||||
if (entered.isEmpty()) {
|
||||
// استایل خطا مثل قبل
|
||||
if (!passwordField.getStyleClass().contains("error"))
|
||||
passwordField.getStyleClass().add("error");
|
||||
if (!visiblePasswordField.getStyleClass().contains("error"))
|
||||
visiblePasswordField.getStyleClass().add("error");
|
||||
if (!passwordLabel.getStyleClass().contains("error"))
|
||||
passwordLabel.getStyleClass().add("error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (entered.equals(correct)) {
|
||||
// Success → reset error styles
|
||||
// تماس با سرور
|
||||
org.json.JSONObject req = new org.json.JSONObject()
|
||||
.put("action", "verify_password")
|
||||
.put("current_password", entered);
|
||||
|
||||
org.json.JSONObject resp = org.to.telegramfinalproject.Client.ActionHandler.sendWithResponse(req);
|
||||
boolean ok = (resp != null && "success".equalsIgnoreCase(resp.optString("status")));
|
||||
|
||||
if (ok) {
|
||||
// پاک کردن خطاها
|
||||
passwordField.getStyleClass().remove("error");
|
||||
visiblePasswordField.getStyleClass().remove("error");
|
||||
passwordLabel.getStyleClass().remove("error");
|
||||
|
||||
// Go to the next scene
|
||||
openChangeCredentials();
|
||||
|
||||
openChangeCredentials(entered); // ← پسورد فعلی را پاس بده
|
||||
} else {
|
||||
// Error → add error styles
|
||||
if (!passwordField.getStyleClass().contains("error"))
|
||||
passwordField.getStyleClass().add("error");
|
||||
|
||||
if (!visiblePasswordField.getStyleClass().contains("error"))
|
||||
visiblePasswordField.getStyleClass().add("error");
|
||||
|
||||
if (!passwordLabel.getStyleClass().contains("error"))
|
||||
passwordLabel.getStyleClass().add("error");
|
||||
}
|
||||
@@ -146,15 +158,17 @@ public class CheckPasswordController {
|
||||
backButton.setGraphic(icon);
|
||||
}
|
||||
|
||||
private void openChangeCredentials() {
|
||||
private void openChangeCredentials(String currentPassword) {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource(
|
||||
"/org/to/telegramfinalproject/Fxml/change_credentials.fxml"));
|
||||
Node overlay = loader.load();
|
||||
|
||||
// Show new overlay
|
||||
MainController.getInstance().showOverlay(overlay);
|
||||
ChangeCredentialsController c = loader.getController();
|
||||
c.setCurrentPassword(currentPassword); // ← مهم
|
||||
c.prefillFromSession(); // ← پیشپر کردن
|
||||
|
||||
MainController.getInstance().showOverlay(overlay);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -49,6 +49,13 @@ public class EditProfileController {
|
||||
@FXML private TextField bioField;
|
||||
@FXML private TextField usernameField;
|
||||
|
||||
// EditProfileController.java
|
||||
private SettingsController parentSettings;
|
||||
public void setParentSettings(SettingsController sc) {
|
||||
this.parentSettings = sc;
|
||||
}
|
||||
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
backButton.setGraphic(new ImageView(
|
||||
@@ -56,19 +63,34 @@ public class EditProfileController {
|
||||
));
|
||||
|
||||
// close on background click
|
||||
// overlayBackground.setOnMouseClicked(e -> {
|
||||
// saveChangesAndClose();
|
||||
// closeEdit();
|
||||
// });
|
||||
//
|
||||
// closeButton.setOnAction(e -> {
|
||||
// saveChangesAndClose();
|
||||
// closeEdit();
|
||||
// });
|
||||
//
|
||||
// backButton.setOnAction(e -> {
|
||||
// saveChangesAndClose();
|
||||
// MainController.getInstance().goBack(overlayBackground);
|
||||
// });
|
||||
|
||||
overlayBackground.setOnMouseClicked(e -> {
|
||||
saveChangesAndClose();
|
||||
closeEdit();
|
||||
closeEdit(); // ← همینه
|
||||
});
|
||||
|
||||
closeButton.setOnAction(e -> {
|
||||
saveChangesAndClose();
|
||||
closeEdit();
|
||||
closeEdit(); // ← همینه
|
||||
});
|
||||
|
||||
backButton.setOnAction(e -> {
|
||||
saveChangesAndClose();
|
||||
MainController.getInstance().goBack(overlayBackground);
|
||||
closeEdit(); // ← قبلاً goBack بود
|
||||
});
|
||||
|
||||
// Load your camera icon image (white camera icon for visibility)
|
||||
@@ -122,7 +144,9 @@ public class EditProfileController {
|
||||
|
||||
private void closeEdit() {
|
||||
//MainController.getInstance().closeOverlay(editCard.getParent());
|
||||
MainController.getInstance().goBack(overlayBackground);
|
||||
// MainController.getInstance().goBack(overlayBackground);
|
||||
MainController.getInstance().closeOverlay(editCard.getParent());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -233,21 +257,33 @@ public class EditProfileController {
|
||||
}
|
||||
|
||||
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")
|
||||
// 1) اگر صفحهی MyProfile باز است
|
||||
var mp = MyProfileController.getInstance();
|
||||
if (mp != null) {
|
||||
mp.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")
|
||||
);
|
||||
}
|
||||
|
||||
// 2) خودِ کارت Settings را فوراً از Session ریفرش کن
|
||||
if (parentSettings != null) {
|
||||
parentSettings.populateFromSession();
|
||||
}
|
||||
|
||||
);
|
||||
// MainController mc = MainController.getInstance();
|
||||
// 3) سایدبار بالایی (اسم/آواتار خود کاربر) اگر داری
|
||||
MainController.getInstance().refreshSidebarUserFromSession();
|
||||
MainController.getInstance().goBack(overlayBackground);
|
||||
|
||||
// MainController.getInstance().closeOverlay(bioField.getParent().getParent());
|
||||
// 4) بستن اورلی ادیت
|
||||
// MainController.getInstance().goBack(overlayBackground);
|
||||
MainController.getInstance().closeOverlay(editCard.getParent());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void showAlert(String title, String message, Alert.AlertType type) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import javafx.scene.control.*;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.shape.Circle;
|
||||
|
||||
@@ -33,17 +32,25 @@ public class SettingsController {
|
||||
|
||||
private static final String ICON_PATH = "/org/to/telegramfinalproject/Icons/";
|
||||
|
||||
private Image cachedAvatar;
|
||||
private String cachedName = "";
|
||||
private String cachedUsername = "";
|
||||
private String cachedStatus = "";
|
||||
private String cachedBio = "";
|
||||
|
||||
private static String nz(String s){ return s==null? "": s.trim(); }
|
||||
private static boolean hasVal(String s){ return s!=null && !s.trim().isEmpty() && !"null".equalsIgnoreCase(s); }
|
||||
|
||||
private static SettingsController instance;
|
||||
public static SettingsController getInstance() { return instance; }
|
||||
@FXML
|
||||
public void initialize() {
|
||||
instance = this;
|
||||
|
||||
editProfileItem.setOnAction(e -> openEditProfile());
|
||||
logoutItem.setOnAction(e -> System.out.println("Log Out clicked"));
|
||||
|
||||
// Example data – load from DB or user session later
|
||||
profileName.setText("Asal");
|
||||
profileId.setText("@Whales_suicide");
|
||||
profileImage.setImage(new Image(
|
||||
getClass().getResourceAsStream("/org/to/telegramfinalproject/Avatars/default_user_profile.png")
|
||||
));
|
||||
populateFromSession();
|
||||
|
||||
// Make it circular
|
||||
Circle clip = new Circle(48, 28, 38); // centerX, centerY, radius
|
||||
@@ -104,19 +111,20 @@ public class SettingsController {
|
||||
|
||||
EditProfileController controller = loader.getController();
|
||||
controller.setProfileData(
|
||||
profileName.getText(),
|
||||
"online",
|
||||
"Pass me that lovely little gun♡.",
|
||||
"@Whales_suicide",
|
||||
profileImage.getImage()
|
||||
cachedName,
|
||||
cachedStatus,
|
||||
cachedBio,
|
||||
cachedUsername,
|
||||
cachedAvatar
|
||||
);
|
||||
|
||||
controller.setParentSettings(this);
|
||||
MainController.getInstance().showOverlay(editOverlay);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateEditIcon(boolean darkMode) {
|
||||
String editPath = darkMode
|
||||
? "/org/to/telegramfinalproject/Icons/edit_light.png"
|
||||
@@ -169,4 +177,57 @@ public class SettingsController {
|
||||
}
|
||||
return new Image(res.toExternalForm());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void populateFromSession() {
|
||||
var u = org.to.telegramfinalproject.Client.Session.currentUser;
|
||||
if (u == null) return;
|
||||
|
||||
// نام
|
||||
String name = nz(u.optString("profile_name",
|
||||
u.optString("name",
|
||||
u.optString("first_name",""))));
|
||||
|
||||
// یوزرنیم/آیدی نمایشی
|
||||
String handle = nz(u.optString("username",
|
||||
u.optString("display_id",
|
||||
u.optString("user_name",""))));
|
||||
// وضعیت
|
||||
String status = u.optBoolean("online", false) ? "online" : "online";
|
||||
String lastSeen = nz(u.optString("last_seen", ""));
|
||||
if (!u.optBoolean("online", false) && hasVal(lastSeen)) status = "online"; // ساده
|
||||
|
||||
// بیو (اگر داری)
|
||||
String bio = nz(u.optString("bio",""));
|
||||
|
||||
// آواتار
|
||||
Image avatar = null;
|
||||
String imageUrl = nz(u.optString("image_url",""));
|
||||
if (hasVal(imageUrl)) {
|
||||
try { avatar = org.to.telegramfinalproject.Client.AvatarLocalResolver.load(imageUrl); }
|
||||
catch (Exception ignore) {}
|
||||
}
|
||||
if (avatar == null) {
|
||||
avatar = new Image(getClass().getResourceAsStream(
|
||||
"/org/to/telegramfinalproject/Avatars/default_user_profile.png"));
|
||||
}
|
||||
|
||||
// کش محلی برای استفاده در صفحهی ویرایش
|
||||
cachedName = hasVal(name) ? name : "User";
|
||||
cachedUsername = hasVal(handle) ? handle : "";
|
||||
cachedStatus = status;
|
||||
cachedBio = bio;
|
||||
cachedAvatar = avatar;
|
||||
|
||||
// ست کردن در UI
|
||||
profileName.setText(cachedName);
|
||||
profileId.setText(cachedUsername);
|
||||
profileImage.setImage(cachedAvatar);
|
||||
|
||||
// گرد کردن تصویر (با توجه به اندازهی واقعی)
|
||||
Circle clip = new Circle(38, 38, 38); // centerX, centerY, radius
|
||||
profileImage.setClip(clip);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user