Last seen & profile in chat fixed.
This commit is contained in:
@@ -2778,6 +2778,35 @@ public class ClientHandler implements Runnable {
|
||||
break;
|
||||
}
|
||||
|
||||
case "get_other_user_status": {
|
||||
try {
|
||||
String userIdStr = requestJson.getString("user_id");
|
||||
UUID user_id = UUID.fromString(userIdStr);
|
||||
|
||||
String lastSeenStr = userDatabase.getLastSeen(user_id); // returns ISO string?
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
if (lastSeenStr != null && !"Unknown".equals(lastSeenStr)) {
|
||||
// parse string to time
|
||||
LocalDateTime lastSeen = LocalDateTime.parse(lastSeenStr);
|
||||
long diffMillis = java.time.Duration.between(lastSeen, LocalDateTime.now()).toMillis();
|
||||
|
||||
boolean online = diffMillis <= 120_000;
|
||||
|
||||
data.put("online", online);
|
||||
data.put("last_seen", lastSeen.toString());
|
||||
|
||||
response = new ResponseModel("success", "Status fetched.", data);
|
||||
} else {
|
||||
response = new ResponseModel("error", "User not found.");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
response = new ResponseModel("error", "Failed to fetch status.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
response = new ResponseModel("error", "Unknown action: " + action);
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChatPageController {
|
||||
@@ -109,12 +110,6 @@ public class ChatPageController {
|
||||
}
|
||||
}
|
||||
|
||||
//Time formatter for messages
|
||||
|
||||
// private static final DateTimeFormatter FMT_HHMM = DateTimeFormatter.ofPattern("HH:mm");
|
||||
// private static final DateTimeFormatter FMT_DATE_TIME = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
|
||||
// private static final String YESTERDAY_LABEL = "Yesterday";
|
||||
|
||||
private static String str(org.json.JSONObject j, String k) {
|
||||
try { return (j.has(k) && !j.isNull(k)) ? j.getString(k) : ""; } catch (Exception e) { return ""; }
|
||||
}
|
||||
@@ -306,31 +301,31 @@ public class ChatPageController {
|
||||
MainController.getInstance().showSearchPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by main controller when opening a chat.
|
||||
*/
|
||||
public void setChat(String chatName, String avatarPath) {
|
||||
this.chatName = chatName;
|
||||
|
||||
// Header text (if present)
|
||||
if (chatTitle != null) chatTitle.setText(chatName);
|
||||
if (chatStatus != null) chatStatus.setText("last seen recently"); // or live status
|
||||
|
||||
// Load avatar if provided
|
||||
if (userAvatar != null && avatarPath != null) {
|
||||
try {
|
||||
Image avatarImg = new Image(getClass().getResourceAsStream(avatarPath));
|
||||
userAvatar.setImage(avatarImg);
|
||||
Circle clip = new Circle(18, 18, 18); // x, y, radius
|
||||
userAvatar.setClip(clip);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Could not load avatar: " + avatarPath);
|
||||
}
|
||||
}
|
||||
|
||||
addSystemMessage("Chat with " + chatName + " opened.");
|
||||
Platform.runLater(() -> messageInput.requestFocus());
|
||||
}
|
||||
// /**
|
||||
// * Called by main controller when opening a chat.
|
||||
// */
|
||||
// public void setChat(String chatName, String avatarPath) {
|
||||
// this.chatName = chatName;
|
||||
//
|
||||
// // Header text (if present)
|
||||
// if (chatTitle != null) chatTitle.setText(chatName);
|
||||
// if (chatStatus != null) chatStatus.setText("last seen recently"); // or live status
|
||||
//
|
||||
// // Load avatar if provided
|
||||
// if (userAvatar != null && avatarPath != null) {
|
||||
// try {
|
||||
// Image avatarImg = new Image(getClass().getResourceAsStream(avatarPath));
|
||||
// userAvatar.setImage(avatarImg);
|
||||
// Circle clip = new Circle(18, 18, 18); // x, y, radius
|
||||
// userAvatar.setClip(clip);
|
||||
// } catch (Exception e) {
|
||||
// System.err.println("Could not load avatar: " + avatarPath);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// addSystemMessage("Chat with " + chatName + " opened.");
|
||||
// Platform.runLater(() -> messageInput.requestFocus());
|
||||
// }
|
||||
|
||||
// ----- actions -----
|
||||
|
||||
@@ -467,24 +462,24 @@ public class ChatPageController {
|
||||
|
||||
// ----- UI helpers -----
|
||||
|
||||
/**
|
||||
* Add a normal message bubble (very simple for now).
|
||||
*/
|
||||
public void addMessage(String sender, String content) {
|
||||
Label msg = new Label(sender + ": " + content);
|
||||
msg.setWrapText(true);
|
||||
|
||||
boolean dark = themeManager.isDarkMode();
|
||||
String bubbleColor = dark ? "#20405a" : "#4fa8f0";
|
||||
String textColor = dark ? "#e8f1f8" : "#0f141a";
|
||||
msg.setStyle(
|
||||
"-fx-background-color: " + bubbleColor + ";" +
|
||||
"-fx-text-fill: " + textColor + ";" +
|
||||
"-fx-padding: 6 10; -fx-background-radius: 10;"
|
||||
);
|
||||
|
||||
messageContainer.getChildren().add(msg);
|
||||
}
|
||||
// /**
|
||||
// * Add a normal message bubble (very simple for now).
|
||||
// */
|
||||
// public void addMessage(String sender, String content) {
|
||||
// Label msg = new Label(sender + ": " + content);
|
||||
// msg.setWrapText(true);
|
||||
//
|
||||
// boolean dark = themeManager.isDarkMode();
|
||||
// String bubbleColor = dark ? "#20405a" : "#4fa8f0";
|
||||
// String textColor = dark ? "#e8f1f8" : "#0f141a";
|
||||
// msg.setStyle(
|
||||
// "-fx-background-color: " + bubbleColor + ";" +
|
||||
// "-fx-text-fill: " + textColor + ";" +
|
||||
// "-fx-padding: 6 10; -fx-background-radius: 10;"
|
||||
// );
|
||||
//
|
||||
// messageContainer.getChildren().add(msg);
|
||||
// }
|
||||
|
||||
private void addSystemMessage(String content) {
|
||||
Label sys = new Label(content);
|
||||
@@ -539,20 +534,68 @@ public class ChatPageController {
|
||||
public void showChat(ChatEntry entry) {
|
||||
this.currentChat = entry;
|
||||
|
||||
// Header
|
||||
chatTitle.setText(entry.getName());
|
||||
chatStatus.setText("");
|
||||
|
||||
// Default avatar
|
||||
if (entry.getImageUrl() != null && !entry.getImageUrl().isEmpty()) {
|
||||
try {
|
||||
userAvatar.setImage(new Image(entry.getImageUrl() != null ? entry.getImageUrl() : "/org/to/telegramfinalproject/Avatars/default_user_profile.png"));
|
||||
userAvatar.setClip(new Circle(18, 18, 18));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
userAvatar.setImage(new Image(entry.getImageUrl()));
|
||||
} else if ("channel".equals(entry.getType())) {
|
||||
userAvatar.setImage(new Image(
|
||||
Objects.requireNonNull(getClass().getResourceAsStream(
|
||||
"/org/to/telegramfinalproject/Avatars/default_channel_profile.png"))
|
||||
));
|
||||
} else if ("group".equals(entry.getType())) {
|
||||
userAvatar.setImage(new Image(
|
||||
Objects.requireNonNull(getClass().getResourceAsStream(
|
||||
"/org/to/telegramfinalproject/Avatars/default_group_profile.png"))
|
||||
));
|
||||
} else {
|
||||
userAvatar.setImage(new Image(
|
||||
Objects.requireNonNull(getClass().getResourceAsStream(
|
||||
"/org/to/telegramfinalproject/Avatars/default_user_profile.png"))
|
||||
));
|
||||
}
|
||||
userAvatar.setClip(new Circle(20, 20, 20));
|
||||
|
||||
// === Private chat? Fetch other user status ===
|
||||
if ("private".equalsIgnoreCase(entry.getType()) && entry.getOtherUserId() != null) {
|
||||
UUID otherId = entry.getOtherUserId();
|
||||
|
||||
new Thread(() -> {
|
||||
JSONObject req = new JSONObject();
|
||||
req.put("action", "get_other_user_status");
|
||||
req.put("user_id", otherId.toString());
|
||||
|
||||
JSONObject resp = ActionHandler.sendWithResponse(req);
|
||||
if (resp != null && "success".equals(resp.optString("status"))) {
|
||||
JSONObject data = resp.optJSONObject("data");
|
||||
boolean online = data.optBoolean("online", false);
|
||||
String lastSeenIso = data.optString("last_seen", null);
|
||||
|
||||
String statusText;
|
||||
if (online) {
|
||||
statusText = "online";
|
||||
} else {
|
||||
// fallback if no timestamp
|
||||
statusText = (lastSeenIso == null || lastSeenIso.isEmpty())
|
||||
? "last seen recently"
|
||||
: "last seen " + formatWhen(parseWhen(lastSeenIso));
|
||||
}
|
||||
|
||||
Platform.runLater(() -> chatStatus.setText(statusText));
|
||||
}
|
||||
}).start();
|
||||
} else if ("group".equalsIgnoreCase(entry.getType())) {
|
||||
chatStatus.setText("Group");
|
||||
} else if ("channel".equalsIgnoreCase(entry.getType())) {
|
||||
chatStatus.setText("Channel");
|
||||
} else {
|
||||
chatStatus.setText("");
|
||||
}
|
||||
|
||||
// Load chat messages
|
||||
messageContainer.getChildren().clear();
|
||||
loadMessages(entry);
|
||||
|
||||
markAsRead(entry);
|
||||
|
||||
Platform.runLater(() -> messageInput.requestFocus());
|
||||
|
||||
@@ -287,30 +287,6 @@ public class MainController {
|
||||
searchBar.clear();
|
||||
}
|
||||
|
||||
// private void addSampleChats() {
|
||||
// addChat("Archived Chats", "Your archived chats", "10:45", 0);
|
||||
// addChat("Saved Messages", "Keep messages for later", "Yesterday", 0);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
// addChat("Alice", "Hey, how are you?", "14:12", 3);
|
||||
// addChat("Bob", "Let's meet tomorrow", "12:08", 1);
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
// ...
|
||||
private String formatChatTime(java.time.LocalDateTime ts) {
|
||||
if (ts == null) return "";
|
||||
var today = java.time.LocalDate.now();
|
||||
@@ -441,20 +417,6 @@ public class MainController {
|
||||
}
|
||||
}
|
||||
|
||||
// private void addChat(String name, String lastMsg, String time, int unread) {
|
||||
// try {
|
||||
// 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);
|
||||
//
|
||||
// chatItem.setOnMouseClicked(e -> openChat(name));
|
||||
// chatListContainer.getChildren().add(chatItem);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
private void openChat(ChatEntry chat) {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/Fxml/chat_page.fxml"));
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Reference in New Issue
Block a user