Manage data after login
This commit is contained in:
@@ -3,8 +3,14 @@ package org.to.telegramfinalproject.Client;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.to.telegramfinalproject.Models.ChatEntry;
|
||||
|
||||
public class ActionHandler {
|
||||
private final PrintWriter out;
|
||||
@@ -51,20 +57,146 @@ public class ActionHandler {
|
||||
this.send(request);
|
||||
}
|
||||
|
||||
|
||||
public void search(){
|
||||
|
||||
System.out.print("Enter keyword to search: ");
|
||||
String keyword = scanner.nextLine();
|
||||
|
||||
JSONObject request = new JSONObject();
|
||||
request.put("action", "search");
|
||||
request.put("keyword", keyword);
|
||||
|
||||
send(request);
|
||||
|
||||
}
|
||||
|
||||
private void send(JSONObject request) {
|
||||
try {
|
||||
this.out.println(request.toString());
|
||||
String responseText = this.in.readLine();
|
||||
|
||||
if (responseText != null) {
|
||||
JSONObject response = new JSONObject(responseText);
|
||||
System.out.println("Server response: " + response.getString("message"));
|
||||
String status = response.getString("status");
|
||||
|
||||
String action = request.getString("action");
|
||||
|
||||
if (status.equals("success") && response.has("data") && !response.isNull("data")) {
|
||||
if (action.equals("login") || action.equals("register")) {
|
||||
|
||||
Session.currentUser = response.getJSONObject("data");
|
||||
|
||||
JSONArray chatListJson = Session.currentUser.getJSONArray("chat_list");
|
||||
List<ChatEntry> chatList = new ArrayList<>();
|
||||
|
||||
for (Object obj : chatListJson) {
|
||||
JSONObject chat = (JSONObject) obj;
|
||||
|
||||
ChatEntry entry = new ChatEntry(
|
||||
chat.getString("id"),
|
||||
chat.getString("name"),
|
||||
chat.getString("image_url"),
|
||||
chat.getString("type"),
|
||||
chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time"))
|
||||
);
|
||||
|
||||
chatList.add(entry);
|
||||
}
|
||||
|
||||
Session.chatList = chatList;
|
||||
}
|
||||
|
||||
else if (action.equals("search")) {
|
||||
|
||||
JSONArray results = response.getJSONObject("data").getJSONArray("results");
|
||||
|
||||
System.out.println("\nSearch Results:");
|
||||
for (Object obj : results) {
|
||||
JSONObject item = (JSONObject) obj;
|
||||
System.out.println("- [" + item.getString("type") + "] " + item.getString("name") + " (ID: " + item.getString("id") + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("No response from server.");
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void userMenu() {
|
||||
while (true) {
|
||||
System.out.println("\nUser Menu:");
|
||||
System.out.println("1. Show chat list");
|
||||
System.out.println("2. Search");
|
||||
System.out.println("3. Logout");
|
||||
|
||||
System.out.print("Choose an option: ");
|
||||
String choice = scanner.nextLine();
|
||||
|
||||
switch (choice) {
|
||||
|
||||
case "1":
|
||||
showChatListAndSelect();
|
||||
break;
|
||||
case "2" :
|
||||
search();
|
||||
break;
|
||||
|
||||
case "3":
|
||||
Session.currentUser = null;
|
||||
Session.chatList = null;
|
||||
System.out.println("Logged out.");
|
||||
return;
|
||||
default:
|
||||
System.out.println("Invalid choice.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void showChatListAndSelect() {
|
||||
if (Session.chatList == null || Session.chatList.isEmpty()) {
|
||||
System.out.println("No chats available.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("\nYour Chats:");
|
||||
for (int i = 0; i < Session.chatList.size(); i++) {
|
||||
ChatEntry entry = Session.chatList.get(i);
|
||||
String time = entry.getLastMessageTime() == null ? "No messages yet" : entry.getLastMessageTime().toString();
|
||||
System.out.println((i + 1) + ". [" + entry.getType() + "] " + entry.getName() + " - Last: " + time);
|
||||
}
|
||||
|
||||
System.out.print("Select a chat by number: ");
|
||||
int choice = Integer.parseInt(scanner.nextLine()) - 1;
|
||||
|
||||
if (choice < 0 || choice >= Session.chatList.size()) {
|
||||
System.out.println("Invalid selection.");
|
||||
return;
|
||||
}
|
||||
|
||||
ChatEntry selected = Session.chatList.get(choice);
|
||||
openChat(selected);
|
||||
}
|
||||
|
||||
|
||||
private void openChat(ChatEntry chat) {
|
||||
JSONObject request = new JSONObject();
|
||||
request.put("action", "get_messages");
|
||||
request.put("receiver_id", chat.getId());
|
||||
request.put("receiver_type", chat.getType());
|
||||
|
||||
send(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.to.telegramfinalproject.Client;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.to.telegramfinalproject.Models.ChatEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
// method for save data from server response
|
||||
public class Session {
|
||||
public static JSONObject currentUser;
|
||||
public static List<ChatEntry> chatList;
|
||||
}
|
||||
@@ -47,6 +47,13 @@ public class TelegramClient {
|
||||
break;
|
||||
case "2":
|
||||
this.handler.loginHandler();
|
||||
if (Session.currentUser != null) {
|
||||
System.out.println("Login successful.");
|
||||
this.handler.userMenu();
|
||||
|
||||
} else {
|
||||
System.out.println("Login failed.");
|
||||
}
|
||||
break;
|
||||
case "3":
|
||||
System.out.println(" Disconnecting...");
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.Channel;
|
||||
import org.to.telegramfinalproject.Models.Group;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChannelDatabase {
|
||||
public static List<Channel> getChannelsByUser(UUID internalUuid) {
|
||||
List<Channel> channels = new ArrayList<>();
|
||||
|
||||
String sql = """
|
||||
SELECT c.* FROM channels c
|
||||
JOIN channel_subscribers cs ON c.internal_uuid = cs.channel_id
|
||||
WHERE cs.user_id = ?
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
|
||||
stmt.setObject(1, internalUuid);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
Channel channel = new Channel();
|
||||
|
||||
channel.setInternal_uuid(UUID.fromString(rs.getString("internal_uuid")));
|
||||
channel.setChannel_id(rs.getString("channel_id"));
|
||||
channel.setChannel_name(rs.getString("channel_name"));
|
||||
channel.setCreator_id(UUID.fromString(rs.getString("creator_id")));
|
||||
channel.setImage_url(rs.getString("image_url"));
|
||||
channel.setDescription(rs.getString("description"));
|
||||
channel.setCreated_at(rs.getTimestamp("created_at").toLocalDateTime());
|
||||
|
||||
channels.add(channel);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return channels;
|
||||
}
|
||||
|
||||
|
||||
public static List<Channel> searchChannels(String keyword) {
|
||||
List<Channel> result = new ArrayList<>();
|
||||
String sql = "SELECT * FROM channels WHERE channel_name ILIKE ? OR channel_id ILIKE ?";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setString(1, "%" + keyword + "%");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
Channel channel = new Channel(
|
||||
UUID.fromString(rs.getString("internal_uuid")),
|
||||
rs.getString("channel_name"),
|
||||
UUID.fromString(rs.getString("creator_id")),
|
||||
rs.getTimestamp("created_at").toLocalDateTime()
|
||||
);
|
||||
channel.setChannel_id(rs.getString("channel_id"));
|
||||
channel.setImage_url(rs.getString("image_url"));
|
||||
channel.setDescription(rs.getString("description"));
|
||||
result.add(channel);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.Contact;
|
||||
import org.to.telegramfinalproject.Models.User;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ContactDatabase {
|
||||
public ContactDatabase(){}
|
||||
|
||||
|
||||
private static Connection getConnection() throws SQLException {
|
||||
return ConnectionDb.connect();
|
||||
}
|
||||
|
||||
|
||||
public boolean addContact(UUID user_id, UUID contact_id) {
|
||||
String sql = "INSERT INTO contacts (user_id, contact_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setObject(2,contact_id);
|
||||
return stmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean removeContact(UUID user_id, UUID contact_id) {
|
||||
String sql = "DELETE FROM contacts WHERE user_id = ? AND contact_id = ?";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setObject(2, contact_id);
|
||||
return stmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean blockContact(UUID user_id, UUID contact_id) {
|
||||
String sql = "UPDATE contacts SET is_blocked = TRUE WHERE user_id = ? AND contact_id = ?";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setObject(2, contact_id);
|
||||
return stmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean unblockContact(UUID user_id, UUID contact_id) {
|
||||
String sql = "UPDATE contacts SET is_blocked = FALSE WHERE user_id = ? AND contact_id = ?";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setObject(2, contact_id);
|
||||
return stmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Contact> getContacts(UUID user_id) {
|
||||
List<Contact> contacts = new ArrayList<>();
|
||||
String sql = "SELECT * FROM contacts WHERE user_id = ?";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
UUID contactId = (UUID) rs.getObject("contact_id");
|
||||
boolean isBlocked = rs.getBoolean("is_blocked");
|
||||
Timestamp addedAt = rs.getTimestamp("added_at");
|
||||
|
||||
Contact contact = new Contact(user_id, contactId);
|
||||
contact.setIs_blocked(isBlocked);
|
||||
contact.setAdd_at(addedAt.toLocalDateTime());
|
||||
contacts.add(contact);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return contacts;
|
||||
}
|
||||
|
||||
|
||||
public boolean existsContact(UUID user_id, UUID contact_id) {
|
||||
String sql = "SELECT 1 FROM contacts WHERE user_id = ? AND contact_id = ? LIMIT 1"; // stop searching when find the first item in DB(LIMIT 1)
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setObject(2, contact_id);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isBlocked(UUID user_id, UUID contact_id) {
|
||||
String sql = "SELECT is_blocked FROM contacts WHERE user_id = ? AND contact_id = ?";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setObject(2, contact_id);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getBoolean("is_blocked");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<Contact> searchContacts(UUID user_id, String searchTerm) {
|
||||
List<Contact> results = new ArrayList<>(); //ILIKE case-insensitive
|
||||
String sql = """
|
||||
SELECT c.contact_id, c.added_at, c.is_blocked
|
||||
FROM contacts c
|
||||
JOIN users u ON c.contact_id = u.internal_uuid
|
||||
WHERE c.user_id = ? AND (u.user_id ILIKE ? OR u.profile_name ILIKE ?)
|
||||
""";
|
||||
try (Connection connection = getConnection()) {
|
||||
PreparedStatement stmt = connection.prepareStatement(sql);
|
||||
stmt.setObject(1, user_id);
|
||||
stmt.setString(2, "%" + searchTerm + "%");
|
||||
stmt.setString(3, "%" + searchTerm + "%");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
UUID contactId = (UUID) rs.getObject("contact_id");
|
||||
boolean isBlocked = rs.getBoolean("is_blocked");
|
||||
Timestamp addedAt = rs.getTimestamp("added_at");
|
||||
Contact contact = new Contact(user_id, contactId);
|
||||
contact.setIs_blocked(isBlocked);
|
||||
contact.setAdd_at(addedAt.toLocalDateTime());
|
||||
results.add(contact);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.Group;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public class GroupDatabase {
|
||||
|
||||
public static List<Group> getGroupsByUser(UUID internalUuid) {
|
||||
List<Group> groups = new ArrayList<>();
|
||||
|
||||
String sql = """
|
||||
SELECT g.* FROM groups g
|
||||
JOIN group_members gm ON g.internal_uuid = gm.group_id
|
||||
WHERE gm.user_id = ?
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
|
||||
stmt.setObject(1, internalUuid);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
Group group = new Group();
|
||||
|
||||
group.setInternal_uuid(UUID.fromString(rs.getString("internal_uuid")));
|
||||
group.setGroup_id(rs.getString("group_id"));
|
||||
group.setGroup_name(rs.getString("group_name"));
|
||||
group.setCreator_id(UUID.fromString(rs.getString("creator_id")));
|
||||
group.setImage_url(rs.getString("image_url"));
|
||||
group.setDescription(rs.getString("description"));
|
||||
group.setCreated_at(rs.getTimestamp("created_at").toLocalDateTime());
|
||||
|
||||
groups.add(group);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
public static List<Group> searchGroups(String keyword) {
|
||||
List<Group> result = new ArrayList<>();
|
||||
String sql = "SELECT * FROM groups WHERE group_name ILIKE ? OR group_id ILIKE ?";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setString(1, "%" + keyword + "%");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
Group group = new Group(
|
||||
UUID.fromString(rs.getString("internal_uuid")),
|
||||
rs.getString("group_name"),
|
||||
UUID.fromString(rs.getString("creator_id")),
|
||||
rs.getTimestamp("created_at").toLocalDateTime()
|
||||
);
|
||||
group.setGroup_id(rs.getString("group_id"));
|
||||
group.setImage_url(rs.getString("image_url"));
|
||||
group.setDescription(rs.getString("description"));
|
||||
result.add(group);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.Message;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MessageDatabase {
|
||||
|
||||
|
||||
public void markMessageAsRead(UUID messageId, UUID userId) {
|
||||
String sql = "INSERT INTO message_receipts (message_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setObject(1, messageId);
|
||||
stmt.setObject(2, userId);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static List<Message> getUnreadMessages(UUID userId) {
|
||||
List<Message> messages = new ArrayList<>();
|
||||
|
||||
String sql = """
|
||||
SELECT m.* FROM messages m
|
||||
LEFT JOIN message_receipts r ON m.message_id = r.message_id AND r.user_id = ?
|
||||
WHERE r.user_id IS NULL
|
||||
AND (
|
||||
(m.receiver_type = 'private' AND m.receiver_id = ?)
|
||||
OR
|
||||
(m.receiver_type = 'group' AND EXISTS (
|
||||
SELECT 1 FROM group_members gm WHERE gm.group_id = m.receiver_id AND gm.user_id = ?
|
||||
))
|
||||
OR
|
||||
(m.receiver_type = 'channel' AND EXISTS (
|
||||
SELECT 1 FROM channel_subscribers cs WHERE cs.channel_id = m.receiver_id AND cs.user_id = ?
|
||||
))
|
||||
)
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
|
||||
stmt.setObject(1, userId);
|
||||
stmt.setObject(2, userId);
|
||||
stmt.setObject(3, userId);
|
||||
stmt.setObject(4, userId);
|
||||
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
messages.add(new Message(
|
||||
UUID.fromString(rs.getString("message_id")),
|
||||
rs.getObject("sender_id") != null ? UUID.fromString(rs.getString("sender_id")) : null,
|
||||
rs.getString("receiver_type"),
|
||||
UUID.fromString(rs.getString("receiver_id")),
|
||||
rs.getString("content"),
|
||||
rs.getString("message_type"),
|
||||
rs.getString("file_url"),
|
||||
rs.getTimestamp("send_at").toLocalDateTime(),
|
||||
rs.getString("status"),
|
||||
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
|
||||
rs.getBoolean("is_edited"),
|
||||
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
|
||||
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
|
||||
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null
|
||||
));
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
||||
public static LocalDateTime getLastMessageTimeBetween(UUID user1, UUID user2, String type) {
|
||||
String sql = """
|
||||
SELECT MAX(send_at) FROM messages
|
||||
WHERE receiver_type = ?
|
||||
AND (
|
||||
(sender_id = ? AND receiver_id = ?)
|
||||
OR (sender_id = ? AND receiver_id = ?)
|
||||
)
|
||||
""";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setString(1, type);
|
||||
stmt.setObject(2, user1);
|
||||
stmt.setObject(3, user2);
|
||||
stmt.setObject(4, user2);
|
||||
stmt.setObject(5, user1);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
Timestamp ts = rs.getTimestamp(1);
|
||||
return ts != null ? ts.toLocalDateTime() : null;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static LocalDateTime getLastMessageTime(UUID receiverId, String type) {
|
||||
String sql = "SELECT MAX(send_at) FROM messages WHERE receiver_id = ? AND receiver_type = ?";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setObject(1, receiverId);
|
||||
stmt.setString(2, type);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
if (rs.next()) {
|
||||
Timestamp ts = rs.getTimestamp(1);
|
||||
return ts != null ? ts.toLocalDateTime() : null;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,10 +3,7 @@ package org.to.telegramfinalproject.Database;
|
||||
|
||||
import org.to.telegramfinalproject.Models.User;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -203,5 +200,87 @@ public class userDatabase {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void updateUserStatus(UUID uuid, String status) {
|
||||
String sql = "UPDATE users SET status = ? WHERE internal_uuid = ?";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setString(1, status);
|
||||
stmt.setObject(2, uuid);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateLastSeen(UUID uuid) {
|
||||
String sql = "UPDATE users SET last_seen = CURRENT_TIMESTAMP WHERE internal_uuid = ?";
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setObject(1, uuid);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static User findByInternalUUID(UUID internalUuid) {
|
||||
String sql = "SELECT * FROM users WHERE internal_uuid = ?";
|
||||
|
||||
try (Connection conn = ConnectionDb.connect();
|
||||
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
|
||||
stmt.setObject(1, internalUuid);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
|
||||
if (rs.next()) {
|
||||
User user = new User(
|
||||
rs.getString("user_id"),
|
||||
UUID.fromString(rs.getString("internal_uuid")),
|
||||
rs.getString("username"),
|
||||
rs.getString("password"),
|
||||
rs.getString("profile_name")
|
||||
);
|
||||
|
||||
user.setBio(rs.getString("bio"));
|
||||
user.setImage_url(rs.getString("image_url"));
|
||||
user.setStatus(rs.getString("status"));
|
||||
|
||||
Timestamp lastSeenTs = rs.getTimestamp("last_seen");
|
||||
if (lastSeenTs != null) {
|
||||
user.setLast_seen(lastSeenTs.toLocalDateTime());
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<User> searchUsers(String keyword) {
|
||||
String query = "SELECT * FROM users WHERE user_id ILIKE ? OR profile_name ILIKE ?"; //(ILIKE) case_insensitive
|
||||
List<User> result = new ArrayList<>();
|
||||
try (Connection conn = getConnection();
|
||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||
stmt.setString(1, "%" + keyword + "%");
|
||||
stmt.setString(2, "%" + keyword + "%");
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
result.add(extractUser(rs));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ public class Channel {
|
||||
this.created_at = created_at;
|
||||
}
|
||||
|
||||
public Channel() {
|
||||
|
||||
}
|
||||
|
||||
public void setChannel_id(String Channel_id){this.channel_id = Channel_id;}
|
||||
public void setCreator_id(UUID creator_id){this.creator_id = creator_id;}
|
||||
public void setChannel_name(String channel_name){this.channel_name = channel_name;}
|
||||
@@ -40,4 +44,6 @@ public class Channel {
|
||||
return this.internal_uuid;
|
||||
}
|
||||
|
||||
public void setInternal_uuid(UUID internalUuid) { this.internal_uuid = internalUuid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,27 +3,27 @@ package org.to.telegramfinalproject.Models;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChannelSubscribe {
|
||||
public class ChannelSubscribe{
|
||||
private UUID channel_id;
|
||||
private UUID user_id;
|
||||
private LocalDateTime join_at;
|
||||
private LocalDateTime Subscribed_at;
|
||||
|
||||
|
||||
public ChannelSubscribe(UUID channel_id, UUID user_id, String role){
|
||||
this.channel_id = channel_id;
|
||||
this.user_id = user_id;
|
||||
this.join_at = LocalDateTime.now();
|
||||
this.Subscribed_at = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public void setChannel_id(UUID group_id){this.channel_id = group_id;}
|
||||
public void setUser_id(UUID user_id){this.user_id = user_id;}
|
||||
public void setJoin_at(LocalDateTime join_at){this.join_at = join_at;}
|
||||
public void setJoin_at(LocalDateTime join_at){this.Subscribed_at = join_at;}
|
||||
|
||||
|
||||
|
||||
public UUID getChannel_id(){return this.channel_id;}
|
||||
public UUID getUser_id(){return this.user_id;}
|
||||
public LocalDateTime getJoin_at(){return this.join_at;}
|
||||
public LocalDateTime getJoin_at(){return this.Subscribed_at;}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class ChatEntry {
|
||||
private final String name;
|
||||
private final String id;
|
||||
private final String imageUrl;
|
||||
private final String type; // "private", "group", "channel"
|
||||
private final LocalDateTime lastMessageTime;
|
||||
|
||||
public ChatEntry(String name, String id, String imageUrl, String type, LocalDateTime lastMessageTime) {
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
this.imageUrl = imageUrl;
|
||||
this.type = type;
|
||||
this.lastMessageTime = lastMessageTime;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastMessageTime() {
|
||||
return lastMessageTime;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,27 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Contact {
|
||||
private UUID user_id;
|
||||
private UUID contact_id;
|
||||
private LocalDateTime add_at;
|
||||
private LocalDateTime added_at;
|
||||
private Boolean is_blocked;
|
||||
|
||||
public Contact(UUID user_id, UUID contact_id){
|
||||
this.user_id = user_id;
|
||||
this.contact_id = contact_id;
|
||||
this.add_at = LocalDateTime.now();
|
||||
this.added_at = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public void setUser_id(UUID user_id){this.user_id = user_id;}
|
||||
public void setContact_id(UUID contact_id){this.contact_id = contact_id;}
|
||||
public void setAdd_at(LocalDateTime add_at){this.add_at =add_at;}
|
||||
public void setAdd_at(LocalDateTime add_at){this.added_at =add_at;}
|
||||
public void setIs_blocked(Boolean is_blocked){this.is_blocked =is_blocked;}
|
||||
|
||||
public UUID getUser_id(){
|
||||
@@ -27,9 +31,14 @@ public class Contact {
|
||||
public UUID getContact_id(){return this.contact_id;}
|
||||
|
||||
public LocalDateTime getAdd_at() {
|
||||
return add_at;
|
||||
return added_at;
|
||||
}
|
||||
public Boolean getIs_blocked(){
|
||||
return is_blocked;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,10 @@ public class Group {
|
||||
this.created_at = created_at;
|
||||
}
|
||||
|
||||
public Group() {
|
||||
|
||||
}
|
||||
|
||||
public void setGroup_id(String group_id){this.group_id = group_id;}
|
||||
public void setCreator_id(UUID creator_id){this.creator_id = creator_id;}
|
||||
public void setGroup_name(String group_name){this.group_name = group_name;}
|
||||
@@ -40,4 +44,6 @@ public class Group {
|
||||
return this.internal_uuid;
|
||||
}
|
||||
|
||||
public void setInternal_uuid(UUID internalUuid) { this.internal_uuid = internalUuid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class JsonUtil {
|
||||
public static JSONArray contactListToJson(List<Contact> contacts) {
|
||||
|
||||
|
||||
JSONArray array = new JSONArray();
|
||||
for (Contact contact : contacts) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("user_id", contact.getUser_id().toString());
|
||||
obj.put("contact_id", contact.getContact_id().toString());
|
||||
obj.put("is_blocked", contact.getIs_blocked());
|
||||
obj.put("added_at", contact.getAdd_at().toString());
|
||||
array.put(obj);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static JSONObject userToJson(User user) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("internalUUID", user.getInternal_uuid().toString());
|
||||
obj.put("user_id", user.getUser_id() != null ?user.getUser_id().toString() :JSONObject.NULL);
|
||||
obj.put("username", user.getUsername());
|
||||
obj.put("profile_name", user.getProfile_name());
|
||||
obj.put("bio", user.getBio()!= null ?user.getBio().toString() :JSONObject.NULL);
|
||||
obj.put("image_url", user.getImage_url() != null ?user.getImage_url().toString() :JSONObject.NULL);
|
||||
obj.put("status", user.getStatus());
|
||||
obj.put("last_seen", user.getLast_seen() != null ? user.getLast_seen().toString() : JSONObject.NULL);
|
||||
obj.put("contactList", JsonUtil.contactListToJson(user.getContactList()));
|
||||
obj.put("channelList", JsonUtil.channelListToJson(user.getChannelList()));
|
||||
obj.put("groupList", JsonUtil.groupListToJson(user.getGroupList()));
|
||||
obj.put("unreadMessages", JsonUtil.messageListToJson(user.getUnreadMessages()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
public static JSONArray messageListToJson(List<Message> messages) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Message message : messages) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("message_id", message.getMessage_id().toString());
|
||||
obj.put("sender_id", message.getSender_id() != null ? message.getSender_id().toString() : JSONObject.NULL);
|
||||
obj.put("receiver_type", message.getReceiver_type());
|
||||
obj.put("receiver_id", message.getReceiver_id().toString());
|
||||
obj.put("content", message.getContent());
|
||||
obj.put("message_type", message.getMessage_type());
|
||||
obj.put("file_url", message.getFile_url());
|
||||
obj.put("send_at", message.getSend_at().toString());
|
||||
obj.put("status", message.getStatus());
|
||||
obj.put("reply_to_id", message.getReply_to_id() != null ? message.getReply_to_id().toString() : JSONObject.NULL);
|
||||
obj.put("is_edited", message.isIs_edited());
|
||||
obj.put("original_message_id", message.getOriginal_message_id() != null ? message.getOriginal_message_id().toString() : JSONObject.NULL);
|
||||
obj.put("forwarded_by", message.getForwarded_by() != null ? message.getForwarded_by().toString() : JSONObject.NULL);
|
||||
obj.put("forwarded_from", message.getForwarded_from() != null ? message.getForwarded_from().toString() : JSONObject.NULL);
|
||||
array.put(obj);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static JSONArray groupListToJson(List<Group> groups) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Group group : groups) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("internal_uuid", group.getInternal_uuid().toString());
|
||||
obj.put("group_id", group.getGroup_id() != null ?group.getGroup_id().toString() :JSONObject.NULL);
|
||||
obj.put("group_name", group.getGroup_name());
|
||||
obj.put("creator_id", group.getCreator_id().toString());
|
||||
obj.put("image_url",group.getImage_url()!= null ?group.getImage_url().toString() : JSONObject.NULL );
|
||||
obj.put("description", group.getDescription() != null ?group.getDescription().toString() : JSONObject.NULL );
|
||||
obj.put("created_at", group.getCreated_at().toString());
|
||||
obj.put("members", JsonUtil.groupMemberListToJson(group.getMembers()));
|
||||
array.put(obj);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static JSONArray channelListToJson(List<Channel> channels) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (Channel channel : channels) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("internal_uuid",channel.getInternal_uuid().toString());
|
||||
obj.put("channel_id", channel.getChannel_id() != null ?channel.getChannel_id().toString() :JSONObject.NULL);
|
||||
obj.put("channel_name", channel.getChannel_name());
|
||||
obj.put("creator_id", channel.getCreator_id().toString());
|
||||
obj.put("image_url",channel.getImage_url()!= null ?channel.getImage_url().toString() : JSONObject.NULL );
|
||||
obj.put("description",channel.getDescription() != null ?channel.getDescription().toString() : JSONObject.NULL );
|
||||
obj.put("created_at",channel.getCreated_at().toString());
|
||||
obj.put("members", JsonUtil.channelSubscribeToJson(channel.getMembers()));
|
||||
array.put(obj);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static JSONArray groupMemberListToJson(List<GroupMember> members) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (GroupMember m : members) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("group_id", m.getGroup_id().toString());
|
||||
obj.put("user_id", m.getUser_id().toString());
|
||||
obj.put("joined_at", m.getJoin_at().toString());
|
||||
obj.put("role", m.getRole());
|
||||
array.put(obj);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static JSONArray channelSubscribeToJson(List<ChannelSubscribe> subscribes){
|
||||
JSONArray array = new JSONArray();
|
||||
for(ChannelSubscribe s :subscribes ){
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("channel_id",s.getChannel_id().toString());
|
||||
obj.put("user_id", s.getUser_id().toString());
|
||||
obj.put("Subscribed_at", s.getJoin_at().toString());
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
public static JSONArray chatListToJson(List<ChatEntry> chatList) {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
|
||||
for (ChatEntry entry : chatList) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("id", entry.getId() != null ?entry.getId() :JSONObject.NULL);
|
||||
obj.put("name", entry.getName());
|
||||
obj.put("image_url", entry.getImageUrl() != null ?entry.getImageUrl() :JSONObject.NULL);
|
||||
obj.put("type", entry.getType());
|
||||
obj.put("last_message_time", entry.getLastMessageTime() != null ? entry.getLastMessageTime().toString() : JSONObject.NULL);
|
||||
|
||||
jsonArray.put(obj);
|
||||
}
|
||||
|
||||
return jsonArray;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LoginBootstrapData {
|
||||
private User user;
|
||||
private List<Contact> contacts;
|
||||
private List<Group> groups;
|
||||
private List<Channel> channels;
|
||||
private List<Message> unreadMessages;
|
||||
|
||||
public LoginBootstrapData(User user, List<Contact> contacts, List<Group> groups,
|
||||
List<Channel> channels, List<Message> unreadMessages) {
|
||||
this.user = user;
|
||||
this.contacts = contacts;
|
||||
this.groups = groups;
|
||||
this.channels = channels;
|
||||
this.unreadMessages = unreadMessages;
|
||||
}
|
||||
|
||||
public void setUnreadMessages(List<Message> unreadMessages){this.unreadMessages = unreadMessages;}
|
||||
public void setContacts(List<Contact> contacts){this.contacts =contacts;}
|
||||
public void setGroups(List<Group> groups){this.groups = groups;}
|
||||
public void setChannels(List<Channel> channels){this.channels = channels;}
|
||||
public void setUser(User user){this.user = user;}
|
||||
|
||||
public List<Message> getUnreadMessages(){return unreadMessages;}
|
||||
public List<Group> getGroups(){return groups;}
|
||||
public List<Contact> getContacts(){return contacts;}
|
||||
public List<Channel> getChannels(){return channels;}
|
||||
public User getUser(User user){return user;}
|
||||
}
|
||||
@@ -1,12 +1,23 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class ResponseModel {
|
||||
private String status;
|
||||
private String message;
|
||||
private JSONObject data;
|
||||
|
||||
|
||||
public ResponseModel(String status, String message) {
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
public ResponseModel(String status, String message, JSONObject data) {
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
@@ -16,4 +27,6 @@ public class ResponseModel {
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public JSONObject getData() {return this.data;}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.to.telegramfinalproject.Models;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -17,6 +19,8 @@ public class User {
|
||||
private List<Contact> contactList;
|
||||
private List<Group> groupList;
|
||||
private List<Channel> channelList;
|
||||
private List<Message> unreadMessages;
|
||||
private List<ChatEntry> chatList;
|
||||
|
||||
public User(String user_id, UUID internal_uuid, String username, String password, String profile_name) {
|
||||
this.user_id = user_id;
|
||||
@@ -64,6 +68,10 @@ public class User {
|
||||
|
||||
public void setGroupList(List<Group> groupList){this.groupList = groupList;}
|
||||
|
||||
public void setUnreadMessages(List<Message> unreadMessages){this.unreadMessages = unreadMessages;}
|
||||
|
||||
public void setChatList(List<ChatEntry> chatList){this.chatList = chatList;}
|
||||
|
||||
public UUID getInternal_uuid() {
|
||||
return this.internal_uuid;
|
||||
}
|
||||
@@ -105,5 +113,13 @@ public class User {
|
||||
public List<Channel> getChannelList(){return this.channelList;}
|
||||
|
||||
public List<Group> getGroupList(){return this.groupList;}
|
||||
|
||||
public List<Message> getUnreadMessages(){return this.unreadMessages;}
|
||||
|
||||
public List<ChatEntry> getChatList(){return this.chatList;}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,19 @@ public class AuthService {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean loginCheck(String username , String password){
|
||||
User user = userDb.findByUsername(username);
|
||||
String pass = user.getPassword();
|
||||
password = PasswordHashing.hash(password);
|
||||
String Username = user.getUsername();
|
||||
boolean login = false;
|
||||
if(user!= null && Username.equals(username)&& pass.equals(password)){
|
||||
login = true;
|
||||
}
|
||||
return login;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package org.to.telegramfinalproject.Server;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.to.telegramfinalproject.Models.RequestModel;
|
||||
import org.to.telegramfinalproject.Models.ResponseModel;
|
||||
import org.to.telegramfinalproject.Models.User;
|
||||
import org.to.telegramfinalproject.Database.*;
|
||||
import org.to.telegramfinalproject.Models.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ClientHandler implements Runnable {
|
||||
private final Socket socket;
|
||||
@@ -34,9 +38,11 @@ public class ClientHandler implements Runnable {
|
||||
requestJson.optString("profile_name")
|
||||
);
|
||||
|
||||
ResponseModel response;
|
||||
ResponseModel response = null;
|
||||
|
||||
switch (request.getAction()) {
|
||||
String action = requestJson.optString("action");
|
||||
|
||||
switch (action) {
|
||||
case "register":
|
||||
boolean registered = authService.register(
|
||||
request.getUser_id(),
|
||||
@@ -51,27 +57,159 @@ public class ClientHandler implements Runnable {
|
||||
|
||||
case "login":
|
||||
User user = authService.login(request.getUsername(), request.getPassword());
|
||||
response = (user != null)
|
||||
? new ResponseModel("success", "Welcome " + user.getProfile_name())
|
||||
: new ResponseModel("error", "Login failed.");
|
||||
if (user == null) {
|
||||
response = new ResponseModel("error", "Login failed.");
|
||||
}
|
||||
else {
|
||||
|
||||
SessionManager.addUser(user.getInternal_uuid(), this.socket);
|
||||
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
|
||||
|
||||
|
||||
|
||||
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
|
||||
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
|
||||
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
|
||||
List<Message> unreadMessages = MessageDatabase.getUnreadMessages(user.getInternal_uuid());
|
||||
|
||||
user.setContactList(contacts);
|
||||
user.setGroupList(groups);
|
||||
user.setChannelList(channels);
|
||||
user.setUnreadMessages(unreadMessages);
|
||||
|
||||
|
||||
List<ChatEntry> chatList = new ArrayList<>();
|
||||
|
||||
for (Contact contact : contacts) {
|
||||
User target = userDatabase.findByInternalUUID(contact.getContact_id());
|
||||
if (target == null) continue;
|
||||
|
||||
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
|
||||
|
||||
chatList.add(new ChatEntry(
|
||||
target.getUser_id(),
|
||||
target.getProfile_name(),
|
||||
target.getImage_url(),
|
||||
"private",
|
||||
last
|
||||
));
|
||||
}
|
||||
|
||||
for (Group group : groups) {
|
||||
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
|
||||
chatList.add(new ChatEntry(
|
||||
group.getGroup_id(),
|
||||
group.getGroup_name(),
|
||||
group.getImage_url(),
|
||||
"group",
|
||||
last
|
||||
));
|
||||
}
|
||||
|
||||
for (Channel channel : channels) {
|
||||
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
|
||||
chatList.add(new ChatEntry(
|
||||
channel.getChannel_id(),
|
||||
channel.getChannel_name(),
|
||||
channel.getImage_url(),
|
||||
"channel",
|
||||
last
|
||||
));
|
||||
}
|
||||
|
||||
chatList.sort((a, b) -> {
|
||||
if (a.getLastMessageTime() == null) return 1;
|
||||
if (b.getLastMessageTime() == null) return -1;
|
||||
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
|
||||
});
|
||||
|
||||
|
||||
|
||||
JSONObject userData = JsonUtil.userToJson(user);
|
||||
JSONArray chatListJson = JsonUtil.chatListToJson(chatList);
|
||||
userData.put("chat_list", chatListJson);
|
||||
|
||||
|
||||
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "logout":
|
||||
|
||||
UUID uuid = UUID.fromString(request.getUser_id());
|
||||
userDatabase.updateUserStatus(uuid, "offline");
|
||||
userDatabase.updateLastSeen(uuid);
|
||||
SessionManager.removeUser(uuid);
|
||||
|
||||
response = new ResponseModel("success", "Logged out.");
|
||||
break;
|
||||
|
||||
case "search":
|
||||
String keyword = requestJson.optString("keyword");
|
||||
|
||||
List<JSONObject> results = new ArrayList<>();
|
||||
|
||||
// User search
|
||||
List<User> users = new userDatabase().searchUsers(keyword);
|
||||
for (User u : users) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("type", "user");
|
||||
obj.put("id", u.getUser_id());
|
||||
obj.put("name", u.getProfile_name());
|
||||
results.add(obj);
|
||||
}
|
||||
|
||||
// Group search
|
||||
List<Group> groups = GroupDatabase.searchGroups(keyword);
|
||||
for (Group g : groups) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("type", "group");
|
||||
obj.put("id", g.getGroup_id());
|
||||
obj.put("name", g.getGroup_name());
|
||||
results.add(obj);
|
||||
}
|
||||
|
||||
// Channel search
|
||||
List<Channel> channels = ChannelDatabase.searchChannels(keyword);
|
||||
for (Channel c : channels) {
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("type", "channel");
|
||||
obj.put("id", c.getChannel_id());
|
||||
obj.put("name", c.getChannel_name());
|
||||
results.add(obj);
|
||||
}
|
||||
|
||||
JSONArray dataArray = new JSONArray(results);
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("results", dataArray);
|
||||
response = new ResponseModel("success", "Search results found", data);
|
||||
break;
|
||||
|
||||
default:
|
||||
response = new ResponseModel("error", "Unknown action: " + request.getAction());
|
||||
response = new ResponseModel("error", "Unknown action: " + action);
|
||||
}
|
||||
|
||||
JSONObject responseJson = new JSONObject();
|
||||
responseJson.put("status", response.getStatus());
|
||||
responseJson.put("message", response.getMessage());
|
||||
responseJson.put("data",response.getData() != null ?response.getData() :JSONObject.NULL);
|
||||
out.println(responseJson.toString());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
} catch(IOException e){
|
||||
System.out.println("Connection with client lost.");
|
||||
|
||||
UUID userId = SessionManager.getUserIdBySocket(this.socket);
|
||||
if (userId != null) {
|
||||
userDatabase.updateUserStatus(userId, "offline");
|
||||
userDatabase.updateLastSeen(userId);
|
||||
SessionManager.removeUser(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.to.telegramfinalproject.Server;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SessionManager {
|
||||
private static final Map<UUID, Socket> onlineUsers = new ConcurrentHashMap<>(); //catch UUID for find the user socket
|
||||
|
||||
public static void addUser(UUID userId, Socket socket) {
|
||||
onlineUsers.put(userId, socket);
|
||||
}
|
||||
|
||||
public static void removeUser(UUID userId) {
|
||||
onlineUsers.remove(userId);
|
||||
}
|
||||
|
||||
public static boolean isOnline(UUID userId) {
|
||||
return onlineUsers.containsKey(userId);
|
||||
}
|
||||
|
||||
public static Socket getUserSocket(UUID userId) {
|
||||
return onlineUsers.get(userId);
|
||||
}
|
||||
|
||||
public static UUID getUserIdBySocket(Socket socket) {
|
||||
for (Map.Entry<UUID, Socket> entry : onlineUsers.entrySet()) {
|
||||
if (entry.getValue().equals(socket)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user