Listening to message status changes, sending READ status updates
This commit is contained in:
parent
7424cc900f
commit
b6167ce166
@ -1,11 +1,14 @@
|
|||||||
package envoy.client;
|
package envoy.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import envoy.client.net.Client;
|
||||||
import envoy.client.ui.list.ComponentListModel;
|
import envoy.client.ui.list.ComponentListModel;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
import envoy.data.Message.MessageStatus;
|
import envoy.data.Message.MessageStatus;
|
||||||
import envoy.data.User;
|
import envoy.data.User;
|
||||||
|
import envoy.event.MessageStatusChangeEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a chat between two {@link User}s <br>
|
* Represents a chat between two {@link User}s <br>
|
||||||
@ -49,13 +52,24 @@ public class Chat implements Serializable {
|
|||||||
* {@code READ} starting from the bottom and stopping once a read message is
|
* {@code READ} starting from the bottom and stopping once a read message is
|
||||||
* found.
|
* found.
|
||||||
*
|
*
|
||||||
|
* @param client the client instance used to notify the server about the message
|
||||||
|
* status changes
|
||||||
|
* @throws IOException if a {@link MessageStatusChangeEvent} could not be
|
||||||
|
* delivered to the server
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void read() {
|
public void read(Client client) throws IOException {
|
||||||
for (int i = model.size() - 1; i >= 0; --i)
|
for (int i = model.size() - 1; i >= 0; --i) {
|
||||||
if (model.get(i).getSenderId() == recipient.getId()) {
|
final Message m = model.get(i);
|
||||||
if (model.get(i).getStatus() == MessageStatus.READ) break;
|
if (m.getSenderId() == recipient.getId()) {
|
||||||
else model.get(i).setStatus(MessageStatus.READ);
|
if (m.getStatus() == MessageStatus.READ) break;
|
||||||
|
else {
|
||||||
|
m.setStatus(MessageStatus.READ);
|
||||||
|
|
||||||
|
// TODO: Cache events in offline mode
|
||||||
|
client.sendEvent(new MessageStatusChangeEvent(m));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@ import envoy.client.Config;
|
|||||||
import envoy.client.database.LocalDb;
|
import envoy.client.database.LocalDb;
|
||||||
import envoy.client.util.EnvoyLog;
|
import envoy.client.util.EnvoyLog;
|
||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
|
import envoy.event.Event;
|
||||||
import envoy.event.IdGeneratorRequest;
|
import envoy.event.IdGeneratorRequest;
|
||||||
|
import envoy.event.MessageStatusChangeEvent;
|
||||||
import envoy.util.SerializationUtils;
|
import envoy.util.SerializationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,19 +105,21 @@ public class Client implements Closeable {
|
|||||||
// Relay cached unread messages
|
// Relay cached unread messages
|
||||||
cache.setProcessor(receivedMessageProcessor);
|
cache.setProcessor(receivedMessageProcessor);
|
||||||
|
|
||||||
// TODO: Status handling
|
// Process message status changes
|
||||||
|
receiver.registerProcessor(MessageStatusChangeEvent.class, new MessageStatusChangeEventProcessor());
|
||||||
|
|
||||||
// Process message ID generation
|
// Process message ID generation
|
||||||
receiver.registerProcessor(IdGenerator.class, localDb::setIdGenerator);
|
receiver.registerProcessor(IdGenerator.class, localDb::setIdGenerator);
|
||||||
|
|
||||||
// Request a generator if none is present
|
// Request a generator if none is present or the existing one is consumed
|
||||||
if (!localDb.hasIdGenerator() || !localDb.getIdGenerator().hasNext()) requestIdGenerator();
|
if (!localDb.hasIdGenerator() || !localDb.getIdGenerator().hasNext()) requestIdGenerator();
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a message to the server.
|
* Sends a message to the server. The message's status will be incremented once
|
||||||
|
* it was delivered successfully.
|
||||||
*
|
*
|
||||||
* @param message the message to send
|
* @param message the message to send
|
||||||
* @throws IOException if the message does not reach the server
|
* @throws IOException if the message does not reach the server
|
||||||
@ -126,6 +130,14 @@ public class Client implements Closeable {
|
|||||||
message.nextStatus();
|
message.nextStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an event to the server.
|
||||||
|
*
|
||||||
|
* @param evt the event to send
|
||||||
|
* @throws IOException if the event did not reach the server
|
||||||
|
*/
|
||||||
|
public void sendEvent(Event<?> evt) throws IOException { writeObject(evt); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests a new {@link IdGenerator} from the server.
|
* Requests a new {@link IdGenerator} from the server.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package envoy.client.net;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import envoy.client.util.EnvoyLog;
|
||||||
|
import envoy.data.Message.MessageStatus;
|
||||||
|
import envoy.event.EventBus;
|
||||||
|
import envoy.event.MessageStatusChangeEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>envoy-client</strong><br>
|
||||||
|
* File: <strong>MessageStatusChangeEventProcessor.java</strong><br>
|
||||||
|
* Created: <strong>4 Feb 2020</strong><br>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
public class MessageStatusChangeEventProcessor implements Consumer<MessageStatusChangeEvent> {
|
||||||
|
|
||||||
|
private static final Logger logger = EnvoyLog.getLogger(MessageStatusChangeEventProcessor.class.getSimpleName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches a {@link MessageStatusChangeEvent} if the status is
|
||||||
|
* {@code RECEIVED} or {@code READ}.
|
||||||
|
*
|
||||||
|
* @param evt the status change event
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void accept(MessageStatusChangeEvent evt) {
|
||||||
|
if (evt.get().ordinal() <= MessageStatus.RECEIVED.ordinal()) logger.info("Received invalid message status change " + evt);
|
||||||
|
else {
|
||||||
|
logger.info("Received " + evt.toString());
|
||||||
|
EventBus.getInstance().dispatch(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package envoy.client.ui;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -19,9 +20,11 @@ import envoy.client.ui.list.ComponentList;
|
|||||||
import envoy.client.ui.settings.SettingsScreen;
|
import envoy.client.ui.settings.SettingsScreen;
|
||||||
import envoy.client.util.EnvoyLog;
|
import envoy.client.util.EnvoyLog;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
|
import envoy.data.Message.MessageStatus;
|
||||||
import envoy.data.MessageBuilder;
|
import envoy.data.MessageBuilder;
|
||||||
import envoy.data.User;
|
import envoy.data.User;
|
||||||
import envoy.event.EventBus;
|
import envoy.event.EventBus;
|
||||||
|
import envoy.event.MessageStatusChangeEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
@ -173,7 +176,12 @@ public class ChatWindow extends JFrame {
|
|||||||
currentChat = localDb.getChats().stream().filter(chat -> chat.getRecipient().getId() == user.getId()).findFirst().get();
|
currentChat = localDb.getChats().stream().filter(chat -> chat.getRecipient().getId() == user.getId()).findFirst().get();
|
||||||
|
|
||||||
// Read current Chat
|
// Read current Chat
|
||||||
currentChat.read();
|
try {
|
||||||
|
currentChat.read(client);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
logger.log(Level.WARNING, "Could notify server about message status change", e);
|
||||||
|
}
|
||||||
|
|
||||||
// Set chat title
|
// Set chat title
|
||||||
textPane.setText(currentChat.getRecipient().getName());
|
textPane.setText(currentChat.getRecipient().getName());
|
||||||
@ -213,6 +221,26 @@ public class ChatWindow extends JFrame {
|
|||||||
repaint();
|
repaint();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Listen to message status changes
|
||||||
|
EventBus.getInstance().register(MessageStatusChangeEvent.class, (evt) -> {
|
||||||
|
final long id = ((MessageStatusChangeEvent) evt).getId();
|
||||||
|
final MessageStatus status = (MessageStatus) evt.get();
|
||||||
|
|
||||||
|
for (Chat c : localDb.getChats())
|
||||||
|
for (Message m : c.getModel())
|
||||||
|
if (m.getId() == id) {
|
||||||
|
|
||||||
|
// Update message status
|
||||||
|
m.setStatus(status);
|
||||||
|
|
||||||
|
// Update model and scroll down if current chat
|
||||||
|
if (c == currentChat) {
|
||||||
|
messageList.setModel(currentChat.getModel());
|
||||||
|
scrollPane.setChatOpened(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
revalidate();
|
revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,10 +314,7 @@ public class ChatWindow extends JFrame {
|
|||||||
if (!localDb.getIdGenerator().hasNext()) client.requestIdGenerator();
|
if (!localDb.getIdGenerator().hasNext()) client.requestIdGenerator();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this, "Error sending message:\n" + e.toString(), "Message sending error", JOptionPane.ERROR_MESSAGE);
|
||||||
"Error sending message:\n" + e.toString(),
|
|
||||||
"Message sending error",
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,9 +345,7 @@ public class ChatWindow extends JFrame {
|
|||||||
* @param client the {@link Client} used to send and receive messages
|
* @param client the {@link Client} used to send and receive messages
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void setClient(Client client) {
|
public void setClient(Client client) { this.client = client; }
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link LocalDb} used by this {@link ChatWindow}. After
|
* Sets the {@link LocalDb} used by this {@link ChatWindow}. After
|
||||||
|
Reference in New Issue
Block a user