feat: show username dialog on app init

This commit is contained in:
Arnaud Vergnet 2020-12-07 11:56:40 +01:00
parent 32dc8d719c
commit 7886d72a39
10 changed files with 175 additions and 89 deletions

View file

@ -0,0 +1,54 @@
package fr.insa.clavardator.ui;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import java.net.URL;
import java.util.ResourceBundle;
public class LoadingScreenController implements Initializable {
@FXML
public VBox indicatorOnlyContainer;
@FXML
public VBox labeledContainer;
@FXML
public Label loadingLabel;
@FXML
public StackPane container;
public void show() {
container.setVisible(true);
setLabel(null);
}
public void show(String label) {
container.setVisible(true);
setLabel(label);
}
public void hide() {
container.setVisible(false);
}
public void setLabel(String label) {
loadingLabel.setText(label);
final boolean showLabel = label != null && !label.isEmpty();
labeledContainer.setVisible(showLabel);
indicatorOnlyContainer.setVisible(!showLabel);
}
public ObservableList<String> getRootStyle() {
return container.getStyleClass();
}
@Override
public void initialize(URL location, ResourceBundle resources) {
show();
}
}

View file

@ -25,9 +25,7 @@ public class MainController implements Initializable {
@FXML @FXML
private StackPane root; private StackPane root;
@FXML @FXML
private VBox loadingContainer; private StackPane mainContainer;
@FXML
private VBox loginContainer;
@FXML @FXML
private ToolbarController toolbarController; private ToolbarController toolbarController;
@ -39,12 +37,20 @@ public class MainController implements Initializable {
private UserListController userListController; private UserListController userListController;
@FXML @FXML
private ChatController chatController; private ChatController chatController;
@FXML
private LoadingScreenController loadingController;
private JFXSnackbar snackbar; private JFXSnackbar snackbar;
private void openEditUsernameDialog() throws IOException { private void openEditUsernameDialog(EditUsernameDialogController.Mode mode) {
editUserDialogController.setOnDismissListener(() -> {
if (mode == EditUsernameDialogController.Mode.INITIAL) {
System.exit(0);
} else {
showChat();
}
});
editUserDialogController.setOnSuccessListener(() -> { editUserDialogController.setOnSuccessListener(() -> {
System.out.println("success");
try { try {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("dialogs/snackbar.fxml")); final FXMLLoader loader = new FXMLLoader(getClass().getResource("dialogs/snackbar.fxml"));
snackbar.enqueue(new JFXSnackbar.SnackbarEvent( snackbar.enqueue(new JFXSnackbar.SnackbarEvent(
@ -57,21 +63,23 @@ public class MainController implements Initializable {
e.printStackTrace(); e.printStackTrace();
} }
}); });
editUserDialogController.show(root, EditUsernameDialogController.Mode.EDIT); editUserDialogController.show(root, mode);
} }
private void showChat() { private void showChat() {
loadingContainer.setVisible(false); loadingController.hide();
loginContainer.setVisible(false); mainContainer.setVisible(true);
} }
private void showLogin() { private void showLogin(boolean isError) {
loadingContainer.setVisible(false); mainContainer.setVisible(false);
loginContainer.setVisible(true); loadingController.hide();
openEditUsernameDialog(isError ? EditUsernameDialogController.Mode.ERROR : EditUsernameDialogController.Mode.INITIAL);
} }
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
loadingController.show("Initialisation de Clavardator...");
snackbar = new JFXSnackbar(root); snackbar = new JFXSnackbar(root);
Timer t = new Timer(); Timer t = new Timer();
@ -80,14 +88,15 @@ public class MainController implements Initializable {
public void run() { public void run() {
Platform.runLater(() -> CurrentUser.getInstance().setState(CurrentUser.State.VALID)); Platform.runLater(() -> CurrentUser.getInstance().setState(CurrentUser.State.VALID));
} }
}, 2000); }, 3000);
CurrentUser.getInstance().addObserver(propertyChangeEvent -> { CurrentUser.getInstance().addObserver(propertyChangeEvent -> {
if (propertyChangeEvent.getPropertyName().equals("state")) { if (propertyChangeEvent.getPropertyName().equals("state")) {
if (propertyChangeEvent.getNewValue().equals(CurrentUser.State.VALID)) final CurrentUser.State state = (CurrentUser.State) propertyChangeEvent.getNewValue();
if (state == CurrentUser.State.VALID)
showChat(); showChat();
else else
showLogin(); showLogin(state == CurrentUser.State.INVALID);
} }
}); });
@ -95,13 +104,7 @@ public class MainController implements Initializable {
userListController.addUserSelectedListener((user) -> chatController.setRemoteUser(user)); userListController.addUserSelectedListener((user) -> chatController.setRemoteUser(user));
chatController.addAttachmentListener(() -> System.out.println("attach event")); chatController.addAttachmentListener(() -> System.out.println("attach event"));
chatController.addSendListener((text) -> System.out.println("sent : " + text)); chatController.addSendListener((text) -> System.out.println("sent : " + text));
toolbarController.addEditListener(() -> { toolbarController.addEditListener(() -> openEditUsernameDialog(EditUsernameDialogController.Mode.EDIT));
try {
openEditUsernameDialog();
} catch (IOException e) {
e.printStackTrace();
}
});
toolbarController.addAboutListener(() -> aboutDialogController.show(root)); toolbarController.addAboutListener(() -> aboutDialogController.show(root));
} }
} }

