diff --git a/src/main/java/org/to/telegramfinalproject/UI/ChatItemController.java b/src/main/java/org/to/telegramfinalproject/UI/ChatItemController.java index 286e59b..270cb94 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/ChatItemController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/ChatItemController.java @@ -1,12 +1,13 @@ package org.to.telegramfinalproject.UI; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; import javafx.scene.control.Label; +import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.layout.StackPane; +import javafx.scene.shape.Circle; -import java.io.IOException; +import java.util.Objects; public class ChatItemController { @@ -15,13 +16,74 @@ public class ChatItemController { @FXML private Label lastMessage; @FXML private Label chatTime; @FXML private Label unreadCount; + @FXML private StackPane systemAvatar; + @FXML private ImageView profileImageUser; + @FXML private ImageView profileImageSystem; + @FXML private Circle systemCircle; - public void setChatData(String name, String lastMsg, String time, int unread) { + // Default avatar resource path + private static final String DEFAULT_AVATAR = + "/org/to/telegramfinalproject/Avatars/default_avatar.png"; + + /** + * Set chat item data, including a profile image (or default). + * + * @param name Chat name + * @param lastMsg Last message text + * @param time Last message time + * @param unread Unread message count + * @param imageUrl Path/URL of profile image (can be null/empty) + */ + public void setChatData(String name, String lastMsg, String time, int unread, String imageUrl) { chatName.setText(name); lastMessage.setText(lastMsg); chatTime.setText(time); - unreadCount.setVisible(unread > 0); - unreadCount.setText(String.valueOf(unread)); + + // Unread count + if (unread > 0) { + unreadCount.setVisible(true); + unreadCount.setText(String.valueOf(unread)); + } else { + unreadCount.setVisible(false); + } + + // Reset all avatar states + profileImageUser.setVisible(false); + profileImageUser.setManaged(false); + systemAvatar.setVisible(false); + systemAvatar.setManaged(false); + + if ("Saved Messages".equals(name)) { + systemCircle.setFill(javafx.scene.paint.Color.web("#2ca4ff")); // Telegram blue + profileImageSystem.setImage(new Image( + Objects.requireNonNull(getClass().getResourceAsStream( + "/org/to/telegramfinalproject/Icons/saved_messages_light.png")) + )); + systemAvatar.setVisible(true); + systemAvatar.setManaged(true); + + } else if ("Archived Chats".equals(name)) { + systemCircle.setFill(javafx.scene.paint.Color.web("#808080")); // gray + profileImageSystem.setImage(new Image( + Objects.requireNonNull(getClass().getResourceAsStream( + "/org/to/telegramfinalproject/Icons/archived_chats_light.png")) + )); + systemAvatar.setVisible(true); + systemAvatar.setManaged(true); + + } else if (imageUrl != null && !imageUrl.isEmpty()) { + profileImageUser.setImage(new Image(imageUrl, true)); + profileImageUser.setVisible(true); + profileImageUser.setManaged(true); + + } else { + profileImageUser.setImage(new Image( + Objects.requireNonNull(getClass().getResourceAsStream( + "/org/to/telegramfinalproject/Icons/default_profile.png")) + )); + profileImageUser.setVisible(true); + profileImageUser.setManaged(true); + } } public void setUnread(int unread) { @@ -30,4 +92,4 @@ public class ChatItemController { unreadCount.setManaged(show); if (show) unreadCount.setText(String.valueOf(unread)); } -} \ No newline at end of file +} diff --git a/src/main/java/org/to/telegramfinalproject/UI/MainController.java b/src/main/java/org/to/telegramfinalproject/UI/MainController.java index 65b7ea5..9f6e80b 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/MainController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/MainController.java @@ -245,6 +245,10 @@ public class MainController { String preview = chat.getLastMessagePreview() == null ? "" : chat.getLastMessagePreview(); String timeText = formatChatTime(chat.getLastMessageTime()); + FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/Fxml/chat_item.fxml")); + Node chatItem = loader.load(); + ChatItemController controller = loader.getController(); + controller.setChatData(name, lastMsg, time, unread, "/org/to/telegramfinalproject/Avatars/default_profile.png"); cc.setChatData(chat.getName(), preview, timeText, chat.getUnreadCount()); item.setOnMouseClicked(e -> openChat(chat)); diff --git a/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java b/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java index 5c63f81..1098278 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java +++ b/src/main/java/org/to/telegramfinalproject/UI/SidebarMenuController.java @@ -48,7 +48,7 @@ public class SidebarMenuController { @FXML public void initialize() { // Load default profile image - Image profile = loadImage("/org/to/telegramfinalproject/Avatars/profile.png"); + Image profile = loadImage("/org/to/telegramfinalproject/Avatars/default_profile.png"); if (profile != null) profileImage.setImage(profile); setupButtonActions(); diff --git a/src/main/resources/org/to/telegramfinalproject/Avatars/profile.png b/src/main/resources/org/to/telegramfinalproject/Avatars/default_profile.png similarity index 100% rename from src/main/resources/org/to/telegramfinalproject/Avatars/profile.png rename to src/main/resources/org/to/telegramfinalproject/Avatars/default_profile.png diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css b/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css index cdb4235..8360317 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/dark_theme.css @@ -124,17 +124,17 @@ /* Input bubble */ .msg-input { - -fx-background-color: white; + -fx-background-color: #1b2b39; /* dark bluish background */ + -fx-control-inner-background: #1b2b39; + -fx-text-fill: #e8f1f8; + -fx-prompt-text-fill: #8ea1b2; -fx-background-radius: 18; -fx-padding: 6 12 6 12; - -fx-text-fill: #0f141a; - -fx-prompt-text-fill: #9aa6b2; -fx-border-color: transparent; - - -fx-control-inner-background: white; -fx-focus-color: transparent; -fx-faint-focus-color: transparent; } + .msg-input .scroll-pane { -fx-vbar-policy: never; -fx-hbar-policy: never; @@ -144,6 +144,7 @@ -fx-background-color: transparent; } +/* Context menu */ .context-menu { -fx-background-color: #1b2735; -fx-background-radius: 6; @@ -162,17 +163,134 @@ -fx-background-radius: 4; } -/* ===== Search panel ===== */ -.chat-search-pane { - -fx-background-color: #1b2735; /* matches sidebar */ + +/* ===== Search panel (dark) ===== */ +.chat-search-pane { -fx-background-color: #1b2735; } +.chat-search-bar { -fx-background-color: transparent; -fx-padding: 8 10; } +.search-placeholder { -fx-text-fill: #8ea1b2; -fx-font-size: 13px; } + +/* ===== Global search bar ===== */ +.global-search { + -fx-background-color: #1b2b39; + -fx-background-radius: 15; + -fx-text-fill: #e8f1f8; + -fx-prompt-text-fill: #8ea1b2; } -.chat-search-bar { +/* ===== Chat list ===== */ +.chat-list { -fx-background-color: #0f1c26; } +.chat-list .label { -fx-text-fill: #e8f1f8; } + +/* ===== Sidebar / Left Pane ===== */ +.sidebar-pane { + -fx-background-color: #1b2735; /* Telegram dark */ +} + +.sidebar-topbar { -fx-background-color: transparent; - -fx-padding: 8 10; } -.search-placeholder { +.menu-btn { + -fx-background-color: transparent; + -fx-cursor: hand; +} + +.global-search { + -fx-background-color: #2a3a4a; + -fx-background-radius: 15; + -fx-text-fill: #e8f1f8; + -fx-prompt-text-fill: #8ea1b2; + -fx-border-color: transparent; +} + +/* Chat list */ +.chat-list { + -fx-background-color: #0f1c26; +} + +.chat-scroll { + -fx-background-color: transparent; +} + +/* ===== Search Panel ===== */ +.chat-search-pane { + -fx-background-color: #1b2735; +} + +.search-label { -fx-text-fill: #8ea1b2; - -fx-font-size: 13px; + -fx-font-size: 11px; + -fx-padding: 10 0 5 10; +} + +.search-separator { + -fx-background-color: #2e3948; +} + +.search-scope-bar { + -fx-padding: 8 10; + -fx-border-color: #2e3948; + -fx-border-width: 0 0 1 0; +} + +.search-scope { + -fx-text-fill: #8ea1b2; + -fx-font-size: 11px; +} + +.close-btn { + -fx-background-color: transparent; + -fx-cursor: hand; + -fx-text-fill: #e8f1f8; +} + +/* ===== Right Chat Panel ===== */ +.chat-display { + -fx-background-color: #0f1c26; +} + +/* ===== Overlay ===== */ +.overlay { + -fx-background-color: rgba(0,0,0,0.3); +} + +/* Chat item container */ +.chat-item { + -fx-background-color: #0f1c26; + -fx-padding: 10; + -fx-border-color: #2e3948; + -fx-border-width: 0 0 1 0; +} + +.chat-item:hover { + -fx-background-color: #223446; + -fx-cursor: hand; +} + +/* Chat details */ +.chat-name { + -fx-font-size: 14; + -fx-font-weight: bold; + -fx-text-fill: #e8f1f8; +} + +.chat-last-message { + -fx-text-fill: #8ea1b2; + -fx-font-size: 12; +} + +/* Time + unread */ +.chat-time { + -fx-font-size: 11; + -fx-text-fill: #8ea1b2; +} + +/* Unread counter (same for both modes) */ +.unread-count { + -fx-background-color: #2196f3; /* blue bubble */ + -fx-text-fill: white !important; /* always white */ + -fx-font-size: 10px; + -fx-padding: 3 6; + -fx-background-radius: 10; + -fx-font-weight: bold; } diff --git a/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css b/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css index c98942f..f2b261d 100644 --- a/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css +++ b/src/main/resources/org/to/telegramfinalproject/CSS/light_theme.css @@ -51,12 +51,12 @@ -fx-text-fill: black; } -/* Thin Telegram-like SplitPane divider (light) */ +/* SplitPane divider */ .split-pane:horizontal > .split-pane-divider { - -fx-background-color: transparent; /* no big solid block */ - -fx-border-color: #cccccc; /* the visible thin line */ - -fx-border-width: 0 1px 0 1px; /* 1px vertical line */ - -fx-padding: 0 0 0 0.5px; /* big invisible hitbox for the mouse */ + -fx-background-color: transparent; + -fx-border-color: #cccccc; + -fx-border-width: 0 1px 0 1px; + -fx-padding: 0 0 0 0.5px; } .placeholder-label { @@ -144,6 +144,7 @@ -fx-background-color: transparent; } +/* Context menu */ .context-menu { -fx-background-color: white; -fx-background-radius: 6; @@ -162,17 +163,133 @@ -fx-background-radius: 4; } -/* ===== Search panel ===== */ + +/* ===== Search panel (light) ===== */ +.chat-search-pane { -fx-background-color: #f5f5f5; } +.chat-search-bar { -fx-background-color: transparent; -fx-padding: 8 10; } +.search-placeholder { -fx-text-fill: #7e8a97; -fx-font-size: 13px; } + +/* ===== Global search bar ===== */ +.global-search { + -fx-background-color: #f5f5f5; + -fx-background-radius: 15; + -fx-text-fill: #0f141a; + -fx-prompt-text-fill: #9aa6b2; +} + +/* ===== Chat list ===== */ +.chat-list { -fx-background-color: #ffffff; } +.chat-list .label { -fx-text-fill: #0f141a; } + +/* ===== Sidebar / Left Pane ===== */ +.sidebar-pane { + -fx-background-color: #ffffff; +} + +.sidebar-topbar { + -fx-background-color: transparent; +} + +.menu-btn { + -fx-background-color: transparent; + -fx-cursor: hand; +} + +.global-search { + -fx-background-color: #f5f5f5; + -fx-background-radius: 15; + -fx-text-fill: #0f141a; + -fx-prompt-text-fill: #7e8a97; + -fx-border-color: transparent; +} + +/* Chat list */ +.chat-list { + -fx-background-color: transparent; +} + +.chat-scroll { + -fx-background-color: transparent; +} + +/* ===== Search Panel ===== */ .chat-search-pane { -fx-background-color: #f5f5f5; } -.chat-search-bar { - -fx-background-color: transparent; - -fx-padding: 8 10; +.search-label { + -fx-text-fill: #7e8a97; + -fx-font-size: 11px; + -fx-padding: 10 0 5 10; } -.search-placeholder { +.search-separator { + -fx-background-color: #e6e6e6; +} + +.search-scope-bar { + -fx-padding: 8 10; + -fx-border-color: #e6e6e6; + -fx-border-width: 0 0 1 0; +} + +.search-scope { -fx-text-fill: #7e8a97; - -fx-font-size: 13px; + -fx-font-size: 11px; +} + +.close-btn { + -fx-background-color: transparent; + -fx-cursor: hand; +} + +/* ===== Right Chat Panel ===== */ +.chat-display { + -fx-background-color: #fafafa; +} + +/* ===== Overlay ===== */ +.overlay { + -fx-background-color: rgba(0,0,0,0.3); +} + +/* Chat item container */ +.chat-item { + -fx-background-color: #ffffff; + -fx-padding: 10; + -fx-border-color: #ddd; + -fx-border-width: 0 0 1 0; +} + +.chat-item:hover { + -fx-background-color: #f5f5f5; + -fx-cursor: hand; +} + +/* Chat details */ +.chat-name { + -fx-font-size: 14; + -fx-font-weight: bold; + -fx-text-fill: #0f141a; +} + +.chat-last-message { + -fx-text-fill: #7e8a97; + -fx-font-size: 12; +} + +/* Time + unread */ +.chat-time { + -fx-font-size: 11; + -fx-text-fill: #7e8a97; +} + +/* Unread counter (same for both modes) */ +.unread-count { + -fx-background-color: #2196f3; /* blue bubble */ + -fx-text-fill: white !important; /* always white */ + -fx-font-size: 10px; + -fx-padding: 3 6; + -fx-background-radius: 10; + -fx-font-weight: bold; } diff --git a/src/main/resources/org/to/telegramfinalproject/Fxml/chat_item.fxml b/src/main/resources/org/to/telegramfinalproject/Fxml/chat_item.fxml index 2d94145..6846611 100644 --- a/src/main/resources/org/to/telegramfinalproject/Fxml/chat_item.fxml +++ b/src/main/resources/org/to/telegramfinalproject/Fxml/chat_item.fxml @@ -5,26 +5,50 @@ + + styleClass="chat-item"> - - + + + + + + + + + + + + + + - - - \ No newline at end of file + diff --git a/src/main/resources/org/to/telegramfinalproject/Fxml/main.fxml b/src/main/resources/org/to/telegramfinalproject/Fxml/main.fxml index 0461623..d6db77f 100644 --- a/src/main/resources/org/to/telegramfinalproject/Fxml/main.fxml +++ b/src/main/resources/org/to/telegramfinalproject/Fxml/main.fxml @@ -21,18 +21,19 @@ - + - + -