Small improvements to usability, auto disconnect when server closes connection

This commit is contained in:
lieght
2025-12-14 01:13:42 +01:00
parent 8cb0a86d4e
commit b94d1b6c9d
17 changed files with 87 additions and 43 deletions

View File

@@ -159,7 +159,8 @@ public final class Server {
.listen(NetworkEvents.GameMatchResponse.class, this::handleMatchResponse, false, "match-response")
.listen(NetworkEvents.GameResultResponse.class, this::handleGameResult, false, "game-result")
.listen(NetworkEvents.GameMoveResponse.class, this::handleReceivedMove, false, "game-move")
.listen(NetworkEvents.YourTurnResponse.class, this::handleYourTurn, false, "your-turn");
.listen(NetworkEvents.YourTurnResponse.class, this::handleYourTurn, false, "your-turn")
.listen(NetworkEvents.ClosedConnection.class, this::closedConnection, false, "closed-connection");
connectFlow = a;
}
@@ -233,7 +234,8 @@ public final class Server {
}
if (gameController != null){
if (gameController != null) {
primary.reEnableButton();
gameController.start();
}
}
@@ -293,6 +295,20 @@ public final class Server {
WidgetContainer.getCurrentView().transitionPrevious();
}
private void closedConnection(NetworkEvents.ClosedConnection e) {
new EventFlow().addPostEvent(new NetworkEvents.CloseClient(clientId)).postEvent();
isPolling = false;
stopScheduler();
connectFlow.unsubscribeAll();
if (nettyGatewayServer != null) {
nettyGatewayServer.stop();
}
WidgetContainer.getCurrentView().transitionPrevious();
WidgetContainer.add(Pos.CENTER, new ErrorPopup("Server closed connection."));
}
private void forfeitGame() {
new EventFlow().addPostEvent(new NetworkEvents.SendForfeit(clientId)).postEvent();
}
@@ -339,7 +355,9 @@ public final class Server {
private void gamesListFromServerHandler(NetworkEvents.GamelistResponse event) {
gameList.clear();
gameList.addAll(List.of(event.gamelist()));
var gl = List.of(event.gamelist());
gameList.addAll(gl);
primary.updateGameList(gl);
}
public void populateGameList() {

View File

@@ -64,7 +64,7 @@ public final class Primitive {
return imageView;
}
public static Button button(String key, Runnable onAction, boolean localize) {
public static Button button(String key, Runnable onAction, boolean localize, boolean disableOnClick) {
var button = new Button();
button.getStyleClass().add("button");
@@ -75,6 +75,7 @@ public final class Primitive {
if (onAction != null) {
button.setOnAction(_ -> {
if (disableOnClick) button.setDisable(true);
onAction.run();
playButtonSound();
});
@@ -83,8 +84,8 @@ public final class Primitive {
return button;
}
public static Button button(String key, Runnable onAction) {
return button(key, onAction, true);
public static Button button(String key, Runnable onAction, boolean disableOnClick) {
return button(key, onAction, true, disableOnClick);
}
public static TextField input(String promptKey, String text, Consumer<String> onValueChanged, boolean localize) {

View File

@@ -26,7 +26,7 @@ public class ConfirmWidget implements Widget {
public void addButton(String key, Runnable onClick) {
Platform.runLater(() -> {
var button = Primitive.button(key, onClick);
var button = Primitive.button(key, onClick, false);
buttonsContainer.getChildren().add(button);
});
}

View File

@@ -91,7 +91,7 @@ public class PlayerInfoWidget {
information.computerDifficulty = depth;
information.computerThinkTime = thinktime;
this.playerName.setText(getName(name));
});
}, false);
}
private String getName(String name) {

View File

@@ -32,7 +32,7 @@ public abstract class ViewWidget extends StackWidget {
var backButton = Primitive.button("back", () -> {
view.transitionPrevious();
});
}, false);
view.add(Pos.BOTTOM_LEFT, Primitive.vbox(backButton));
}
@@ -45,7 +45,7 @@ public abstract class ViewWidget extends StackWidget {
var customButton = Primitive.button(key, () -> {
runnable.run();
view.transitionPrevious();
});
}, false);
view.add(Pos.BOTTOM_LEFT, Primitive.vbox(customButton));
}
@@ -97,7 +97,7 @@ public abstract class ViewWidget extends StackWidget {
var backButton = Primitive.button("back", () -> {
view.transitionPrevious();
});
}, false);
view.add(Pos.BOTTOM_LEFT, Primitive.vbox(backButton));
}