View file

@ -3,6 +3,7 @@ package fr.insa.clavardator.ui.chat;
import fr.insa.clavardator.chat.ChatHistory; import fr.insa.clavardator.chat.ChatHistory;
import fr.insa.clavardator.chat.Message; import fr.insa.clavardator.chat.Message;
import fr.insa.clavardator.ui.ButtonPressEvent; import fr.insa.clavardator.ui.ButtonPressEvent;
import fr.insa.clavardator.ui.LoadingScreenController;
import fr.insa.clavardator.ui.NoSelectionModel; import fr.insa.clavardator.ui.NoSelectionModel;
import fr.insa.clavardator.users.ActiveUser; import fr.insa.clavardator.users.ActiveUser;
import fr.insa.clavardator.users.PeerUser; import fr.insa.clavardator.users.PeerUser;
@ -25,13 +26,13 @@ public class ChatController implements Initializable {
private ChatFooterController chatFooterController; private ChatFooterController chatFooterController;
@FXML @FXML
private ChatHeaderController chatHeaderController; private ChatHeaderController chatHeaderController;
@FXML
private LoadingScreenController loadingController;
@FXML @FXML
private VBox chatContainer; private VBox chatContainer;
@FXML @FXML
private VBox emptyContainer; private VBox emptyContainer;
@FXML
private VBox loadingContainer;
private PeerUser remoteUser; private PeerUser remoteUser;
@ -74,12 +75,12 @@ public class ChatController implements Initializable {
emptyContainer.setVisible(true); emptyContainer.setVisible(true);
chatFooterController.setEnabled(false); chatFooterController.setEnabled(false);
chatContainer.setVisible(false); chatContainer.setVisible(false);
loadingContainer.setVisible(false); loadingController.hide();
messageList.setItems(null); messageList.setItems(null);
break; break;
case LOADING: case LOADING:
chatContainer.setVisible(true); chatContainer.setVisible(true);
loadingContainer.setVisible(true); loadingController.show();
chatFooterController.setEnabled(false); chatFooterController.setEnabled(false);
emptyContainer.setVisible(false); emptyContainer.setVisible(false);
break; break;
@ -87,13 +88,15 @@ public class ChatController implements Initializable {
chatFooterController.setEnabled(true); chatFooterController.setEnabled(true);
chatContainer.setVisible(true); chatContainer.setVisible(true);
emptyContainer.setVisible(false); emptyContainer.setVisible(false);
loadingContainer.setVisible(false); loadingController.hide();
break; break;
} }
} }
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
loadingController.getRootStyle().clear();
loadingController.getRootStyle().add("inner");
messageList.setSelectionModel(new NoSelectionModel<Message>()); messageList.setSelectionModel(new NoSelectionModel<Message>());
messageList.setCellFactory(listView -> new MessageListItemCell()); messageList.setCellFactory(listView -> new MessageListItemCell());
setState(State.INITIAL); setState(State.INITIAL);

View file

