Access restrictions, errors & properties

This commit is contained in:
2023-12-25 00:43:48 +02:00
parent a477a87c3d
commit 3c7845f439
22 changed files with 402 additions and 46 deletions
@@ -84,8 +84,13 @@ public class Connection {
}
connection.updateConnectionStats();
} catch (PacketException e) {
e.printStackTrace();
} catch (SocketException e) {
break;
} catch (IOException e) {
e.printStackTrace();
}
@@ -212,9 +217,19 @@ public class Connection {
}
try {
return getPacketManager().readPacket(getSocket().getInputStream());
Packet packet = getPacketManager().readPacket(getSocket().getInputStream());
if (packet.getType() == ErrorPacket.TYPE) {
ErrorPacket errorPacket = (ErrorPacket) packet;
throw new PacketException(packetManager.getPacketMap().get(errorPacket.getErrorType()), errorPacket.getReason());
}
return packet;
} catch (SocketException e) {
throw e;
} catch (IOException e) {
e.printStackTrace();
return null;
@@ -231,6 +246,7 @@ public class Connection {
if (packet.getType() != packetType) {
queuedPackets.add(packet);
updateConnectionStats();
continue;
}
@@ -0,0 +1,9 @@
package dev.wiing.gossip.client;
import dev.wiing.gossip.lib.packets.Packet;
public class PacketException extends RuntimeException {
public PacketException(Packet packet, String message) {
super("Packet of type=" + packet.getType() + " (" + packet.getClass().getSimpleName() + ") caused an error: " + message);
}
}
@@ -13,6 +13,7 @@ import dev.wiing.gossip.lib.packets.MessagePushPacket;
import dev.wiing.gossip.lib.packets.TopicJoinPacket;
import dev.wiing.gossip.lib.packets.TypingPingPacket;
import javafx.application.Platform;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
@@ -109,6 +110,13 @@ public class MainChatController {
});
updateTypingMembers();
txtCompose.getParagraphs().addListener((ListChangeListener<? super CharSequence>) c -> {
int height = 8 + Math.min(c.getList().size(), 5) * 17;
txtCompose.setMinHeight(height);
txtCompose.setPrefHeight(height);
});
}
private void setTopicName(String name) {
@@ -256,7 +264,12 @@ public class MainChatController {
}
public void updateTypingMembers() {
if (topic.getTypingUsersCount() == 0) {
int typingUsersCount = topic.getTypingUsersCount();
if (topic.getTypingUsersReadOnly().stream().anyMatch(user -> user.getUserID() == Connection.getInstance().getSelf().getUserID()))
--typingUsersCount;
if (typingUsersCount == 0) {
lblTyping.setText("");
lblTyping.setMinHeight(0);
lblTyping.setMaxHeight(0);
@@ -266,7 +279,7 @@ public class MainChatController {
lblTyping.setMinHeight(Region.USE_COMPUTED_SIZE);
lblTyping.setMaxHeight(Region.USE_COMPUTED_SIZE);
if (topic.getTypingUsersCount() > 3) {
if (typingUsersCount > 3) {
lblTyping.setText("Several babblers are writing...");
return;
}
@@ -274,11 +287,14 @@ public class MainChatController {
StringBuilder sb = new StringBuilder();
for (User user : topic.getTypingUsersReadOnly()) {
if (user.getUserID() == Connection.getInstance().getSelf().getUserID())
continue;
if (!sb.isEmpty()) sb.append(", ");
sb.append(user.getUsername());
}
sb.append(topic.getTypingUsersCount() == 1 ? " is" : " are");
sb.append(typingUsersCount == 1 ? " is" : " are");
sb.append(" writing...");
@@ -289,7 +305,4 @@ public class MainChatController {
return Utils.createInstance("views/chat-view.fxml");
}
}
// TODO: better mutliline input
// 25 + 17 per extra line
}
@@ -31,6 +31,7 @@ public class MainController implements Initializable {
Topic activeTopic = null;
Parent activeTopicElement = null;
private final Map<Long, Pair<Parent, MainChatController>> topicMap = new ConcurrentHashMap<>();
private final Map<Long, Thread> topicUpdateThreadMap = new ConcurrentHashMap<>();
@FXML
private VBox vboxRoot;
@@ -121,6 +122,10 @@ public class MainController implements Initializable {
for (LongData userID : packet.getUsersJoined()) {
User userJoined = Connection.getInstance().getUser(userID.getValue());
topic.addUser(userJoined);
if (userJoined.getUserID() == Connection.getInstance().getSelf().getUserID()) {
pullTopicMessages(topic);
}
}
}
@@ -139,7 +144,7 @@ public class MainController implements Initializable {
User author = Connection.getInstance().getUser(packet.getAuthorID());
UserMessage userMessage = new UserMessage(packet.getMessageID(), author, topic, packet.getContents());
UserMessage userMessage = new UserMessage(packet.getMessageID(), author, topic, packet.getContents(), packet.getCreatedTimestamp());
topic.addMessage(userMessage);
});
@@ -154,7 +159,7 @@ public class MainController implements Initializable {
targetUser = Connection.getInstance().getUser(packet.getUserID());
}
SystemMessage systemMessage = new SystemMessage(packet.getMessageID(), topic, packet.getSystemType(), targetUser, packet.getContent());
SystemMessage systemMessage = new SystemMessage(packet.getMessageID(), topic, packet.getSystemType(), targetUser, packet.getContent(), packet.getCreatedTimestamp());
topic.addMessage(systemMessage);
});
@@ -178,10 +183,12 @@ public class MainController implements Initializable {
}
private void fetchTopicMessage(Topic topic, long messageID) {
if (topic.hasMessageByID(messageID)) return;
MessageFetchPacket messageFetchPacket = new MessageFetchPacket();
messageFetchPacket.setMessageID(messageID);
messageFetchPacket.setTopicID(topic.getId());
Connection.getInstance().sendPacket(messageFetchPacket);
Connection.getInstance().sendPacketAuthenticated(messageFetchPacket);
try {
Packet messageFetchResult = Connection.getInstance().nextPacket(MessageDataPacket.TYPE);
@@ -195,7 +202,8 @@ public class MainController implements Initializable {
messageData.getMessageID(),
Connection.getInstance().getUser(messageData.getUserAuthorID()),
Connection.getInstance().getTopic(messageData.getTopicID()),
messageData.getUserContents()
messageData.getUserContents(),
messageData.getCreatedTimestamp()
);
}
else if (messageData.isSystemMessage()) {
@@ -204,7 +212,8 @@ public class MainController implements Initializable {
Connection.getInstance().getTopic(messageData.getTopicID()),
messageData.getSystemType(),
Connection.getInstance().getUser(messageData.getSystemUserID()),
messageData.getSystemContents()
messageData.getSystemContents(),
messageData.getCreatedTimestamp()
);
}
@@ -232,10 +241,6 @@ public class MainController implements Initializable {
AnchorPane.setRightAnchor(contentPair.first(), 0.0);
contentPair.first().setVisible(false);
MessageListFetchPacket messageListFetchPacket = new MessageListFetchPacket();
messageListFetchPacket.setTopicID(topic.getId());
Connection.getInstance().sendPacket(messageListFetchPacket);
Platform.runLater(() -> {
paneContent.getChildren().add(contentPair.first());
@@ -246,6 +251,16 @@ public class MainController implements Initializable {
setActiveTopic(topic, pair.first());
});
pullTopicMessages(topic);
}
private void pullTopicMessages(Topic topic) {
if (!topic.hasUser(Connection.getInstance().getSelf())) return;
MessageListFetchPacket messageListFetchPacket = new MessageListFetchPacket();
messageListFetchPacket.setTopicID(topic.getId());
Connection.getInstance().sendPacketAuthenticated(messageListFetchPacket);
try {
Packet messageListFetchResult = Connection.getInstance().nextPacket(MessageListDataPacket.TYPE);
if (messageListFetchResult == null) return;
@@ -259,6 +274,22 @@ public class MainController implements Initializable {
} catch (SocketException e) {
throw new RuntimeException(e);
}
long topicID = topic.getId();
Thread thread = new Thread(() -> {
while (topicMap.containsKey(topicID)) {
topic.updateAllRelativeTimes();
try {
Thread.sleep(30_000);
} catch (InterruptedException ignored) {
}
}
});
thread.start();
topicUpdateThreadMap.put(topicID, thread);
}
public void setActiveTopic(Topic topic, Parent element) {
@@ -6,6 +6,7 @@ import dev.wiing.gossip.client.generic.Pair;
import dev.wiing.gossip.client.utils.Utils;
import dev.wiing.gossip.lib.models.UserMessage;
import dev.wiing.gossip.lib.models.User;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
@@ -42,6 +43,7 @@ public class MessageItemController implements Initializable {
@Override
public void initialize(URL location, ResourceBundle resources) {
vboxMessages.getChildren().clear();
lblTimeAgo.setText("");
}
public User getAuthor() {
@@ -70,6 +72,10 @@ public class MessageItemController implements Initializable {
this.lblTag.getStyleClass().add("secondary");
}
if (userMessages.isEmpty()) {
userMessage.attachRelativeTime(data -> Platform.runLater(() -> lblTimeAgo.setText(data)));
}
userMessages.add(userMessage);
Label label = new Label(userMessage.getContents());
@@ -3,6 +3,7 @@ package dev.wiing.gossip.client.controllers.item;
import dev.wiing.gossip.client.generic.Pair;
import dev.wiing.gossip.client.utils.Utils;
import dev.wiing.gossip.lib.models.SystemMessage;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Parent;
@@ -32,6 +33,9 @@ public class SystemMessageItemController {
public void setSystemMessage(SystemMessage systemMessage) {
this.systemMessage = systemMessage;
lblTimeAgo.setText("");
systemMessage.attachRelativeTime(data -> Platform.runLater(() -> this.lblTimeAgo.setText(data)));
switch (this.systemMessage.getType()) {
case SystemMessage.SystemType.USER_JOIN:
removeNode(lblPrefix);
@@ -88,7 +88,7 @@
<String fx:value="list" />
</styleClass>
<children>
<TextArea fx:id="txtCompose" maxHeight="1.7976931348623157E308" minHeight="1.0" onKeyPressed="#onKeyPressed" onKeyTyped="#onKeyTyped" prefHeight="25.0" prefRowCount="1" promptText="Compose..." styleClass="transparent" wrapText="true" HBox.hgrow="ALWAYS" />
<TextArea fx:id="txtCompose" maxHeight="1.7976931348623157E308" minHeight="25.0" onKeyPressed="#onKeyPressed" onKeyTyped="#onKeyTyped" prefHeight="25.0" prefRowCount="1" promptText="Compose..." styleClass="transparent" wrapText="true" HBox.hgrow="ALWAYS" />
<ImageView fitHeight="20.0" fitWidth="20.0" onMouseClicked="#onSend" opacity="0.5" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../icons/icon-send-2.png" />