2020-02-05 20:58:30 +01:00
|
|
|
package envoy.client.data;
|
2019-12-21 21:23:19 +01:00
|
|
|
|
2020-09-25 14:29:23 +02:00
|
|
|
import java.io.*;
|
|
|
|
import java.util.*;
|
2019-12-21 21:23:19 +01:00
|
|
|
|
2020-09-25 19:19:54 +02:00
|
|
|
import javafx.collections.*;
|
|
|
|
|
2020-02-06 21:28:02 +01:00
|
|
|
import envoy.client.net.WriteProxy;
|
2020-09-25 14:29:23 +02:00
|
|
|
import envoy.data.*;
|
2020-02-01 10:20:06 +01:00
|
|
|
import envoy.data.Message.MessageStatus;
|
2020-06-20 10:00:38 +02:00
|
|
|
import envoy.event.MessageStatusChange;
|
2019-12-21 21:23:19 +01:00
|
|
|
|
|
|
|
/**
|
2020-06-26 23:36:14 +02:00
|
|
|
* Represents a chat between two {@link User}s
|
2019-12-21 21:23:19 +01:00
|
|
|
* as a list of {@link Message} objects.
|
|
|
|
*
|
|
|
|
* @author Maximilian Käfer
|
|
|
|
* @author Leon Hofmeister
|
|
|
|
* @author Kai S. K. Engelbart
|
2020-03-23 21:52:33 +01:00
|
|
|
* @since Envoy Client v0.1-alpha
|
2019-12-21 21:23:19 +01:00
|
|
|
*/
|
2020-07-05 14:38:19 +02:00
|
|
|
public class Chat implements Serializable {
|
2019-12-21 21:23:19 +01:00
|
|
|
|
2020-09-25 19:19:54 +02:00
|
|
|
protected transient ObservableList<Message> messages = FXCollections.observableArrayList();
|
2019-12-21 21:23:19 +01:00
|
|
|
|
2020-10-17 16:40:13 +02:00
|
|
|
protected int unreadAmount;
|
|
|
|
protected boolean disabled;
|
2020-07-12 14:34:07 +02:00
|
|
|
|
2020-10-17 16:40:13 +02:00
|
|
|
protected final Contact recipient;
|
2020-10-11 23:04:25 +02:00
|
|
|
|
2020-07-25 16:26:13 +02:00
|
|
|
/**
|
2020-07-25 17:12:24 +02:00
|
|
|
* Stores the last time an {@link envoy.event.IsTyping} event has been sent.
|
2020-07-25 16:26:13 +02:00
|
|
|
*/
|
|
|
|
protected transient long lastWritingEvent;
|
|
|
|
|
2020-09-25 19:19:54 +02:00
|
|
|
private static final long serialVersionUID = 2L;
|
2019-12-21 21:23:19 +01:00
|
|
|
|
|
|
|
/**
|
2020-07-03 13:47:40 +02:00
|
|
|
* Provides the list of messages that the recipient receives.
|
|
|
|
* <p>
|
2019-12-21 21:23:19 +01:00
|
|
|
* Saves the Messages in the corresponding chat at that Point.
|
|
|
|
*
|
|
|
|
* @param recipient the user who receives the messages
|
2020-03-23 21:52:33 +01:00
|
|
|
* @since Envoy Client v0.1-alpha
|
2019-12-21 21:23:19 +01:00
|
|
|
*/
|
2020-07-25 16:26:13 +02:00
|
|
|
public Chat(Contact recipient) { this.recipient = recipient; }
|
2019-12-21 21:23:19 +01:00
|
|
|
|
2020-09-25 19:19:54 +02:00
|
|
|
private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException {
|
|
|
|
stream.defaultReadObject();
|
|
|
|
messages = FXCollections.observableList((List<Message>) stream.readObject());
|
|
|
|
}
|
|
|
|
|
|
|
|
private void writeObject(ObjectOutputStream stream) throws IOException {
|
|
|
|
stream.defaultWriteObject();
|
|
|
|
stream.writeObject(new ArrayList<>(messages));
|
|
|
|
}
|
|
|
|
|
2020-03-29 09:16:29 +02:00
|
|
|
@Override
|
2020-10-13 23:51:02 +02:00
|
|
|
public String toString() {
|
2020-10-17 16:40:13 +02:00
|
|
|
return String.format(
|
|
|
|
"%s[recipient=%s,messages=%d,disabled=%b]",
|
|
|
|
getClass().getSimpleName(),
|
|
|
|
recipient,
|
|
|
|
messages.size(),
|
|
|
|
disabled
|
|
|
|
);
|
2020-10-13 23:51:02 +02:00
|
|
|
}
|
2020-03-29 09:16:29 +02:00
|
|
|
|
2020-06-12 10:48:33 +02:00
|
|
|
/**
|
|
|
|
* Generates a hash code based on the recipient.
|
2020-07-25 16:26:13 +02:00
|
|
|
*
|
2020-06-12 10:48:33 +02:00
|
|
|
* @since Envoy Client v0.1-beta
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public int hashCode() { return Objects.hash(recipient); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests equality to another object based on the recipient.
|
2020-07-25 16:26:13 +02:00
|
|
|
*
|
2020-06-12 10:48:33 +02:00
|
|
|
* @since Envoy Client v0.1-beta
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (this == obj) return true;
|
|
|
|
if (!(obj instanceof Chat)) return false;
|
2020-09-30 20:50:58 +02:00
|
|
|
final var other = (Chat) obj;
|
2020-06-12 10:48:33 +02:00
|
|
|
return Objects.equals(recipient, other.recipient);
|
|
|
|
}
|
|
|
|
|
2019-12-21 21:23:19 +01:00
|
|
|
/**
|
2020-02-03 06:57:19 +01:00
|
|
|
* Sets the status of all chat messages received from the recipient to
|
|
|
|
* {@code READ} starting from the bottom and stopping once a read message is
|
|
|
|
* found.
|
|
|
|
*
|
2020-02-06 21:28:02 +01:00
|
|
|
* @param writeProxy the write proxy instance used to notify the server about
|
|
|
|
* the message status changes
|
2020-03-23 21:52:33 +01:00
|
|
|
* @since Envoy Client v0.3-alpha
|
2019-12-21 21:23:19 +01:00
|
|
|
*/
|
2020-09-25 19:19:54 +02:00
|
|
|
public void read(WriteProxy writeProxy) {
|
2020-03-28 15:32:24 +01:00
|
|
|
for (int i = messages.size() - 1; i >= 0; --i) {
|
2020-09-30 20:50:58 +02:00
|
|
|
final var m = messages.get(i);
|
2020-10-17 16:40:13 +02:00
|
|
|
if (m.getSenderID() == recipient.getID())
|
|
|
|
if (m.getStatus() == MessageStatus.READ)
|
|
|
|
break;
|
|
|
|
else {
|
|
|
|
m.setStatus(MessageStatus.READ);
|
|
|
|
writeProxy.writeMessageStatusChange(new MessageStatusChange(m));
|
|
|
|
}
|
2020-02-05 07:09:25 +01:00
|
|
|
}
|
2020-07-12 14:34:07 +02:00
|
|
|
unreadAmount = 0;
|
2020-02-01 10:20:06 +01:00
|
|
|
}
|
2019-12-21 21:23:19 +01:00
|
|
|
|
2020-02-03 22:06:56 +01:00
|
|
|
/**
|
|
|
|
* @return {@code true} if the newest message received in the chat doesn't have
|
|
|
|
* the status {@code READ}
|
2020-03-23 21:52:33 +01:00
|
|
|
* @since Envoy Client v0.3-alpha
|
2020-02-03 22:06:56 +01:00
|
|
|
*/
|
2020-03-28 15:32:24 +01:00
|
|
|
public boolean isUnread() { return !messages.isEmpty() && messages.get(messages.size() - 1).getStatus() != MessageStatus.READ; }
|
2020-02-03 22:06:56 +01:00
|
|
|
|
2020-07-01 08:36:21 +02:00
|
|
|
/**
|
|
|
|
* Inserts a message at the correct place according to its creation date.
|
2020-07-25 16:26:13 +02:00
|
|
|
*
|
2020-07-01 08:36:21 +02:00
|
|
|
* @param message the message to insert
|
|
|
|
* @since Envoy Client v0.1-beta
|
|
|
|
*/
|
|
|
|
public void insert(Message message) {
|
2020-07-01 08:58:02 +02:00
|
|
|
for (int i = messages.size() - 1; i >= 0; --i)
|
2020-07-01 08:36:21 +02:00
|
|
|
if (message.getCreationDate().isAfter(messages.get(i).getCreationDate())) {
|
|
|
|
messages.add(i + 1, message);
|
2020-07-01 08:58:02 +02:00
|
|
|
return;
|
2020-07-01 08:36:21 +02:00
|
|
|
}
|
2020-07-01 08:58:02 +02:00
|
|
|
messages.add(0, message);
|
2020-07-01 08:36:21 +02:00
|
|
|
}
|
2020-09-30 20:50:58 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes the message with the given ID.
|
|
|
|
*
|
|
|
|
* @param messageID the ID of the message to remove
|
|
|
|
* @return whether the message has been found and removed
|
|
|
|
* @since Envoy Client v0.3-beta
|
|
|
|
*/
|
|
|
|
public boolean remove(long messageID) { return messages.removeIf(m -> m.getID() == messageID); }
|
2020-07-01 08:36:21 +02:00
|
|
|
|
2020-07-12 14:46:35 +02:00
|
|
|
/**
|
2020-07-12 16:27:20 +02:00
|
|
|
* Increments the amount of unread messages.
|
2020-07-25 16:26:13 +02:00
|
|
|
*
|
2020-07-12 14:46:35 +02:00
|
|
|
* @since Envoy Client v0.1-beta
|
|
|
|
*/
|
2020-10-04 21:53:58 +02:00
|
|
|
public void incrementUnreadAmount() { ++unreadAmount; }
|
2020-07-12 14:34:07 +02:00
|
|
|
|
2020-07-12 14:46:35 +02:00
|
|
|
/**
|
2020-07-25 16:26:13 +02:00
|
|
|
* @return the amount of unread messages in this chat
|
2020-07-12 14:46:35 +02:00
|
|
|
* @since Envoy Client v0.1-beta
|
|
|
|
*/
|
2020-07-12 14:34:07 +02:00
|
|
|
public int getUnreadAmount() { return unreadAmount; }
|
2020-07-10 22:41:59 +02:00
|
|
|
|
2019-12-21 21:23:19 +01:00
|
|
|
/**
|
|
|
|
* @return all messages in the current chat
|
2020-03-28 15:32:24 +01:00
|
|
|
* @since Envoy Client v0.1-beta
|
2019-12-21 21:23:19 +01:00
|
|
|
*/
|
2020-09-25 19:19:54 +02:00
|
|
|
public ObservableList<Message> getMessages() { return messages; }
|
2020-02-01 10:20:06 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the recipient of a message
|
2020-03-23 21:52:33 +01:00
|
|
|
* @since Envoy Client v0.1-alpha
|
2020-02-01 10:20:06 +01:00
|
|
|
*/
|
2020-04-02 09:23:47 +02:00
|
|
|
public Contact getRecipient() { return recipient; }
|
|
|
|
|
|
|
|
/**
|
2020-07-25 17:12:24 +02:00
|
|
|
* @return the last known time a {@link envoy.event.IsTyping} event has been
|
2020-07-25 16:51:46 +02:00
|
|
|
* sent
|
2020-07-25 16:26:13 +02:00
|
|
|
* @since Envoy Client v0.2-beta
|
|
|
|
*/
|
|
|
|
public long getLastWritingEvent() { return lastWritingEvent; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the {@code lastWritingEvent} to {@code System#currentTimeMillis()}.
|
|
|
|
*
|
|
|
|
* @since Envoy Client v0.2-beta
|
|
|
|
*/
|
|
|
|
public void lastWritingEventWasNow() { lastWritingEvent = System.currentTimeMillis(); }
|
2020-10-11 23:04:25 +02:00
|
|
|
|
|
|
|
/**
|
2020-10-17 16:40:13 +02:00
|
|
|
* Determines whether messages can be sent in this chat. Should be {@code true}
|
|
|
|
* i.e. for chats whose recipient deleted this client as a contact.
|
2020-10-11 23:04:25 +02:00
|
|
|
*
|
2020-10-17 16:40:13 +02:00
|
|
|
* @return whether this chat has been disabled
|
2020-10-11 23:04:25 +02:00
|
|
|
* @since Envoy Client v0.3-beta
|
|
|
|
*/
|
|
|
|
public boolean isDisabled() { return disabled; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines whether messages can be sent in this chat. Should be true i.e. for
|
|
|
|
* chats whose recipient deleted this client as a contact.
|
|
|
|
*
|
2020-10-17 16:40:13 +02:00
|
|
|
* @param disabled whether this chat should be disabled
|
2020-10-11 23:04:25 +02:00
|
|
|
* @since Envoy Client v0.3-beta
|
|
|
|
*/
|
|
|
|
public void setDisabled(boolean disabled) { this.disabled = disabled; }
|
2020-03-14 19:59:37 +01:00
|
|
|
}
|