@ -3,7 +3,6 @@ package fr.insa.clavardator.ui.dialogs;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialog; import com.jfoenix.controls.JFXDialog;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.RequiredFieldValidator;
import com.jfoenix.validation.base.ValidatorBase; import com.jfoenix.validation.base.ValidatorBase;
import fr.insa.clavardator.ui.ButtonPressEvent; import fr.insa.clavardator.ui.ButtonPressEvent;
import javafx.beans.property.ReadOnlyBooleanWrapper; import javafx.beans.property.ReadOnlyBooleanWrapper;
@ -42,53 +41,10 @@ public class EditUsernameDialogController implements Initializable {
private State currentState; private State currentState;
private Validator validator; private Validator validator;
private ButtonPressEvent successListener; private ButtonPressEvent successListener;
private ButtonPressEvent dismissListener;
public void setOnSuccessListener(ButtonPressEvent listener) { @FXML
this.successListener = listener; private void onConfirm() {
}
public void show(StackPane root, Mode mode) {
setLocked(false);
setFieldError(State.VALID);
setMode(mode);
dialog.show(root);
}
public void hide() {
dialog.close();
}
public void onCancel() {
hide();
}
private void setLocked(boolean state) {
confirmButton.setDisable(state);
cancelButton.setDisable(state);
dialog.setOverlayClose(!state);
textField.setDisable(state);
}
private void onSuccess() {
setFieldError(State.VALID);
setLocked(false);
hide();
successListener.onPress();
}
private void onError() {
validator.setMessage("Nom d'utilisateur invalide");
setFieldError(State.INVALID);
setLocked(false);
}
private void setFieldError(State state) {
currentState = state;
textField.validate();
}
public void onConfirm() {
setLocked(true); setLocked(true);
// TODO replace by network call // TODO replace by network call
Timer t = new Timer(); Timer t = new Timer();
@ -101,6 +57,45 @@ public class EditUsernameDialogController implements Initializable {
}, 1000); }, 1000);
} }
@FXML
private void onCancel() {
hide();
}
public void setOnSuccessListener(ButtonPressEvent listener) {
this.successListener = listener;
}
public void setOnDismissListener(ButtonPressEvent listener) {
this.dismissListener = listener;
}
public void show(StackPane root, Mode mode) {
setLocked(false);
setFieldError(State.VALID);
setMode(mode);
dialog.show(root);
}
public void hide() {
dialog.close();
if (dismissListener != null) {
dismissListener.onPress();
}
}
private void setLocked(boolean state) {
confirmButton.setDisable(state);
cancelButton.setDisable(state);
dialog.setOverlayClose(!state);
textField.setDisable(state);
}
private void setFieldError(State state) {
currentState = state;
textField.validate();
}
public void onUsernameChange(ObservableValue<? extends String> observable, String oldText, String newText) { public void onUsernameChange(ObservableValue<? extends String> observable, String oldText, String newText) {
setFieldError(State.VALID); setFieldError(State.VALID);
confirmButton.setDisable(newText.isEmpty()); confirmButton.setDisable(newText.isEmpty());
@ -109,14 +104,20 @@ public class EditUsernameDialogController implements Initializable {
public void setMode(Mode mode) { public void setMode(Mode mode) {
switch (mode) { switch (mode) {
case INITIAL: case INITIAL:
dialog.setOverlayClose(false);
cancelButton.setText("Quitter");
titleLabel.setText("Nom d'utilisateur"); titleLabel.setText("Nom d'utilisateur");
descriptionLabel.setText("Choisissez votre nom d'utilisateur. Vous pourrez le changer plus tard"); descriptionLabel.setText("Choisissez votre nom d'utilisateur.\nVous pourrez le changer plus tard");
break; break;
case ERROR: case ERROR:
dialog.setOverlayClose(false);
cancelButton.setText("Hors ligne");
titleLabel.setText("Nom d'utilisateur expiré"); titleLabel.setText("Nom d'utilisateur expiré");
descriptionLabel.setText("Votre nom d'utilisateur n'est plus valide, merci d'en choisir un autre."); descriptionLabel.setText("Votre nom d'utilisateur n'est plus valide.\nMerci d'en choisir un autre.");
break; break;
case EDIT: case EDIT:
dialog.setOverlayClose(true);
cancelButton.setText("Annuler");
titleLabel.setText("Changer le nom d'utilisateur"); titleLabel.setText("Changer le nom d'utilisateur");
descriptionLabel.setText("Entrez votre nouveau nom d'utilisateur"); descriptionLabel.setText("Entrez votre nouveau nom d'utilisateur");
break; break;
@ -133,6 +134,19 @@ public class EditUsernameDialogController implements Initializable {
textField.getValidators().add(validator); textField.getValidators().add(validator);
} }
private void onSuccess() {
setFieldError(State.VALID);
setLocked(false);
hide();
successListener.onPress();
}
private void onError() {
validator.setMessage("Nom d'utilisateur invalide");
setFieldError(State.INVALID);
setLocked(false);
}
public enum Mode { public enum Mode {
INITIAL, INITIAL,

View file

@ -46,6 +46,7 @@ public class CurrentUser extends User {
public enum State { public enum State {
UNINITIALIZED, UNINITIALIZED,
VALID, VALID,
INVALID INVALID,
NONE
} }
} }

View file

@ -14,9 +14,7 @@
<fx:include source="chatHeader.fxml" fx:id="chatHeader"/> <fx:include source="chatHeader.fxml" fx:id="chatHeader"/>
<StackPane VBox.vgrow="ALWAYS"> <StackPane VBox.vgrow="ALWAYS">
<ListView fx:id="messageList"/> <ListView fx:id="messageList"/>
<VBox alignment="CENTER" fx:id="loadingContainer" styleClass="inner"> <fx:include source="../loadingScreen.fxml" fx:id="loading"/>
<JFXSpinner />
</VBox>
</StackPane> </StackPane>
<fx:include source="chatFooter.fxml" fx:id="chatFooter"/> <fx:include source="chatFooter.fxml" fx:id="chatFooter"/>
</VBox> </VBox>

View file

@ -16,7 +16,7 @@
prefHeight="400" styleClass="container"> prefHeight="400" styleClass="container">
<VBox AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0"> <VBox AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0">
<padding> <padding>
<Insets left="10" right="10" bottom="10" top="10"/> <Insets left="20" right="20" bottom="20" top="20"/>
</padding> </padding>
<VBox VBox.vgrow="ALWAYS" spacing="10"> <VBox VBox.vgrow="ALWAYS" spacing="10">
<padding> <padding>

View file

@ -16,7 +16,7 @@
prefHeight="400" styleClass="container"> prefHeight="400" styleClass="container">
<VBox AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0"> <VBox AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.bottomAnchor="0">
<padding> <padding>
<Insets left="10" right="10" bottom="10" top="10"/> <Insets left="20" right="20" bottom="20" top="20"/>
</padding> </padding>
<VBox VBox.vgrow="ALWAYS" spacing="10"> <VBox VBox.vgrow="ALWAYS" spacing="10">
<padding> <padding>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXSpinner?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<StackPane xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="fr.insa.clavardator.ui.LoadingScreenController"
stylesheets="@styles.css"
styleClass="container"
fx:id="container">
<VBox alignment="CENTER" fx:id="indicatorOnlyContainer">
<JFXSpinner/>
</VBox>
<VBox alignment="CENTER" fx:id="labeledContainer" spacing="30">
<Label fx:id="loadingLabel">TEXT</Label>
<JFXSpinner/>
</VBox>
</StackPane>

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!--suppress JavaFxUnresolvedFxIdReference --> <!--suppress JavaFxUnresolvedFxIdReference -->
<?import com.jfoenix.controls.JFXSpinner?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<StackPane xmlns:fx="http://javafx.com/fxml/1" <StackPane xmlns:fx="http://javafx.com/fxml/1"
@ -21,11 +20,5 @@
</HBox> </HBox>
</VBox> </VBox>
</StackPane> </StackPane>
<VBox alignment="CENTER" fx:id="loginContainer" styleClass="container" spacing="30"> <fx:include source="loadingScreen.fxml" fx:id="loading"/>
<Label>ERROR</Label>
</VBox>
<VBox alignment="CENTER" fx:id="loadingContainer" styleClass="container" spacing="30">
<Label>Initialisation de Clavardator...</Label>
<JFXSpinner/>
</VBox>
</StackPane> </StackPane>