From 2f46ac3177b4ca33689398500024486157d1f083 Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Thu, 18 Sep 2025 18:02:06 +0200 Subject: [PATCH] Erweiterungen --- .../emulatorstation/Application.java | 1 + .../base/ui/view/LoginView.java | 6 ++ .../base/ui/view/MainView.java | 86 ++++++++++++------- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/src/main/java/de/assecutor/emulatorstation/Application.java b/src/main/java/de/assecutor/emulatorstation/Application.java index 3ad6318..aa62069 100644 --- a/src/main/java/de/assecutor/emulatorstation/Application.java +++ b/src/main/java/de/assecutor/emulatorstation/Application.java @@ -37,6 +37,7 @@ public class Application implements AppShellConfigurator { ); public static final Map activeNiederlassungen = new ConcurrentHashMap<>(); + public static final Map activeUsers = new ConcurrentHashMap<>(); public static void main(String[] args) { SpringApplication.run(Application.class, args); diff --git a/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java b/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java index f39c48f..e4c6e52 100644 --- a/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java +++ b/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java @@ -50,12 +50,18 @@ public class LoginView extends VerticalLayout { return; } + if (Application.activeUsers.containsKey(username)) { + Notification.show("Benutzer ist bereits angemeldet", 3000, Notification.Position.MIDDLE); + return; + } + if (Application.activeNiederlassungen.containsKey(niederlassung)) { Notification.show("Niederlassung ist bereits von einem anderen Benutzer belegt", 3000, Notification.Position.MIDDLE); return; } Application.activeNiederlassungen.put(niederlassung, username); + Application.activeUsers.put(username, niederlassung); // Spring Security Authentifizierung setzen var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER")); diff --git a/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java b/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java index 4c9ead1..c150e67 100644 --- a/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java +++ b/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java @@ -46,6 +46,7 @@ public final class MainView extends Main implements BeforeEnterObserver private final IFrame webView = new IFrame(); private final Div emulatorContainer = new Div(); private final Div welcomeMessage = new Div(); + private Button startBtn; private final ExecutorService executor = Executors.newSingleThreadExecutor(); @@ -113,7 +114,8 @@ public final class MainView extends Main implements BeforeEnterObserver .set("background-color", "#f8f9fa") .set("border", "2px dashed #dee2e6") .set("border-radius", "8px") - .set("color", "#6c757d"); + .set("color", "#6c757d") + .set("margin-bottom", "16px"); Icon icon = new Icon(VaadinIcon.DESKTOP); icon.setSize("48px"); @@ -135,9 +137,10 @@ public final class MainView extends Main implements BeforeEnterObserver buttonLayout.getStyle() .set("margin", "0") .set("padding", "8px 0") - .set("flex-shrink", "0"); + .set("flex-shrink", "0") + .set("order", "999"); - Button startBtn = new Button("Emulator starten", new Icon(VaadinIcon.PLAY), event -> startup()); + startBtn = new Button("Emulator starten", new Icon(VaadinIcon.PLAY), event -> startup()); startBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY); Button logoutBtn = new Button("Abmelden", new Icon(VaadinIcon.SIGN_OUT), event -> logout()); @@ -155,10 +158,25 @@ public final class MainView extends Main implements BeforeEnterObserver .set("box-shadow", "0 2px 4px rgba(0,0,0,0.1)") .set("overflow", "hidden") .set("display", "none") - .set("flex-grow", "1"); + .set("flex-grow", "1") + .set("margin-bottom", "16px"); webView.setSizeFull(); webView.getElement().setAttribute("frameborder", "0"); + webView.getElement().setAttribute("scrolling", "no"); + webView.getElement().getStyle() + .set("overflow", "hidden") + .set("-webkit-overflow-scrolling", "touch") + .set("-ms-overflow-style", "none") + .set("scrollbar-width", "none"); + + // CSS für Webkit-Browser (Chrome, Safari) + webView.getElement().executeJs( + "this.style.setProperty('overflow', 'hidden', 'important');" + + "var style = document.createElement('style');" + + "style.textContent = 'iframe::-webkit-scrollbar { display: none !important; }';" + + "document.head.appendChild(style);" + ); emulatorContainer.add(webView); container.add(emulatorContainer); @@ -198,6 +216,10 @@ public final class MainView extends Main implements BeforeEnterObserver private void startup() { UI ui = UI.getCurrent(); + // Button sofort sperren + startBtn.setEnabled(false); + startBtn.setText("Emulator starten"); + var dialog = showWaitDialog("Der Emulator wird gestartet, bitte warten..."); executor.submit(() -> { @@ -225,6 +247,9 @@ public final class MainView extends Main implements BeforeEnterObserver welcomeMessage.getStyle().set("display", "none"); emulatorContainer.getStyle().set("display", "block"); + // Button bleibt dauerhaft deaktiviert + startBtn.setText("Emulator gestartet"); + refreshWebView(); }); } @@ -536,33 +561,34 @@ public final class MainView extends Main implements BeforeEnterObserver @ClientCallable public void logout() { - UI ui = UI.getCurrent(); - var vaadinSession = VaadinService.getCurrentRequest().getWrappedSession(); + try { + // Cleanup in separatem Thread ohne UI-Navigation + executor.submit(() -> { + try { + shutdown(); + } catch (Exception ex) { + logger.error("Fehler beim Shutdown während Logout", ex); + } + }); - var dialog = showWaitDialog("Sie werden abgemeldet. Bitte warten..."); - dialog.open(); - - executor.submit(() -> { - try { - shutdown(); - } catch (Exception ex) { - // Logging, Fehlerbehandlung … - } finally { - // 4) UI-update sicher aus Nicht-UI-Thread heraus - ui.access(() -> { - dialog.close(); - - // Session cleanup vor Navigation - if (niederlassung != null) { - Application.activeNiederlassungen.remove(niederlassung); - } - - vaadinSession.invalidate(); - - // Navigiere direkt zur Login-Seite - ui.navigate("login"); - }); + // Session cleanup sofort + if (niederlassung != null) { + Application.activeNiederlassungen.remove(niederlassung); } - }); + if (username != null) { + Application.activeUsers.remove(username); + } + + // Session invalidieren + UI.getCurrent().getSession().getSession().invalidate(); + + // Direkte Browser-Weiterleitung ohne Vaadin Navigation + UI.getCurrent().getPage().setLocation("login"); + + } catch (Exception ex) { + logger.error("Fehler beim Logout", ex); + // Fallback: Browser reload + UI.getCurrent().getPage().reload(); + } } }