From 22ee07a5b3f6453237ee3f372d289abda1432b5c Mon Sep 17 00:00:00 2001 From: bloodwiing Date: Mon, 11 Dec 2023 18:07:31 +0200 Subject: [PATCH] A bunch of Packet changes --- .idea/compiler.xml | 5 - Client/pom.xml | 6 + .../dev/wiing/gossip/client/Connection.java | 109 ++++++- .../client/controllers/LoginController.java | 31 +- .../controllers/MainChatController.java | 114 ++++++++ .../client/controllers/MainController.java | 140 +++++++++ .../item/MainTopicItemController.java | 41 +++ .../wiing/gossip/client/data/UserAvatar.java | 102 +++++++ .../wiing/gossip/client/data/UserIcon.java | 72 ----- .../dev/wiing/gossip/client/generic/Pair.java | 20 ++ .../dev/wiing/gossip/client/utils/Utils.java | 57 ++++ Client/src/main/java/module-info.java | 3 + .../icon_0.png => avatars/avatar-0.png} | Bin .../icon_1.png => avatars/avatar-1.png} | Bin .../icon_2.png => avatars/avatar-2.png} | Bin .../icon_3.png => avatars/avatar-3.png} | Bin .../icon_4.png => avatars/avatar-4.png} | Bin .../icon_5.png => avatars/avatar-5.png} | Bin .../icon_6.png => avatars/avatar-6.png} | Bin .../icon_7.png => avatars/avatar-7.png} | Bin .../icon_8.png => avatars/avatar-8.png} | Bin .../icon_9.png => avatars/avatar-9.png} | Bin .../dev/wiing/gossip/client/custom.css | 11 + .../wiing/gossip/client/icons/door-enter.png | Bin 0 -> 4912 bytes .../client/{edit.png => icons/icon-edit.png} | Bin .../wiing/gossip/client/icons/icon-hash.png | Bin 0 -> 4749 bytes .../wiing/gossip/client/icons/icon-send-2.png | Bin 0 -> 5026 bytes .../dev/wiing/gossip/client/styling.css | 72 ++++- .../wiing/gossip/client/views/login-view.fxml | 7 +- .../gossip/client/views/main-chat-view.fxml | 165 +++++++++++ .../gossip/client/views/main-topic-item.fxml | 32 ++ .../wiing/gossip/client/views/main-view.fxml | 273 ++++++++++++++++-- .../dev/wiing/gossip/lib/PacketHandler.java | 10 + .../dev/wiing/gossip/lib/PacketManager.java | 22 +- .../dev/wiing/gossip/lib/data/StringType.java | 2 +- .../dev/wiing/gossip/lib/models/Message.java | 17 ++ .../dev/wiing/gossip/lib/models/Topic.java | 96 ++++++ .../dev/wiing/gossip/lib/models/User.java | 22 +- .../gossip/lib/packets/CreateTopicPacket.java | 72 +++++ .../gossip/lib/packets/FetchUserPacket.java | 37 +++ .../gossip/lib/packets/RegisterPacket.java | 18 +- .../gossip/lib/packets/TopicAddedPacket.java | 96 ++++++ .../gossip/lib/packets/UserDataPacket.java | 63 ++++ .../dev/wiing/gossip/server/Database.java | 63 +++- .../dev/wiing/gossip/server/UserSocket.java | 60 +++- 45 files changed, 1667 insertions(+), 171 deletions(-) create mode 100644 Client/src/main/java/dev/wiing/gossip/client/controllers/MainChatController.java create mode 100644 Client/src/main/java/dev/wiing/gossip/client/controllers/MainController.java create mode 100644 Client/src/main/java/dev/wiing/gossip/client/controllers/item/MainTopicItemController.java create mode 100644 Client/src/main/java/dev/wiing/gossip/client/data/UserAvatar.java delete mode 100644 Client/src/main/java/dev/wiing/gossip/client/data/UserIcon.java create mode 100644 Client/src/main/java/dev/wiing/gossip/client/generic/Pair.java create mode 100644 Client/src/main/java/dev/wiing/gossip/client/utils/Utils.java rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_0.png => avatars/avatar-0.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_1.png => avatars/avatar-1.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_2.png => avatars/avatar-2.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_3.png => avatars/avatar-3.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_4.png => avatars/avatar-4.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_5.png => avatars/avatar-5.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_6.png => avatars/avatar-6.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_7.png => avatars/avatar-7.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_8.png => avatars/avatar-8.png} (100%) rename Client/src/main/resources/dev/wiing/gossip/client/{icons/icon_9.png => avatars/avatar-9.png} (100%) create mode 100644 Client/src/main/resources/dev/wiing/gossip/client/custom.css create mode 100644 Client/src/main/resources/dev/wiing/gossip/client/icons/door-enter.png rename Client/src/main/resources/dev/wiing/gossip/client/{edit.png => icons/icon-edit.png} (100%) create mode 100644 Client/src/main/resources/dev/wiing/gossip/client/icons/icon-hash.png create mode 100644 Client/src/main/resources/dev/wiing/gossip/client/icons/icon-send-2.png create mode 100644 Client/src/main/resources/dev/wiing/gossip/client/views/main-chat-view.fxml create mode 100644 Client/src/main/resources/dev/wiing/gossip/client/views/main-topic-item.fxml create mode 100644 Lib/src/main/java/dev/wiing/gossip/lib/models/Message.java create mode 100644 Lib/src/main/java/dev/wiing/gossip/lib/models/Topic.java create mode 100644 Lib/src/main/java/dev/wiing/gossip/lib/packets/CreateTopicPacket.java create mode 100644 Lib/src/main/java/dev/wiing/gossip/lib/packets/FetchUserPacket.java create mode 100644 Lib/src/main/java/dev/wiing/gossip/lib/packets/TopicAddedPacket.java create mode 100644 Lib/src/main/java/dev/wiing/gossip/lib/packets/UserDataPacket.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index ede0b46..abaf24f 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -11,10 +11,5 @@ - - - - - \ No newline at end of file diff --git a/Client/pom.xml b/Client/pom.xml index 1a04367..8855526 100644 --- a/Client/pom.xml +++ b/Client/pom.xml @@ -45,6 +45,12 @@ ${junit.version} test + + org.jetbrains + annotations + 16.0.1 + compile + diff --git a/Client/src/main/java/dev/wiing/gossip/client/Connection.java b/Client/src/main/java/dev/wiing/gossip/client/Connection.java index c400349..efb88db 100644 --- a/Client/src/main/java/dev/wiing/gossip/client/Connection.java +++ b/Client/src/main/java/dev/wiing/gossip/client/Connection.java @@ -1,24 +1,37 @@ package dev.wiing.gossip.client; +import dev.wiing.gossip.lib.PacketHandler; import dev.wiing.gossip.lib.PacketManager; import dev.wiing.gossip.lib.models.SecretUser; +import dev.wiing.gossip.lib.models.User; +import dev.wiing.gossip.lib.packets.FetchUserPacket; import dev.wiing.gossip.lib.packets.Packet; +import dev.wiing.gossip.lib.packets.UserDataPacket; +import javafx.application.Platform; import java.io.IOException; import java.net.Socket; +import java.net.SocketException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; public class Connection { private static final Connection instance = new Connection(); - private final PacketManager packetManager; + private final PacketManager packetManager = new PacketManager(); + + private final PacketHandler packetHandler = new PacketHandler(); + + private Thread handlerThread; private Socket socket; private SecretUser self; + private final List queuedPackets = Collections.synchronizedList(new LinkedList<>()); + private Connection() { - packetManager = new PacketManager(); packetManager.registerPackets(); } @@ -30,6 +43,35 @@ public class Connection { return packetManager; } + public PacketHandler getPacketHandler() { + return packetHandler; + } + + public static class PacketHandlerRunnable implements Runnable { + private final Connection connection; + + public PacketHandlerRunnable(Connection connection) { + this.connection = connection; + } + + @Override + public void run() { + while (true) { + try { + Packet packet = connection.nextPacket(); + connection.getPacketHandler().runPacket(packet); + } catch (SocketException e) { + break; + } + } + } + } + + public void beginHandlingPackets() { + handlerThread = new Thread(new PacketHandlerRunnable(this)); + handlerThread.start(); + } + public Socket getSocket() { return socket; } @@ -46,20 +88,81 @@ public class Connection { } } - public Packet nextPacket() { + public Packet nextPacket(boolean useQueue) throws SocketException { + if (!queuedPackets.isEmpty()) { + return queuedPackets.remove(0); + } + try { return getPacketManager().readPacket(getSocket().getInputStream()); + } catch (SocketException e) { + throw e; } catch (IOException e) { e.printStackTrace(); return null; } } + public Packet nextPacket() throws SocketException { + return nextPacket(true); + } + + public Packet nextPacket(short packetType) throws SocketException { + while (true) { + Packet packet = nextPacket(false); + + if (packet.getType() != packetType) { + queuedPackets.add(packet); + continue; + } + + return packet; + } + } + public SecretUser getSelf() { return self; } public void setSelf(SecretUser self) { this.self = self; + + userCache.put(self.getUserID(), new User( + self.getUsername(), + self.getAvatarID(), + self.getUserID() + )); + } + + private final Map userCache = new ConcurrentHashMap<>(); + + public User getUser(long userID) { + User result; + + if ((result = userCache.getOrDefault(userID, null)) != null) { + return result; + } + + FetchUserPacket fetch = new FetchUserPacket(); + fetch.setUserID(userID); + Connection.getInstance().sendPacket(fetch); + + Packet resp; + try { + resp = Connection.getInstance().nextPacket(UserDataPacket.TYPE); + } catch (SocketException e) { + throw new RuntimeException(e); + } + if (resp.getType() == UserDataPacket.TYPE) { + UserDataPacket userData = (UserDataPacket)resp; + result = new User( + userData.getUsername(), + userData.getAvatarID(), + userData.getUserID() + ); + userCache.put(result.getUserID(), result); + } + + return result; } } diff --git a/Client/src/main/java/dev/wiing/gossip/client/controllers/LoginController.java b/Client/src/main/java/dev/wiing/gossip/client/controllers/LoginController.java index 95105ab..119daad 100644 --- a/Client/src/main/java/dev/wiing/gossip/client/controllers/LoginController.java +++ b/Client/src/main/java/dev/wiing/gossip/client/controllers/LoginController.java @@ -2,7 +2,7 @@ package dev.wiing.gossip.client.controllers; import dev.wiing.gossip.client.Connection; -import dev.wiing.gossip.client.data.UserIcon; +import dev.wiing.gossip.client.data.UserAvatar; import dev.wiing.gossip.lib.models.SecretUser; import dev.wiing.gossip.lib.packets.CredentialsPacket; import dev.wiing.gossip.lib.packets.Packet; @@ -12,12 +12,15 @@ import javafx.event.ActionEvent; import javafx.event.Event; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.Scene; import javafx.scene.control.TextField; import javafx.scene.input.MouseEvent; import javafx.scene.layout.*; import javafx.scene.shape.Circle; +import javafx.stage.Stage; import javafx.util.Duration; +import java.net.SocketException; import java.net.URL; import java.util.ResourceBundle; @@ -34,15 +37,7 @@ public class LoginController implements Initializable { @Override public void initialize(URL location, ResourceBundle resources) { - paneIcon.setBackground(new Background( - new BackgroundImage( - UserIcon.MORNING.getImage(), - BackgroundRepeat.NO_REPEAT, - BackgroundRepeat.NO_REPEAT, - BackgroundPosition.CENTER, - new BackgroundSize(100.0, 100.0, true, true, false, true) - ) - )); + UserAvatar.MORNING.applyToRegionBackground(paneIcon, false); Circle circle = new Circle(paneIcon.getMinWidth() * 0.5); paneIcon.setShape(circle); @@ -57,17 +52,27 @@ public class LoginController implements Initializable { @FXML public void onLogin(ActionEvent event) { RegisterPacket packet = new RegisterPacket(); - packet.setIconID((char)0); + packet.setAvatarID((byte)0); packet.setUsername(txtUsername.getText()); Connection.getInstance().sendPacket(packet); - Packet result = Connection.getInstance().nextPacket(); + Packet result = null; + try { + result = Connection.getInstance().nextPacket(); + } catch (SocketException e) { + throw new RuntimeException(e); + } + if (result != null && result.getType() == CredentialsPacket.TYPE) { CredentialsPacket creds = (CredentialsPacket)result; - SecretUser user = new SecretUser(packet.getUsername(), packet.getIconID(), creds.getUID(), creds.getSecret()); + SecretUser user = new SecretUser(packet.getUsername(), packet.getAvatarID(), creds.getUID(), creds.getSecret()); Connection.getInstance().setSelf(user); + + var pair = MainController.createInstance(); + + ((Stage)Stage.getWindows().get(0)).setScene(new Scene(pair.first())); } } diff --git a/Client/src/main/java/dev/wiing/gossip/client/controllers/MainChatController.java b/Client/src/main/java/dev/wiing/gossip/client/controllers/MainChatController.java new file mode 100644 index 0000000..91c1c5e --- /dev/null +++ b/Client/src/main/java/dev/wiing/gossip/client/controllers/MainChatController.java @@ -0,0 +1,114 @@ +package dev.wiing.gossip.client.controllers; + +import dev.wiing.gossip.client.Connection; +import dev.wiing.gossip.client.generic.Pair; +import dev.wiing.gossip.client.utils.Utils; +import dev.wiing.gossip.lib.models.Topic; +import dev.wiing.gossip.lib.models.User; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.Parent; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.VBox; + +import java.net.URL; +import java.util.List; +import java.util.ResourceBundle; + +public class MainChatController { + + private Topic topic; + + @FXML + private Label lblBabblersCount; + + @FXML + private Label lblTopicName; + + @FXML + private Label lblTyping; + + @FXML + private Label lblVisitBabblerCount; + + @FXML + private Label lblVisitHostName; + + @FXML + private Label lblVisitTopicDescription; + + @FXML + private Label lblVisitTopicName; + + @FXML + private TextArea txtCompose; + + @FXML + private VBox vboxChatPage; + + @FXML + private VBox vboxMessages; + + @FXML + private VBox vboxVisitPage; + + public void setTopic(Topic topic) { + this.topic = topic; + + boolean participating = topic.hasUser(Connection.getInstance().getSelf()); + togglePages(participating); + + setTopicName(topic.getName()); + lblVisitTopicDescription.setText(topic.getDescription()); + setBabblerCount(topic.getUsersReadOnly().size()); + lblVisitHostName.setText(topic.getHost().getUsernameDisplay()); + + this.topic.addChangeListener(evt -> { + if (evt.getPropertyName().equals("userAdd") || evt.getPropertyName().equals("userRemove")) { + setBabblerCount(topic.getUsersReadOnly().size()); + } + }); + } + + private void setTopicName(String name) { + lblTopicName.setText(name); + lblVisitTopicName.setText(name); + } + + private void setBabblerCount(int count) { + String res = "No Babblers"; + if (count == 1) { + res = "1 Babbler"; + } else if (count > 1) { + res = Integer.toString(count) + " Babblers"; + } + + lblBabblersCount.setText(res); + lblVisitBabblerCount.setText(res + " active"); + } + + private void togglePages(boolean participating) { + vboxChatPage.setVisible(participating); + vboxVisitPage.setVisible(!participating); + } + + @FXML + void onJoinTopic(ActionEvent event) { + topic.addUser(Connection.getInstance().getSelf()); + + togglePages(true); + } + + @FXML + void onSend(MouseEvent event) { + + } + + public static Pair createInstance() { + return Utils.createInstance("views/main-chat-view.fxml"); + } + +} diff --git a/Client/src/main/java/dev/wiing/gossip/client/controllers/MainController.java b/Client/src/main/java/dev/wiing/gossip/client/controllers/MainController.java new file mode 100644 index 0000000..42bab5b --- /dev/null +++ b/Client/src/main/java/dev/wiing/gossip/client/controllers/MainController.java @@ -0,0 +1,140 @@ +package dev.wiing.gossip.client.controllers; + +import dev.wiing.gossip.client.Connection; +import dev.wiing.gossip.client.controllers.item.MainTopicItemController; +import dev.wiing.gossip.client.data.UserAvatar; +import dev.wiing.gossip.client.generic.Pair; +import dev.wiing.gossip.client.utils.Utils; +import dev.wiing.gossip.lib.models.Topic; +import dev.wiing.gossip.lib.models.User; +import dev.wiing.gossip.lib.packets.*; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.Parent; +import javafx.scene.control.Label; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; + +import java.net.URL; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.concurrent.ConcurrentHashMap; + +public class MainController implements Initializable { + + Topic activeTopic = null; + Parent activeTopicElement = null; + private final Map topicContentMap = new ConcurrentHashMap<>(); + + @FXML + private VBox vboxRoot; + + @FXML + private VBox vboxTopics; + + @FXML + private Label lblUsername; + + @FXML + private Pane paneIcon; + + @FXML + private AnchorPane paneContent; + + @FXML + private Label lblJoinMessage; + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + User user = Connection.getInstance().getSelf(); + lblUsername.setText(user.getUsernameDisplay()); + + UserAvatar.getAvatar(user.getAvatarID()).applyToRegionBackground(paneIcon, true); + + Connection.getInstance().getPacketHandler().addListener(TopicAddedPacket.class, packet -> { + User host = Connection.getInstance().getUser(packet.getHostID()); + + Topic topic = new Topic( + packet.getTopicID(), + packet.getTopicName(), + packet.getTopicDescription(), + host, + packet.getTopicColor() + ); + + var pair = MainTopicItemController.createInstance(); + pair.second().setTopic(topic); + + var contentPair = MainChatController.createInstance(); + contentPair.second().setTopic(topic); + + topicContentMap.put(topic.getId(), contentPair.first()); + + AnchorPane.setLeftAnchor(contentPair.first(), 0.0); + AnchorPane.setBottomAnchor(contentPair.first(), 0.0); + AnchorPane.setTopAnchor(contentPair.first(), 0.0); + AnchorPane.setRightAnchor(contentPair.first(), 0.0); + contentPair.first().setVisible(false); + + Platform.runLater(() -> { + paneContent.getChildren().add(contentPair.first()); + + vboxTopics.getChildren().add(pair.first()); + }); + + pair.second().setOnMouseClicked(event -> { + setActiveTopic(topic, pair.first()); + }); + }); + + Connection.getInstance().beginHandlingPackets(); + + vboxTopics.getChildren().clear(); + } + + public void setActiveTopic(Topic topic, Parent element) { + if (activeTopic != null) { + activeTopicElement.getStyleClass().remove("tag-min"); + topicContentMap.get(activeTopic.getId()).setVisible(false); + } else { + lblJoinMessage.setVisible(false); + } + + if (topic == null) { + activeTopic = null; + activeTopicElement = null; + + lblJoinMessage.setVisible(true); + + vboxRoot.setStyle("-accent: hsb(250, 10%, 50%);"); + return; + } + + vboxRoot.setStyle("-accent: hsb(" + topic.getColor() + ", 70%, 100%);"); + + element.getStyleClass().add("tag-min"); + + activeTopic = topic; + activeTopicElement = element; + + topicContentMap.get(activeTopic.getId()).setVisible(true); + } + + @FXML + void onCreateTopic(ActionEvent event) { + CreateTopicPacket packet = new CreateTopicPacket(); + packet.setUserSecret(Connection.getInstance().getSelf().getUserSecret()); + packet.setTopicName("Point Nemo"); + packet.setTopicDescription("We are so gone XDD"); + + Connection.getInstance().sendPacket(packet); + } + + public static Pair createInstance() { + return Utils.createInstance("views/main-view.fxml"); + } + +} diff --git a/Client/src/main/java/dev/wiing/gossip/client/controllers/item/MainTopicItemController.java b/Client/src/main/java/dev/wiing/gossip/client/controllers/item/MainTopicItemController.java new file mode 100644 index 0000000..db76afd --- /dev/null +++ b/Client/src/main/java/dev/wiing/gossip/client/controllers/item/MainTopicItemController.java @@ -0,0 +1,41 @@ +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.Topic; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.Parent; +import javafx.scene.control.Label; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.HBox; + +public class MainTopicItemController { + + private Topic topic; + + @FXML + private HBox hboxParent; + + @FXML + private Label lblTopicName; + + public void setTopic(Topic topic) { + this.topic = topic; + this.lblTopicName.setText(topic.getName()); + } + + public Topic getTopic() { + return topic; + } + + public static Pair createInstance() { + return Utils.createInstance("views/main-topic-item.fxml"); + } + + public void setOnMouseClicked(EventHandler eventHandler) { + hboxParent.setOnMouseClicked(eventHandler); + } + +} diff --git a/Client/src/main/java/dev/wiing/gossip/client/data/UserAvatar.java b/Client/src/main/java/dev/wiing/gossip/client/data/UserAvatar.java new file mode 100644 index 0000000..6ff88e0 --- /dev/null +++ b/Client/src/main/java/dev/wiing/gossip/client/data/UserAvatar.java @@ -0,0 +1,102 @@ +package dev.wiing.gossip.client.data; + +import dev.wiing.gossip.client.Program; +import javafx.scene.image.Image; +import javafx.scene.layout.*; +import javafx.scene.shape.Circle; + +import java.io.IOException; +import java.net.URL; +import java.util.Arrays; + +public class UserAvatar { + + public static final UserAvatar MORNING = new UserAvatar("Morning", "Eggs and Bacon", 0, "avatars/avatar-0.png"); + public static final UserAvatar VINTAGE = new UserAvatar("Vintage", "Red Car", 1, "avatars/avatar-1.png"); + public static final UserAvatar ROUTINE = new UserAvatar("Routine", "Coffee Cup", 2, "avatars/avatar-2.png"); + public static final UserAvatar SILLY = new UserAvatar("Silly", "Ghost Toy", 3, "avatars/avatar-3.png"); + public static final UserAvatar ADVENTURE = new UserAvatar("Adventure", "Slide with a Plant", 4, "avatars/avatar-4.png"); + public static final UserAvatar REBELLION = new UserAvatar("Rebellion", "Potted Cactus", 5, "avatars/avatar-5.png"); + public static final UserAvatar DIGITAL = new UserAvatar("Digital", "Game Controller", 6, "avatars/avatar-6.png"); + public static final UserAvatar MYSTERY = new UserAvatar("Mystery", "Floating Sphere", 7, "avatars/avatar-7.png"); + public static final UserAvatar VACATION = new UserAvatar("Vacation", "Cat under an Umbrella", 8, "avatars/avatar-8.png"); + public static final UserAvatar SIMPLE = new UserAvatar("Simple", "Potted Succulent", 9, "avatars/avatar-9.png"); + + public static UserAvatar getAvatar(int avatarID) { + return Arrays.stream(getAvatars()) + .skip(avatarID) + .findFirst() + .orElse(null); + } + + public static UserAvatar[] getAvatars() { + return new UserAvatar[]{ + MORNING, + VINTAGE, + ROUTINE, + SILLY, + ADVENTURE, + REBELLION, + DIGITAL, + MYSTERY, + VACATION, + SIMPLE + }; + } + + private final String name; + private final String description; + private final int id; + private final URL url; + + private UserAvatar(String name, String description, int id, String path) { + this.name = name; + this.description = description; + this.id = id; + this.url = Program.class.getResource(path); + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public int getId() { + return id; + } + + public URL getUrl() { + return url; + } + + public Image getImage() { + try { + return new Image(url.openStream()); + } catch (IOException e) { + return null; + } + } + + public void applyToRegionBackground(Region region, boolean applyShape) { + if (getImage() == null) return; + + region.setBackground(new Background( + new BackgroundImage( + getImage(), + BackgroundRepeat.NO_REPEAT, + BackgroundRepeat.NO_REPEAT, + BackgroundPosition.CENTER, + new BackgroundSize(100.0, 100.0, true, true, false, true) + ) + )); + region.setStyle(""); + + if (applyShape) { + Circle circle = new Circle(region.getMinWidth() * 0.5); + region.setShape(circle); + } + } +} diff --git a/Client/src/main/java/dev/wiing/gossip/client/data/UserIcon.java b/Client/src/main/java/dev/wiing/gossip/client/data/UserIcon.java deleted file mode 100644 index fc7d2b8..0000000 --- a/Client/src/main/java/dev/wiing/gossip/client/data/UserIcon.java +++ /dev/null @@ -1,72 +0,0 @@ -package dev.wiing.gossip.client.data; - -import dev.wiing.gossip.client.Program; -import javafx.scene.image.Image; - -import java.io.IOException; -import java.net.URL; - -public class UserIcon { - - public static final UserIcon MORNING = new UserIcon("Morning", "Eggs and Bacon", 0, "icons/icon_0.png"); - public static final UserIcon VINTAGE = new UserIcon("Vintage", "Red Car", 1, "icons/icon_1.png"); - public static final UserIcon ROUTINE = new UserIcon("Routine", "Coffee Cup", 2, "icons/icon_2.png"); - public static final UserIcon SILLY = new UserIcon("Silly", "Ghost Toy", 3, "icons/icon_3.png"); - public static final UserIcon ADVENTURE = new UserIcon("Adventure", "Slide with a Plant", 4, "icons/icon_4.png"); - public static final UserIcon REBELLION = new UserIcon("Rebellion", "Potted Cactus", 5, "icons/icon_5.png"); - public static final UserIcon DIGITAL = new UserIcon("Digital", "Game Controller", 6, "icons/icon_6.png"); - public static final UserIcon MYSTERY = new UserIcon("Mystery", "Floating Sphere", 7, "icons/icon_7.png"); - public static final UserIcon VACATION = new UserIcon("Vacation", "Cat under an Umbrella", 8, "icons/icon_8.png"); - public static final UserIcon SIMPLE = new UserIcon("Simple", "Potted Succulent", 9, "icons/icon_9.png"); - - public static UserIcon[] getIcons() { - return new UserIcon[]{ - MORNING, - VINTAGE, - ROUTINE, - SILLY, - ADVENTURE, - REBELLION, - DIGITAL, - MYSTERY, - VACATION, - SIMPLE - }; - } - - private final String name; - private final String description; - private final int id; - private final URL url; - - private UserIcon(String name, String description, int id, String path) { - this.name = name; - this.description = description; - this.id = id; - this.url = Program.class.getResource(path); - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public int getId() { - return id; - } - - public URL getUrl() { - return url; - } - - public Image getImage() { - try { - return new Image(url.openStream()); - } catch (IOException e) { - return null; - } - } -} diff --git a/Client/src/main/java/dev/wiing/gossip/client/generic/Pair.java b/Client/src/main/java/dev/wiing/gossip/client/generic/Pair.java new file mode 100644 index 0000000..c06836d --- /dev/null +++ b/Client/src/main/java/dev/wiing/gossip/client/generic/Pair.java @@ -0,0 +1,20 @@ +package dev.wiing.gossip.client.generic; + +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public record Pair(@NotNull U first, @NotNull V second) { + + public static Pair cast(Pair second) { + return new Pair<>(second.first, second.second); + } + + @Override + public String toString() { + return "Pair[" + + "first=" + first + ", " + + "second=" + second + ']'; + } + +} diff --git a/Client/src/main/java/dev/wiing/gossip/client/utils/Utils.java b/Client/src/main/java/dev/wiing/gossip/client/utils/Utils.java new file mode 100644 index 0000000..942269a --- /dev/null +++ b/Client/src/main/java/dev/wiing/gossip/client/utils/Utils.java @@ -0,0 +1,57 @@ +package dev.wiing.gossip.client.utils; + +import dev.wiing.gossip.client.Program; +import dev.wiing.gossip.client.generic.Pair; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.stage.Stage; + +import java.io.IOException; +import java.util.Arrays; + +public class Utils { + + public static Pair createInstance(String res) { + FXMLLoader loader = new FXMLLoader(Program.class.getResource(res)); + + Parent parent; + try { + parent = loader.load(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + T controller = loader.getController(); + + return new Pair<>(parent, controller); + } + + public static void openParentAsWindow(Parent parent, String title) { + Stage stage = new Stage(); + stage.setTitle(title); + stage.setScene(new Scene(parent)); + stage.show(); + } + + public static void updateLabelColorOnText(Label label, TextField... texts) { + for (TextField text : texts) { + text.setOnKeyTyped(keyEvent -> updateLabelColorOnTextCallback(label, texts)); + } + } + + private static void updateLabelColorOnTextCallback(Label label, TextField... texts) { + boolean hadItems = label.getStyleClass().contains("accent"); + + if (Arrays.stream(texts).allMatch(textField -> textField.getText().isEmpty())) { + label.getStyleClass().remove("accent"); + } + else if (Arrays.stream(texts).allMatch(textField -> !textField.getText().isEmpty() && !hadItems)) { + label.getStyleClass().add("accent"); + } + } + +} diff --git a/Client/src/main/java/module-info.java b/Client/src/main/java/module-info.java index 9736d4f..41d05ac 100644 --- a/Client/src/main/java/module-info.java +++ b/Client/src/main/java/module-info.java @@ -2,8 +2,11 @@ module dev.wiing.gossip.client { requires javafx.controls; requires javafx.fxml; requires dev.wiing.gossip.lib; + requires annotations; + requires java.desktop; exports dev.wiing.gossip.client; opens dev.wiing.gossip.client to javafx.fxml; opens dev.wiing.gossip.client.controllers to javafx.fxml; + opens dev.wiing.gossip.client.controllers.item to javafx.fxml; } \ No newline at end of file diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_0.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-0.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_0.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-0.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_1.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-1.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_1.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-1.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_2.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-2.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_2.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-2.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_3.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-3.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_3.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-3.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_4.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-4.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_4.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-4.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_5.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-5.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_5.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-5.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_6.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-6.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_6.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-6.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_7.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-7.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_7.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-7.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_8.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-8.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_8.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-8.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon_9.png b/Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-9.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/icons/icon_9.png rename to Client/src/main/resources/dev/wiing/gossip/client/avatars/avatar-9.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/custom.css b/Client/src/main/resources/dev/wiing/gossip/client/custom.css new file mode 100644 index 0000000..68a6b85 --- /dev/null +++ b/Client/src/main/resources/dev/wiing/gossip/client/custom.css @@ -0,0 +1,11 @@ +.gradient { + -fx-background-color: radial-gradient(radius 130%, ladder(#eee, -accent, #111), #111); +} + +.topic-button.clickable:hover { + -fx-background-color: #fff1; +} + +.topic-button.clickable.tag-min:hover { + -fx-background-color: ladder(hsb(0, 0%, 50%), -color, #0000); +} \ No newline at end of file diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/door-enter.png b/Client/src/main/resources/dev/wiing/gossip/client/icons/door-enter.png new file mode 100644 index 0000000000000000000000000000000000000000..f43fdcaec16b1031ad582590839e5ba86dc2699e GIT binary patch literal 4912 zcmeHKc~}$I7M}!#$nM@MN(g-gp_62?ClUc6KrGP+5wVJPl9|9jHj_YtqDHM-U8)FH zl=lSp-RIIOB8rx3)ruQSOVMhd618qmt5ijKcfumP_WR!F_r3nd&3ALpoO{mip8LD! zo@ACN$Hx134)KH_$VZ+Kn*_!vveVqb_fBH^bue7QQ{`H@JPe|N2VhC*1yM*F&?#MH zD#Z?oFcyQ(0rCJa?gX7!)V9`f zAd`*e`Xm5}MD7^l6~@(mVRGTUG71^2@R@Ez^=R`u^+W^vLViW;Ry1 zwLIe_Usy3cs`jJc!o^-i_jmf|$!JoV#{YFc?lbZD#8Z~MYu}uyFMsdilTpo1TDW*M zWz<~zn!5{S$D$)Dh`YtjOM-WYj;L~0Y24FR{=Vwh1Luv!UcRq#wN(k*nwA7tjV@h& zTcDN2{Ouo%6=6H$Uc6a$-qQ(JXO^8?*L;iRefv-$zV~WC9Cc~xJQ{_wGqlv(3;Bef zl(;z~^5M-ua|@#kGZ$8Vx8LEZN>~xt;y2rt)f5uaxLFx+CvX3QFZ$Atc=0m7emzU~ z)AIiG$KF#2c+M8z@ALAfW)YWzOKd}r95E12hMUUVyd&=B2Z@s$TO&7kT)%i{{eh^T z;Y$@w&+8h`+;v;Ib#K0~@?;SElal+{U)XG4H9vn;q@5EPQ)w=!3nf4T_}B?msx?)S zDA5@8OcXP!ai(2wA`c9Th_stfO%`sYtMPQgAZ0u%Kf$0An3OS*uV5=oF?a@%FvE-| z&ls!H%*fJ+F-GJl&j`B&0O)ZmO1JBE28+ZlWw>x9Kql2J2Hj<1&5|-wK_0~z%{ZOM z%ueKR7^6Jt5oSy)Ns5hYhX7AfMuydDlCW4dn~iDXGL7bR79tjlS!@oA!-0VX zY{@lPQ9Ep~1d|YL7_qoTVi!f2qAn5f#AZIv<@V4mI)pWdWUbix}f?JNL3Sa#IJ zLYQopUeD_4VX?|`07!d4f9hdT<(hC-5^gbOn>DyB2RB%QyFy@^PJdIjS?AggreWba zTn|hwU{$2slH`r+^dKonC-f$l7a+TvrIpaWC97L(}B`ow(hsJNE7}2387% zB-W_OCc~4*N*Uz(63nO}Fo{bPVM0ueaoI4!(TZRmhH+uFnlFU;T9kwF`64lfXuCkk z4HheE(BLE#0A~^ahr>n$Vl_t%YsG2+fpgWcTEpkUJduDcM0sj1F6as|&P;%;M0H)G zBB3x63d03l5z2uzLR0|rczgsFX?Q|dB;<(2T!8=q0lA{VG?F-@S&xF_B=l%H&N3O& zT@xhXl4zw|%HS~BZ#7CCYSjVEfM& zn=K#{NlaJmbh(qqA_1EL#G+)L0sxmD>_rk|#!;)$tTGyPQbuRh?VMJC>x7|JG#0hu z0JO6Xt2*j%IGZD3w*^4LDU2AQ&HZ22>2BbiES;?_}JQUH><_Jm0=f;Rf(8$Oc}Pc3p)k!Hbr=`s4UmsFnPb zRBT%fG<{47lPnPA)t~GXXkGDpKqeheHtcf;=`_Wp8+}t~_hN z_yLPfl;=7I{d?|7kG_ZM1f%>_v9bI6%XE2;zt3B~pkY!&>W<}py@Eb(b<~{>-F~D0 z$#bC_7w?v-YZy%j-$&E5zwBLKbbstazpZ66ZPmq(8fRAjIMQo8XqME{Le{RObB9&B zmjvD+ZsweDI4igKpGuvaoIJCZn^{{_|Idc2)z!^AY~N4(b=&^HnsbRSl8GxXJWT_C zDB?OFdcT_N2#K0dvE%vRVXtT1Q&nFM96vKz_b4UgUX$;@HN95fiG;4KNgrtMm6vsM z(ub?>O!W;~RzK3O(Y>jDmNWcP;OMnsjF;iHXA2fzOaAg!h7f)-=Qov)3~tqr@MCZB zZMxsm?ClJx*&}<{S~0>8DVlipW&Ev>eEoPkHPP)-?b&MEVRXZ)!pG2Ts)wUo;jqQ! zV|~M;uJIMOvh)JWEakYb8zXM}M5S$>eRjv;wMor~8v8Wuj;8N34>@qOK8N~v_;&|O zbL$^M*CD6nXfxYXx@T7uE&AC2wx4JX^1#F7`Fl;(o}Z}~N7GghyX>(&?cM^SU&F`Q zKk90njG?7*^p9Au!#(Jj^2;@YqUQTA9OF|$q1C30JeCtSe^Twu!6xdFwUgNdQSRbMZ}_wxkQR3D!+0?y^j&9 zyU+*XpQzC)4tmnXJIYkT7E#%il*DNV@Vy_T7Zh@CIhfB%X2eL>A2TV|*KfMMZ{#h} zq?d8qPro@m;MJxr#?LZ&E0IA>o{lRib7^$yVu<1R!w{NU)as|Kr^e46c=l41d*$TJ zzQ*)7^>5;DjG^6}(69&{;*573&+j$E`-cMepe(O|5v!hla6G{9p~r6prt)Ti+l?^x zREG0RzYRmqQ{=-_-2$j7*+-sks(j{uDr+Oz-qabB)lWC}K0ikVavhS(#>Va){pq~_ E035&JzW@LL literal 0 HcmV?d00001 diff --git a/Client/src/main/resources/dev/wiing/gossip/client/edit.png b/Client/src/main/resources/dev/wiing/gossip/client/icons/icon-edit.png similarity index 100% rename from Client/src/main/resources/dev/wiing/gossip/client/edit.png rename to Client/src/main/resources/dev/wiing/gossip/client/icons/icon-edit.png diff --git a/Client/src/main/resources/dev/wiing/gossip/client/icons/icon-hash.png b/Client/src/main/resources/dev/wiing/gossip/client/icons/icon-hash.png new file mode 100644 index 0000000000000000000000000000000000000000..bdc27ed253211c8fbb60d5526588043ae686c246 GIT binary patch literal 4749 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 literal 0 HcmV?d00001 diff --git a/Client/src/main/resources/dev/wiing/gossip/client/styling.css b/Client/src/main/resources/dev/wiing/gossip/client/styling.css index 1545f52..ab0a444 100644 --- a/Client/src/main/resources/dev/wiing/gossip/client/styling.css +++ b/Client/src/main/resources/dev/wiing/gossip/client/styling.css @@ -19,10 +19,10 @@ -fx-background-radius: 16px; } -.list.container .viewport, +.list.container > .viewport, .section, .pane.list.container { - -fx-background-color: #19191d; + -fx-background-color: #88f1; } .list.container.dim .viewport { @@ -34,12 +34,12 @@ SplitPane { } SplitPane .split-pane-divider { - -fx-background-color: #19191d; + -fx-background-color: #88f1; -fx-padding: 0.0 5.0 0.0 0.0; } .elevated { - -fx-background-color: #25252c; + -fx-background-color: #88f2; } .border-radius { @@ -52,18 +52,29 @@ SplitPane .split-pane-divider { Label, RadioButton, -TextField { +TextField, +TextArea { -fx-text-fill: #fff; -fx-fill: #fff; } +TextArea, +TextArea .scroll-pane { + -fx-background-color: transparent; +} + +TextArea .scroll-pane .content { + -fx-background-color: red; +} + ChoiceBox, -TextField { - -fx-background-color: #19191d; +TextField, +TextArea .scroll-pane .content { + -fx-background-color: #88f1; } ColorPicker { - -fx-background-color: #29292F; + -fx-background-color: #88f1; -fx-padding: 4px 14px; } @@ -77,6 +88,12 @@ ColorPicker { -fx-fill: #556; } +.transparent, +.transparent.list.container .viewport, +TextArea.transparent .scroll-pane .content { + -fx-background-color: transparent; +} + .accent { -fx-text-fill: -accent; } @@ -85,15 +102,10 @@ Separator { -fx-opacity: 0.1; } -Button { - -fx-background-color: -accent; - -fx-background-insets: 0; - -fx-text-fill: white; - -fx-padding: 4px 14px; -} - -Button.gray { +Button.secondary { -fx-background-color: #4a4a55; + -fx-border-width: 0px; + -fx-text-fill: white; } Button, @@ -101,6 +113,17 @@ Button, -fx-cursor: hand; } +Button:hover { + -fx-background-color: ladder(hsb(0, 0%, 40%), -color, #0000); + -fx-text-fill: ladder(hsb(0, 0%, 50%), -color, #fff); + -fx-border-color: ladder(hsb(0, 0%, 50%), -color, #fff); +} + +Button.secondary:hover { + -fx-background-color: #6c6c80; + -fx-text-fill: white; +} + ChoiceBox { -fx-background-insets: 0; } @@ -109,7 +132,9 @@ ChoiceBox { -fx-font-family: "AXIS Extra Bold"; } +Button, Label.tag { + -color: -accent; -fx-background-color: ladder(hsb(0, 0%, 70%), -color, #0000); -fx-background-radius: 8px; -fx-border-radius: 8px; @@ -119,6 +144,21 @@ Label.tag { -fx-padding: 6px 14px; } +.tag-min { + -color: -accent; + -fx-background-color: ladder(hsb(0, 0%, 60%), -color, #0000); + -fx-text-fill: -color; +} + +Label.tag.small { + -fx-background-color: -color; + -fx-background-radius: 4px; + -fx-border-width: 0; + -fx-text-fill: white; + -fx-font-size: 10px; + -fx-padding: 2px 8px; +} + CheckBox .box { -fx-background-color: #25252c; } diff --git a/Client/src/main/resources/dev/wiing/gossip/client/views/login-view.fxml b/Client/src/main/resources/dev/wiing/gossip/client/views/login-view.fxml index 8d2ee5c..8c4c8f6 100644 --- a/Client/src/main/resources/dev/wiing/gossip/client/views/login-view.fxml +++ b/Client/src/main/resources/dev/wiing/gossip/client/views/login-view.fxml @@ -12,10 +12,11 @@ - + + @@ -31,13 +32,13 @@ - + - + diff --git a/Client/src/main/resources/dev/wiing/gossip/client/views/main-chat-view.fxml b/Client/src/main/resources/dev/wiing/gossip/client/views/main-chat-view.fxml new file mode 100644 index 0000000..154e3ba --- /dev/null +++ b/Client/src/main/resources/dev/wiing/gossip/client/views/main-chat-view.fxml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +