diff --git a/.gitignore b/.gitignore index b83d222..7836310 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target/ +/local_chats.db diff --git a/src/main/java/envoy/client/Chat.java b/src/main/java/envoy/client/Chat.java index 3f48c7c..6dcb35a 100644 --- a/src/main/java/envoy/client/Chat.java +++ b/src/main/java/envoy/client/Chat.java @@ -1,12 +1,16 @@ package envoy.client; +import java.io.Serializable; + import javax.swing.DefaultListModel; import envoy.schema.Message; import envoy.schema.User; -public class Chat { +public class Chat implements Serializable { + private static final long serialVersionUID = -7751248474547242056L; + private User recipient; private DefaultListModel model = new DefaultListModel<>(); diff --git a/src/main/java/envoy/client/ChatSynchronizer.java b/src/main/java/envoy/client/ChatSynchronizer.java new file mode 100644 index 0000000..0f7322f --- /dev/null +++ b/src/main/java/envoy/client/ChatSynchronizer.java @@ -0,0 +1,47 @@ +package envoy.client; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Project: envoy-client
+ * File: ChatSynchronizer.java
+ * Created: 27.10.2019
+ * + * @author Kai S. K. Engelbart + * @since Envoy v0.1-alpha + */ +public class ChatSynchronizer { + + private File localDB; + private List chats = new ArrayList<>(); + + public ChatSynchronizer(String localDBPath) { + localDB = new File(localDBPath); + if (localDB.exists() && !localDB.isDirectory()) loadFromLocalDB(); + } + + public void saveToLocalDB() { + try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { + out.writeObject(chats); + } catch(IOException ex) { + ex.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + private void loadFromLocalDB() { + try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) { + Object obj = in.readObject(); + if (obj instanceof ArrayList) chats = (ArrayList) obj; + } catch (ClassNotFoundException | IOException e) {} + } + + public List getChats() { return chats; } +} diff --git a/src/main/java/envoy/client/ui/ChatWindow.java b/src/main/java/envoy/client/ui/ChatWindow.java index dd7ff5e..4f5256e 100644 --- a/src/main/java/envoy/client/ui/ChatWindow.java +++ b/src/main/java/envoy/client/ui/ChatWindow.java @@ -6,8 +6,8 @@ import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.util.ArrayList; -import java.util.List; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import javax.swing.DefaultListModel; import javax.swing.JButton; @@ -24,6 +24,7 @@ import javax.swing.Timer; import javax.swing.border.EmptyBorder; import envoy.client.Chat; +import envoy.client.ChatSynchronizer; import envoy.client.Client; import envoy.schema.Message; import envoy.schema.Messages; @@ -46,20 +47,30 @@ public class ChatWindow extends JFrame { private JPanel contentPane = new JPanel(); - private Client client; + private Client client; + private ChatSynchronizer chatSynchronizer; - private JList userList = new JList<>(); - private List partnerChatList = new ArrayList(); + private JList userList = new JList<>(); private Chat currentChat; - public ChatWindow(Client client) { - this.client = client; + public ChatWindow(Client client, ChatSynchronizer chatSynchronizer) { + this.client = client; + this.chatSynchronizer = chatSynchronizer; setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 600, 800); setTitle("Envoy"); setLocationRelativeTo(null); + // Save chats when window closes + addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + chatSynchronizer.saveToLocalDB(); + } + }); + contentPane.setBackground(new Color(0, 0, 0)); contentPane.setForeground(Color.white); contentPane.setBorder(new EmptyBorder(0, 5, 0, 0)); @@ -138,7 +149,8 @@ public class ChatWindow extends JFrame { postButton.addActionListener((evt) -> { if (!client.hasRecipient()) { - JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", + JOptionPane.INFORMATION_MESSAGE); return; } @@ -158,8 +170,7 @@ public class ChatWindow extends JFrame { } catch (Exception e) { JOptionPane.showMessageDialog(this, "An exception occured while sending a message. See the log for more details.", - "Exception occured", - JOptionPane.ERROR_MESSAGE); + "Exception occured", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } }); @@ -186,12 +197,18 @@ public class ChatWindow extends JFrame { userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); userList.addListSelectionListener((listSelectionEvent) -> { if (!listSelectionEvent.getValueIsAdjusting()) { - @SuppressWarnings("unchecked") + @SuppressWarnings( + "unchecked" + ) final JList selectedUserList = (JList) listSelectionEvent.getSource(); final User user = selectedUserList.getSelectedValue(); client.setRecipient(user); - currentChat = partnerChatList.stream().filter(chat -> chat.getRecipient().getID() == user.getID()).findFirst().get(); + currentChat = chatSynchronizer.getChats() + .stream() + .filter(chat -> chat.getRecipient().getID() == user.getID()) + .findFirst() + .get(); client.setRecipient(user); @@ -232,7 +249,15 @@ public class ChatWindow extends JFrame { new Thread(() -> { Users users = client.getUsersListXml(); DefaultListModel userListModel = new DefaultListModel<>(); - users.getUser().forEach(user -> { userListModel.addElement(user); partnerChatList.add(new Chat(user)); }); + users.getUser().forEach(user -> { + userListModel.addElement(user); + + // Check if user exists in local DB + if (chatSynchronizer.getChats() + .stream() + .filter(c -> c.getRecipient().getID() == user.getID()) + .count() == 0) chatSynchronizer.getChats().add(new Chat(user)); + }); SwingUtilities.invokeLater(() -> userList.setModel(userListModel)); }).start(); } @@ -247,9 +272,11 @@ public class ChatWindow extends JFrame { new Timer(timeout, (evt) -> { Messages unreadMessages = client.getUnreadMessages(client.getSender().getID()); for (int i = 0; i < unreadMessages.getMessage().size(); i++) - for (int j = 0; j < partnerChatList.size(); j++) - if (partnerChatList.get(j).getRecipient().getID() == unreadMessages.getMessage().get(i).getMetaData().getSender()) - partnerChatList.get(j).appendMessage(unreadMessages.getMessage().get(i)); + for (int j = 0; j < chatSynchronizer.getChats().size(); j++) + if (chatSynchronizer.getChats().get(j) + .getRecipient() + .getID() == unreadMessages.getMessage().get(i).getMetaData().getSender()) + chatSynchronizer.getChats().get(j).appendMessage(unreadMessages.getMessage().get(i)); }).start(); } } \ No newline at end of file diff --git a/src/main/java/envoy/client/ui/Startup.java b/src/main/java/envoy/client/ui/Startup.java index b525861..e664aa8 100644 --- a/src/main/java/envoy/client/ui/Startup.java +++ b/src/main/java/envoy/client/ui/Startup.java @@ -6,6 +6,7 @@ import java.util.Properties; import javax.swing.JOptionPane; +import envoy.client.ChatSynchronizer; import envoy.client.Client; import envoy.client.Config; @@ -51,7 +52,7 @@ public class Startup { EventQueue.invokeLater(() -> { try { - ChatWindow frame = new ChatWindow(client); + ChatWindow frame = new ChatWindow(client, new ChatSynchronizer("local_chats.db")); frame.setVisible(true); } catch (Exception e) { e.printStackTrace();