package envoy.client.ui.controller; import java.util.logging.*; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.control.Alert.AlertType; import envoy.client.data.Context; import envoy.client.event.BackEvent; import envoy.client.helper.AlertHelper; import envoy.client.net.Client; import envoy.client.ui.control.ContactControl; import envoy.client.ui.listcell.ListCellFactory; import envoy.data.User; import envoy.event.ElementOperation; import envoy.event.contact.*; import envoy.util.EnvoyLog; import dev.kske.eventbus.*; /** * Provides a search bar in which a user name (substring) can be entered. The * users with a matching name are then displayed inside a list view. A * {@link UserSearchRequest} is sent on every keystroke. *

* The actual search algorithm is implemented on the server. *

* To create a group, a button is available that loads the * {@link GroupCreationTab}. * * @author Leon Hofmeister * @author Maximilian Käfer * @since Envoy Client v0.1-beta */ public class ContactSearchTab implements EventListener { @FXML private TextArea searchBar; @FXML private ListView userList; private User currentlySelectedUser; private final Alert alert = new Alert(AlertType.CONFIRMATION); private static final Client client = Context.getInstance().getClient(); private static final EventBus eventBus = EventBus.getInstance(); private static final Logger logger = EnvoyLog.getLogger(ChatScene.class); @FXML private void initialize() { eventBus.registerListener(this); userList.setCellFactory(new ListCellFactory<>(ContactControl::new)); alert.setTitle("Add User?"); } @Event private void onUserSearchResult(UserSearchResult result) { Platform.runLater(() -> { userList.getItems().clear(); userList.getItems().addAll(result.get()); }); } @Event private void onUserOperation(UserOperation operation) { final var contact = operation.get(); if (operation.getOperationType() == ElementOperation.ADD) Platform.runLater(() -> { userList.getItems().remove(contact); if (currentlySelectedUser != null && currentlySelectedUser.equals(contact) && alert.isShowing()) alert.close(); }); } /** * If text is present, sends a request to the server. * * @since Envoy Client v0.1-beta */ @FXML private void sendRequest() { final var text = searchBar.getText().strip(); if (!text.isBlank()) client.send(new UserSearchRequest(text)); else userList.getItems().clear(); } /** * Clears the text in the search bar and the items shown in the list. * Additionally disables both clear and search button. * * @since Envoy Client v0.1-beta */ @FXML private void clear() { searchBar.setText(null); userList.getItems().clear(); } /** * Sends an {@link UserOperation} for the selected user to the * server. * * @since Envoy Client v0.1-beta */ @FXML private void userListClicked() { final var user = userList.getSelectionModel().getSelectedItem(); if (user != null) { currentlySelectedUser = user; alert.setContentText("Add user " + currentlySelectedUser.getName() + " to your contacts?"); AlertHelper.confirmAction(alert, this::addAsContact); } } private void addAsContact() { // Sends the event to the server final var event = new UserOperation(currentlySelectedUser, ElementOperation.ADD); client.send(event); // Removes the chosen user and updates the UI userList.getItems().remove(currentlySelectedUser); eventBus.dispatch(event); logger.log(Level.INFO, "Added user " + currentlySelectedUser); } @FXML private void backButtonClicked() { searchBar.setText(""); eventBus.dispatch(new BackEvent()); } }