Chat page UI updated.

This commit is contained in:
Asal Lotfi
2025-09-05 17:15:29 +03:30
parent f4be87a6df
commit 7fe4a997fd
4 changed files with 77 additions and 48 deletions
@@ -71,15 +71,17 @@ public class ChatPageController {
@FXML private VBox blockedPane;
@FXML
private Button moreButton; // 3-dots button
private Button chatMoreButton; // 3-dots button
@FXML
private ImageView moreIcon;
@FXML
private ContextMenu moreMenu;
private ContextMenu chatMoreMenu;
@FXML
private MenuItem viewProfileItem;
@FXML
private MenuItem deleteChatItem;
@FXML
private MenuItem archiveItem;
// ===== send icon =====
@FXML
@@ -262,12 +264,12 @@ public class ChatPageController {
}
// Hook "More" button → show menu under it
if (moreButton != null) {
moreButton.setOnAction(e -> {
if (!moreMenu.isShowing()) {
moreMenu.show(moreButton, Side.BOTTOM, 0, 0);
if (chatMoreButton != null) {
chatMoreButton.setOnAction(e -> {
if (!chatMoreMenu.isShowing()) {
chatMoreMenu.show(chatMoreButton, Side.BOTTOM, 0, 0);
} else {
moreMenu.hide();
chatMoreMenu.hide();
}
});
}
@@ -283,6 +285,19 @@ public class ChatPageController {
// TODO: delete logic
});
if (archiveItem != null) {
archiveItem.setOnAction(e -> {
System.out.println("Toggling archive for chat " + chatName);
// TODO: backend call → toggleArchive(chatId, type)
// Also update text: "Archive chat" ↔ "Unarchive chat"
if ("Archive chat".equals(archiveItem.getText())) {
archiveItem.setText("Unarchive chat");
} else {
archiveItem.setText("Archive chat");
}
});
}
// Initial icon sync once the Scene is ready (stylesheet applied)
Platform.runLater(this::syncIconsWithTheme);
@@ -933,42 +948,34 @@ public class ChatPageController {
}
private void configureHeaderActions(ChatEntry entry) {
moreMenu.getItems().clear();
chatMoreMenu.getItems().clear();
switch (entry.getType().toLowerCase(Locale.ROOT)) {
case "private" -> {
MenuItem viewProfile = new MenuItem("View profile");
viewProfile.setOnAction(e -> openInfoScene(entry));
MenuItem deleteChat = new MenuItem("Delete chat");
deleteChat.setStyle("-fx-text-fill: red;");
deleteChat.setOnAction(e -> deleteChatButton(entry));
moreMenu.getItems().addAll(viewProfile, deleteChat);
archiveItem.setOnAction(e -> toggleArchive(entry));
viewProfileItem.setOnAction(e -> openInfoScene(entry));
deleteChatItem.setOnAction(e -> deleteChatButton(entry));
chatMoreMenu.getItems().addAll(archiveItem, viewProfileItem, deleteChatItem);
}
case "group" -> {
MenuItem viewGroup = new MenuItem("View group info");
viewGroup.setOnAction(e -> openInfoScene(entry));
MenuItem leaveGroup = new MenuItem("Leave group");
leaveGroup.setOnAction(e -> leaveGroupButton(entry));
moreMenu.getItems().addAll(viewGroup, leaveGroup);
chatMoreMenu.getItems().addAll(viewGroup, leaveGroup);
}
case "channel" -> {
MenuItem viewChannel = new MenuItem("View channel info");
viewChannel.setOnAction(e -> openInfoScene(entry));
MenuItem leaveChannel = new MenuItem("Leave channel");
leaveChannel.setOnAction(e -> leaveChannelButton(entry));
moreMenu.getItems().addAll(viewChannel, leaveChannel);
chatMoreMenu.getItems().addAll(viewChannel, leaveChannel);
}
}
// Clicking header (but not the 3-dot) → open info scene
// Header click opens info
chatHeader.setOnMouseClicked(e -> {
if (!moreButton.equals(e.getTarget())) {
if (!chatMoreButton.equals(e.getTarget())) {
openInfoScene(entry);
}
});
@@ -1138,6 +1145,19 @@ public class ChatPageController {
}
}
private void toggleArchive(ChatEntry entry) {
if (entry == null) return;
// Just toggle the text for now
if ("Archive chat".equals(archiveItem.getText())) {
archiveItem.setText("Unarchive chat");
System.out.println("Pretend: chat " + entry.getName() + " archived.");
} else {
archiveItem.setText("Archive chat");
System.out.println("Pretend: chat " + entry.getName() + " unarchived.");
}
}
private void loadMessages(ChatEntry entry) {
JSONObject req = new JSONObject();
req.put("action", "get_messages_UI");
@@ -2945,20 +2965,24 @@ public class ChatPageController {
String suffix = dark ? "_light.png" : "_dark.png";
if (attachmentIcon != null) attachmentIcon.setImage(loadIcon("attachment" + suffix));
if (sendIcon != null) sendIcon.setImage(loadIcon("send_cyan2.png"));
if (sendIcon != null) sendIcon.setImage(loadIcon("send_cyan2.png")); // always cyan
if (searchIcon != null) searchIcon.setImage(loadIcon("search" + suffix));
if (moreIcon != null) moreIcon.setImage(loadIcon("more" + suffix));
if (chatTitle != null) chatTitle.setStyle(dark ? "-fx-text-fill:#e8f1f8;" : "-fx-text-fill:#0f141a;");
if (chatStatus != null) chatStatus.setStyle(dark ? "-fx-text-fill:#8ea1b2;" : "-fx-text-fill:#7e8a97;");
// 👇 این خط قبلاً ممکن بود NPE بده
// === Context menu icons ===
if (archiveItem != null && archiveItem.getGraphic() instanceof ImageView iv) {
iv.setImage(loadIcon("archived_chats" + suffix));
}
if (viewProfileItem != null && viewProfileItem.getGraphic() instanceof ImageView iv) {
iv.setImage(loadIcon("view_profile" + suffix));
}
if (deleteChatItem != null && deleteChatItem.getGraphic() instanceof ImageView iv) {
iv.setImage(loadIcon("delete_red.png")); // stays red in both themes
}
}
// ChatPageController
@@ -2996,7 +3020,4 @@ public class ChatPageController {
}
}
}
@@ -30,8 +30,8 @@ public class UserInfoController {
@FXML private HBox usernameBlock;
@FXML private Label userId;
@FXML private Button moreButton;
@FXML private ContextMenu moreMenu;
@FXML private Button infoMoreButton;
@FXML private ContextMenu infoMoreMenu;
@FXML private MenuItem deleteChatItem;
@FXML private MenuItem blockItem;
@FXML private MenuItem unblockItem;
@@ -51,21 +51,21 @@ public class UserInfoController {
MainController.getInstance().closeOverlay(profileCard.getParent()));
// Show menu manually
moreButton.setOnAction(e -> {
if (moreMenu != null) {
moreMenu.show(moreButton, javafx.geometry.Side.BOTTOM, 0, 0);
infoMoreButton.setOnAction(e -> {
if (infoMoreMenu != null) {
infoMoreMenu.show(infoMoreButton, javafx.geometry.Side.BOTTOM, 0, 0);
}
});
// Hide menu when clicking outside
Platform.runLater(() -> {
if (moreButton.getScene() != null) {
moreButton.getScene().addEventFilter(
if (infoMoreButton.getScene() != null) {
infoMoreButton.getScene().addEventFilter(
javafx.scene.input.MouseEvent.MOUSE_PRESSED, ev -> {
if (moreMenu.isShowing()
&& !moreButton.localToScreen(moreButton.getBoundsInLocal())
if (infoMoreMenu.isShowing()
&& !infoMoreButton.localToScreen(infoMoreButton.getBoundsInLocal())
.contains(ev.getScreenX(), ev.getScreenY())) {
moreMenu.hide();
infoMoreMenu.hide();
}
}
);
@@ -197,7 +197,7 @@ public class UserInfoController {
moreIcon.setImage(loadImage(ICON_PATH + "more" + suffix));
bioIcon.setImage(loadImage(ICON_PATH + "bio" + suffix));
usernameIcon.setImage(loadImage(ICON_PATH + "user_id" + suffix));
usernameIcon.setImage(loadImage(ICON_PATH + "username" + suffix));
}
// --- helpers -------------------------------------------------------------
@@ -41,19 +41,27 @@
</Button>
<!-- More / overflow -->
<Button fx:id="moreButton" styleClass="icon-btn">
<Button fx:id="chatMoreButton" styleClass="icon-btn">
<graphic>
<ImageView fx:id="moreIcon" fitWidth="18" fitHeight="18" preserveRatio="true">
<image><Image url="@/org/to/telegramfinalproject/Icons/more_light.png"/></image>
</ImageView>
</graphic>
<contextMenu>
<ContextMenu fx:id="moreMenu">
<ContextMenu fx:id="chatMoreMenu">
<items>
<MenuItem fx:id="archiveItem" text="Archive chat">
<graphic>
<ImageView fitWidth="16" fitHeight="16" preserveRatio="true">
<image><Image url="@/org/to/telegramfinalproject/Icons/archived_chats_dark.png"/>
</image>
</ImageView>
</graphic>
</MenuItem>
<MenuItem fx:id="viewProfileItem" text="View profile">
<graphic>
<ImageView fitWidth="16" fitHeight="16" preserveRatio="true">
<image><Image url="@/org/to/telegramfinalproject/Icons/view_profile_light.png"/></image>
<image><Image url="@/org/to/telegramfinalproject/Icons/view_profile_dark.png"/></image>
</ImageView>
</graphic>
</MenuItem>
@@ -24,7 +24,7 @@
<Pane HBox.hgrow="ALWAYS"/> <!-- pushes buttons to right -->
<!-- More / overflow -->
<Button fx:id="moreButton" styleClass="icon-button">
<Button fx:id="infoMoreButton" styleClass="icon-button">
<graphic>
<ImageView fx:id="moreIcon" fitWidth="18" fitHeight="18" preserveRatio="true">
<image>
@@ -33,7 +33,7 @@
</ImageView>
</graphic>
<contextMenu>
<ContextMenu fx:id="moreMenu">
<ContextMenu fx:id="infoMoreMenu">
<items>
<MenuItem fx:id="deleteChatItem" text="Delete chat" style="-fx-text-fill: red;">
<graphic>
@@ -113,7 +113,7 @@
<ImageView fx:id="usernameIcon" fitWidth="16" fitHeight="16" preserveRatio="true"
styleClass="info-icon">
<image>
<Image url="@/org/to/telegramfinalproject/Icons/user_id_dark.png"/>
<Image url="@/org/to/telegramfinalproject/Icons/username_dark.png"/>
</image>
</ImageView>