feat: implement mobile terminal UX

- Add mobile viewport detection hook
- Add virtual keyboard detection with fallback
- Add auto-hide hook for header/keys strip
- Add special keys mapping hook
- Create MobileTerminalHeader, SpecialKeysStrip, SpecialKeysPanel components
- Create MobileTerminalWrapper component
- Update TerminalComponent with mobile support, font scaling, copy/paste, reconnection
- Update AppShell to hide chrome on mobile terminal pages
- Update TerminalPage to use MobileTerminalWrapper
- Add comprehensive mobile terminal styles
- TypeScript check passes
- Build succeeds
This commit is contained in:
Fusion
2026-05-24 11:30:04 +02:00
parent 312a646b89
commit b6bda3d692
19 changed files with 1721 additions and 81 deletions
@@ -0,0 +1,23 @@
## MODIFIED Requirements
### Requirement: Layout Component
The system SHALL provide a consistent application layout for authenticated screens across desktop and mobile sizes.
#### Scenario: Application shell
- **GIVEN** the frontend application
- **THEN** a Layout component SHALL:
- Display a header with user info and logout
- Display sidebar navigation on desktop
- Show main content area
- Collapse sidebar into a mobile menu toggle on small viewports
- **AND** on mobile terminal pages, provide a minimal collapsible header instead of the full AppShell
#### Scenario: Terminal page mobile layout
- **GIVEN** a user on a terminal page on a mobile device
- **WHEN** the page loads
- **THEN** the full AppShell is replaced with a minimal header
- **AND** the header contains: back button, menu toggle, instance name, close button
- **AND** the header auto-hides after 3 seconds of inactivity
- **AND** tapping the terminal area toggles header visibility
- **AND** the sidebar navigation is accessible via the menu toggle
@@ -0,0 +1,121 @@
## ADDED Requirements
### Requirement: Mobile Terminal Layout
The system SHALL provide a fullscreen terminal experience on mobile devices.
#### Scenario: Mobile terminal page
- **WHEN** a user navigates to an instance terminal page on a mobile device (viewport width < 768px)
- **THEN** the AppShell chrome is collapsed to a minimal header
- **AND** the terminal occupies the full viewport below the header
- **AND** the header auto-hides after 3 seconds of inactivity
- **AND** tapping the terminal area toggles header visibility
#### Scenario: Collapsed AppShell header
- **WHEN** the terminal is in mobile mode
- **THEN** the header displays:
- A back button
- A hamburger menu toggle (reveals navigation)
- The instance name
- A close button
- **AND** the sidebar navigation is hidden by default
### Requirement: Special Keys Toolbar
The system SHALL provide access to special terminal keys on mobile devices.
#### Scenario: Special keys strip
- **WHEN** a user is on a mobile terminal
- **THEN** a strip of special keys is available at the bottom of the screen
- **AND** the strip contains: Esc, Tab, Ctrl, Alt, Up, Down, Left, Right
- **AND** the strip auto-hides after 3 seconds of inactivity
- **AND** swiping up from the bottom reveals the strip
- **AND** tapping the terminal area hides the strip
#### Scenario: Expanded special keys panel
- **WHEN** a user taps the "More" button on the special keys strip
- **THEN** an expanded panel appears with additional keys:
- Home, End, Page Up, Page Down
- Ctrl+C, Ctrl+D, Ctrl+Z
- F1 through F12
- **AND** tapping outside the panel closes it
#### Scenario: Sending special keys
- **WHEN** a user taps a special key
- **THEN** the corresponding escape sequence is sent via WebSocket
- **AND** the key press is visually acknowledged (brief highlight)
### Requirement: Virtual Keyboard Handling
The system SHALL handle virtual keyboard appearance on mobile devices.
#### Scenario: Keyboard-aware resizing
- **WHEN** the virtual keyboard appears on a mobile device
- **THEN** the terminal container resizes to fit the remaining viewport
- **AND** the special keys strip remains visible above the virtual keyboard
#### Scenario: Visual viewport detection
- **WHEN** the browser supports the Visual Viewport API
- **THEN** the system uses `visualViewport` events to detect keyboard height
- **AND** falls back to `window.innerHeight` comparison if API is unavailable
#### Scenario: Focus management
- **WHEN** a user taps on the terminal area
- **THEN** focus is maintained on a hidden input element to keep the virtual keyboard open
- **AND** terminal input continues to work normally
### Requirement: Touch Gestures
The system SHALL support touch interactions in the terminal.
#### Scenario: Disable browser zoom
- **WHEN** a user is on a mobile terminal page
- **THEN** browser zoom is disabled via `meta viewport` tag with `user-scalable=no`
- **AND** pinch gestures do not zoom the page
#### Scenario: Terminal scroll
- **WHEN** a user performs a two-finger swipe in the terminal
- **THEN** the terminal scrollback buffer scrolls
- **AND** the browser page does not scroll
#### Scenario: Text selection
- **WHEN** a user long-presses in the terminal
- **THEN** xterm.js native selection behavior is used
- **AND** browser native text selection UI is suppressed
### Requirement: Screen Orientation
The system SHALL handle device orientation changes gracefully.
#### Scenario: Orientation change
- **WHEN** a user rotates their device
- **THEN** the terminal recalculates dimensions after a 250ms debounce
- **AND** the new dimensions are sent to the backend via WebSocket resize message
### Requirement: Copy and Paste
The system SHALL provide copy and paste functionality on mobile devices.
#### Scenario: Copy button
- **WHEN** a user selects text in the terminal
- **THEN** a "Copy" button appears in the header
- **AND** tapping it copies the selection to clipboard
#### Scenario: Paste button
- **WHEN** a user taps a "Paste" button in the header or special keys panel
- **THEN** the system attempts to read from the clipboard
- **AND** pastes the content into the terminal
### Requirement: Font Scaling
The system SHALL provide readable font sizes on mobile devices.
#### Scenario: Mobile font size
- **WHEN** the terminal is displayed on a mobile device
- **THEN** the font size is at least 16px
- **AND** the font size scales proportionally with viewport width (min 16px, max 24px)
#### Scenario: Font size preference
- **WHEN** a user changes the font size
- **THEN** the preference is persisted in localStorage
- **AND** applied on subsequent terminal sessions
@@ -0,0 +1,123 @@
## MODIFIED Requirements
### Requirement: Terminal Resize
The system SHALL support terminal resize events.
#### Scenario: Resize terminal
- **GIVEN** an active terminal session
- **WHEN** the browser window is resized
- **THEN** the terminal dimensions (COLS, ROWS) are updated
- **AND** the shell receives the new size
- **AND** on mobile devices, the resize is debounced by 250ms
#### Scenario: Mobile keyboard resize
- **GIVEN** an active terminal session on a mobile device
- **WHEN** the virtual keyboard appears or disappears
- **THEN** the terminal container height adjusts to fit the visible viewport
- **AND** the terminal is refitted with new dimensions
### Requirement: WebSocket Terminal
The system SHALL provide terminal sessions via WebSocket.
#### Scenario: Mobile reconnection
- **GIVEN** a terminal session on a mobile device
- **WHEN** the WebSocket disconnects due to network change or backgrounding
- **THEN** the terminal shows a "Reconnecting..." status
- **AND** attempts to reconnect automatically
- **AND** if reconnection fails after 3 attempts, shows an error with a manual reconnect option
## ADDED Requirements
### Requirement: Mobile Terminal Layout
The system SHALL provide a fullscreen terminal experience on mobile devices.
#### Scenario: Mobile terminal page
- **WHEN** a user navigates to an instance terminal page on a mobile device (viewport width < 768px)
- **THEN** the AppShell chrome is collapsed to a minimal header
- **AND** the terminal occupies the full viewport below the header
- **AND** the header auto-hides after 3 seconds of inactivity
- **AND** tapping the terminal area toggles header visibility
#### Scenario: Collapsed AppShell header
- **WHEN** the terminal is in mobile mode
- **THEN** the header displays:
- A back button
- A hamburger menu toggle (reveals navigation)
- The instance name
- A close button
- **AND** the sidebar navigation is hidden by default
### Requirement: Special Keys Toolbar
The system SHALL provide access to special terminal keys on mobile devices.
#### Scenario: Special keys strip
- **WHEN** a user is on a mobile terminal
- **THEN** a strip of special keys is available at the bottom of the screen
- **AND** the strip contains: Esc, Tab, Ctrl, Alt, Up, Down, Left, Right
- **AND** the strip auto-hides after 3 seconds of inactivity
- **AND** swiping up from the bottom reveals the strip
- **AND** tapping the terminal area hides the strip
#### Scenario: Expanded special keys panel
- **WHEN** a user taps the "More" button on the special keys strip
- **THEN** an expanded panel appears with additional keys:
- Home, End, Page Up, Page Down
- Ctrl+C, Ctrl+D, Ctrl+Z
- F1 through F12
- **AND** tapping outside the panel closes it
#### Scenario: Sending special keys
- **WHEN** a user taps a special key
- **THEN** the corresponding escape sequence is sent via WebSocket
- **AND** the key press is visually acknowledged (brief highlight)
### Requirement: Touch Gestures
The system SHALL support touch interactions in the terminal.
#### Scenario: Disable browser zoom
- **WHEN** a user is on a mobile terminal page
- **THEN** browser zoom is disabled via `meta viewport` tag with `user-scalable=no`
- **AND** pinch gestures do not zoom the page
#### Scenario: Terminal scroll
- **WHEN** a user performs a two-finger swipe in the terminal
- **THEN** the terminal scrollback buffer scrolls
- **AND** the browser page does not scroll
#### Scenario: Text selection
- **WHEN** a user long-presses in the terminal
- **THEN** xterm.js native selection behavior is used
- **AND** browser native text selection UI is suppressed
### Requirement: Copy and Paste
The system SHALL provide copy and paste functionality on mobile devices.
#### Scenario: Copy button
- **WHEN** a user selects text in the terminal
- **THEN** a "Copy" button appears in the header
- **AND** tapping it copies the selection to clipboard
#### Scenario: Paste button
- **WHEN** a user taps a "Paste" button in the header or special keys panel
- **THEN** the system attempts to read from the clipboard
- **AND** pastes the content into the terminal
### Requirement: Font Scaling
The system SHALL provide readable font sizes on mobile devices.
#### Scenario: Mobile font size
- **WHEN** the terminal is displayed on a mobile device
- **THEN** the font size is at least 16px
- **AND** the font size scales proportionally with viewport width (min 16px, max 24px)
#### Scenario: Font size preference
- **WHEN** a user changes the font size
- **THEN** the preference is persisted in localStorage
- **AND** applied on subsequent terminal sessions