This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/src/main/java/envoy/client/ui/ChatSceneController.java

176 lines
5.1 KiB
Java
Raw Normal View History

package envoy.client.ui;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import envoy.client.data.Chat;
import envoy.client.data.LocalDB;
import envoy.client.event.MessageCreationEvent;
import envoy.client.net.Client;
import envoy.client.net.WriteProxy;
import envoy.data.Contact;
import envoy.data.Message;
import envoy.data.MessageBuilder;
import envoy.event.EventBus;
import envoy.event.MessageStatusChangeEvent;
import envoy.event.UserStatusChangeEvent;
import envoy.util.EnvoyLog;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>ChatSceneController.java</strong><br>
* Created: <strong>26.03.2020</strong><br>
*
* @author Kai S. K. Engelbart
* @since Envoy Client v0.1-beta
*/
public final class ChatSceneController {
@FXML
private Label contactLabel;
@FXML
private ListView<Message> messageList;
@FXML
private ListView<Contact> userList;
@FXML
private Button postButton;
@FXML
private Button settingsButton;
@FXML
private TextArea messageTextArea;
private LocalDB localDB;
private Client client;
private WriteProxy writeProxy;
private Chat currentChat;
private static final EventBus eventBus = EventBus.getInstance();
private static final Logger logger = EnvoyLog.getLogger(ChatSceneController.class);
@FXML
private void initialize() {
// Initialize message and user rendering
messageList.setCellFactory(listView -> new MessageListCell());
userList.setCellFactory(listView -> new UserListCell());
// Listen to received messages
eventBus.register(MessageCreationEvent.class, e -> {
final var message = e.get();
final var chat = localDB.getChats().stream().filter(c -> c.getRecipient().getID() == message.getSenderID()).findAny().get();
chat.getMessages().add(message);
// Update UI if in current chat
if (chat == currentChat) Platform.runLater(() -> messageList.getItems().add(message));
});
// Listen to message status changes
eventBus.register(MessageStatusChangeEvent.class, e -> {
final var message = localDB.getMessage(e.getID());
message.setStatus(e.get());
// Update UI if in current chat
if (currentChat != null && message.getSenderID() == currentChat.getRecipient().getID()) Platform.runLater(() -> messageList.refresh());
});
// Listen to user status changes
eventBus.register(UserStatusChangeEvent.class, e -> Platform.runLater(() -> userList.refresh()));
}
void initializeData(LocalDB localDB, Client client, WriteProxy writeProxy) {
this.localDB = localDB;
this.client = client;
this.writeProxy = writeProxy;
// TODO: handle offline mode
userList.setItems(FXCollections.observableList(localDB.getUser().getContacts().stream().collect(Collectors.toList())));
}
@FXML
private void userListClicked() {
final Contact user = userList.getSelectionModel().getSelectedItem();
if (user != null && (currentChat == null || user.getID() != currentChat.getRecipient().getID())) {
contactLabel.setText(user.getName());
// LEON: JFC <===> JAVA FRIED CHICKEN <=/=> Java Foundation Classes
// Load the chat or create a new one and add it to the LocalDB
currentChat = localDB.getChats()
.stream()
.filter(c -> c.getRecipient().getID() == user.getID())
.findAny()
.orElseGet(() -> { var chat = new Chat(user); localDB.getChats().add(chat); return chat; });
messageList.setItems(FXCollections.observableList(currentChat.getMessages()));
}
}
@FXML
private void postButtonClicked() { postMessage(); }
@FXML
private void settingsButtonClicked() { logger.info("Settings Button clicked."); }
@FXML
private void messageTextUpdated(KeyEvent e) {
if (e.getCode() == KeyCode.ENTER) postMessage();
else postButton.setDisable(messageTextArea.getText().isBlank());
}
/**
* Sends a new message to the server based on the text entered in the
* messageTextArea.
*
* @since Envoy Client v0.1-beta
*/
private void postMessage() {
// Create and send message
sendMessage(new MessageBuilder(localDB.getUser().getID(), currentChat.getRecipient().getID(), localDB.getIDGenerator())
.setText(messageTextArea.getText().strip())
.build());
// Clear text field and disable post button
messageTextArea.setText("");
postButton.setDisable(true);
}
/**
* Sends a message to the server and appends it to the current chat. If all
* message IDs have been used, a new ID generator is requested.
*
* @param message the message to send
* @since Envoy Client v0.1-beta
*/
private void sendMessage(Message message) {
try {
// Send message
writeProxy.writeMessage(message);
// Add message to LocalDB and update UI
messageList.getItems().add(message);
// Request a new ID generator if all IDs were used
if (!localDB.getIDGenerator().hasNext() && client.isOnline()) client.requestIdGenerator();
} catch (IOException e) {
logger.log(Level.SEVERE, "Error sending message", e);
}
}
}