View File

@@ -37,8 +37,8 @@ public final class ChallengePopup extends PopupWidget {
var acceptButton = Primitive.button("accept", () -> {
onAccept.accept(playerInformation);
this.hide();
});
var denyButton = Primitive.button("deny", () -> hide());
}, false);
var denyButton = Primitive.button("deny", () -> hide(), false);
var leftSection = Primitive.vbox(
challengeText,

View File

@@ -24,7 +24,7 @@ public class EscapePopup extends PopupWidget {
var opt = Primitive.button("options", () -> {
hide();
WidgetContainer.getCurrentView().transitionNext(new OptionsView());
});
}, false);
nodes.add(opt);
}
@@ -33,14 +33,14 @@ public class EscapePopup extends PopupWidget {
if (tut != null) {
nodes.add(Primitive.button("tutorialstring", () -> {
WidgetContainer.getCurrentView().add(Pos.CENTER, tut);
}));
}, false));
}
}
nodes.add(Primitive.button("quit", () -> {
hide();
WidgetContainer.add(Pos.CENTER, new QuitPopup());
}));
}, false));
add(Pos.CENTER, Primitive.vbox(nodes.toArray(new Node[0])));

View File

@@ -62,9 +62,9 @@ public final class SendChallengePopup extends PopupWidget {
var sendButton = Primitive.button(
"send",
() -> { onSend.accept(playerInformation, gameChoice.getValue()); this.hide(); }
);
, false);
var cancelButton = Primitive.button("cancel", () -> hide());
var cancelButton = Primitive.button("cancel", () -> hide(), false);
var leftSection = Primitive.vbox(
challengeText,

View File

@@ -47,8 +47,8 @@ public class BaseTutorialWidget extends PopupWidget implements Updatable {
this.pages = pages;
this.nextScreen = nextScreen;
previousButton = Primitive.button("goback", () -> { update(false); this.hide(); });
nextButton = Primitive.button(">", () -> update(true));
previousButton = Primitive.button("goback", () -> { update(false); this.hide(); }, false);
nextButton = Primitive.button(">", () -> update(true), false);
var w = Primitive.hbox(
previousButton,

View File

@@ -10,9 +10,9 @@ public class ShowEnableTutorialWidget extends PopupWidget {
public ShowEnableTutorialWidget(Runnable tutorial, Runnable nextScreen, Runnable appSettingsSetter) {
var a = Primitive.hbox(
Primitive.button("ok", () -> { appSettingsSetter.run(); tutorial.run(); this.hide(); }),
Primitive.button("no", () -> { appSettingsSetter.run(); nextScreen.run(); this.hide(); }),
Primitive.button("never", () -> { AppSettings.getSettings().setTutorialFlag(false); nextScreen.run(); this.hide(); })
Primitive.button("ok", () -> { appSettingsSetter.run(); tutorial.run(); this.hide(); }, false),
Primitive.button("no", () -> { appSettingsSetter.run(); nextScreen.run(); this.hide(); }, false),
Primitive.button("never", () -> { AppSettings.getSettings().setTutorialFlag(false); nextScreen.run(); this.hide(); }, false)
);
var txt = Primitive.text("tutorial");

View File

@@ -40,7 +40,7 @@ public final class GameView extends ViewWidget {
player2Icon = new Circle();
if (onForfeit != null) {
forfeitButton = Primitive.button("forfeit", () -> onForfeit.run());
forfeitButton = Primitive.button("forfeit", () -> onForfeit.run(), false);
} else {
forfeitButton = null;
}
@@ -48,7 +48,7 @@ public final class GameView extends ViewWidget {
exitButton = Primitive.button("exit", () -> {
onExit.run();
transitionPrevious();
});
}, false);
if (onMessage != null) {
chatInput = Primitive.input("enter-your-message", "", null);

View File

@@ -107,7 +107,7 @@ public class LocalMultiplayerView extends ViewWidget {
}
break;
}
});
}, false);
var playerSection = setupPlayerSections();

View File

@@ -10,11 +10,11 @@ public class LocalView extends ViewWidget {
public LocalView() {
var ticTacToeButton = Primitive.button("tic-tac-toe", () -> {
transitionNext(new LocalMultiplayerView(GameInformation.Type.TICTACTOE));
});
}, false);
var reversiButton = Primitive.button("reversi", () -> {
transitionNext(new LocalMultiplayerView(GameInformation.Type.REVERSI));
});
}, false);
add(Pos.CENTER, Primitive.vbox(
ticTacToeButton,

View File

@@ -9,24 +9,24 @@ public class MainView extends ViewWidget {
public MainView() {
var localButton = Primitive.button("local", () -> {
transitionNext(new LocalView());
});
}, false);
var onlineButton = Primitive.button("online", () -> {
transitionNext(new OnlineView());
});
}, false);
var creditsButton = Primitive.button("credits", () -> {
transitionNext(new CreditsView());
});
}, false);
var optionsButton = Primitive.button("options", () -> {
transitionNext(new OptionsView());
});
}, false);
var quitButton = Primitive.button("quit", () -> {
var a = new QuitPopup();
a.show(Pos.CENTER);
});
}, false);
add(Pos.CENTER, Primitive.vbox(
localButton,

View File

@@ -29,7 +29,7 @@ public class OnlineView extends ViewWidget {
serverPortInput.getValue(),
playerNameInput.getValue()
);
});
}, false);
var localHostButton = Primitive.button("host!", () -> {
@@ -53,7 +53,7 @@ public class OnlineView extends ViewWidget {
"host",
a
);
}, false);
}, false, false);
add(Pos.CENTER, Primitive.vbox(
serverInformationHeader,

View File

@@ -1,9 +1,13 @@
package org.toop.app.widget.view;
import javafx.collections.FXCollections;
import javafx.css.converter.StringConverter;
import javafx.scene.control.ComboBox;
import org.toop.app.widget.Primitive;
import org.toop.app.widget.complex.ViewWidget;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import javafx.application.Platform;
@@ -18,13 +22,16 @@ public final class ServerView extends ViewWidget {
private final Consumer<String> onPlayerClicked;
private final long clientId;
private final ComboBox<String> gameList;
private final ListView<Button> listView;
private Button subscribeButton;
public ServerView(String user, Consumer<String> onPlayerClicked, long clientId) {
this.user = user;
this.onPlayerClicked = onPlayerClicked;
this.clientId = clientId;
this.gameList = new ComboBox<>();
this.listView = new ListView<>();
setupLayout();
@@ -33,24 +40,26 @@ public final class ServerView extends ViewWidget {
private void setupLayout() {
var playerHeader = Primitive.header(user, false);
Button subscribeButton = Primitive.button(
subscribeButton = Primitive.button(
"subscribe",
() -> new EventFlow().addPostEvent(new NetworkEvents.SendSubscribe(clientId, "reversi")).postEvent(),
false
() -> new EventFlow().addPostEvent(new NetworkEvents.SendSubscribe(clientId, gameList.getValue())).postEvent(),
false,
true
); // TODO localize
var subscribe = Primitive.hbox(gameList, subscribeButton);
var playerListSection = Primitive.vbox(
playerHeader,
Primitive.separator(),
subscribeButton,
subscribe,
listView
);
add(Pos.CENTER, playerListSection);
var disconnectButton = Primitive.button("disconnect", () -> {
transitionPrevious();
});
var disconnectButton = Primitive.button(
"disconnect", () -> transitionPrevious(), false);
add(Pos.BOTTOM_LEFT, Primitive.vbox(disconnectButton));
}
@@ -60,9 +69,21 @@ public final class ServerView extends ViewWidget {
listView.getItems().clear();
for (String player : players) {
var playerButton = Primitive.button(player, () -> onPlayerClicked.accept(player), false);
var playerButton = Primitive.button(player, () -> onPlayerClicked.accept(player), false, false);
listView.getItems().add(playerButton);
}
});
}
public void updateGameList(List<String> games) {
Platform.runLater(() -> {
gameList.getItems().clear();
gameList.setItems(FXCollections.observableArrayList(games));
gameList.getSelectionModel().select(0);
});
}
public void reEnableButton() {
subscribeButton.setDisable(false);
}
}