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 dev.kske.eventbus.core.*; import envoy.data.User; import envoy.event.ElementOperation; import envoy.event.contact.*; import envoy.util.EnvoyLog; 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; /** * 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 { @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()); } }