Move toju-app into own its folder
This commit is contained in:
137
toju-app/src/app/domains/screen-share/README.md
Normal file
137
toju-app/src/app/domains/screen-share/README.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Screen Share Domain
|
||||
|
||||
Manages screen sharing sessions, source selection (Electron), quality presets, and the viewer/workspace UI. Like `voice-connection`, the actual WebRTC track distribution lives in `infrastructure/realtime`; this domain provides the application-facing API and UI components.
|
||||
|
||||
## Module map
|
||||
|
||||
```
|
||||
screen-share/
|
||||
├── application/
|
||||
│ ├── screen-share.facade.ts Proxy to RealtimeSessionFacade for screen share signals and methods
|
||||
│ └── screen-share-source-picker.service.ts Electron desktop source picker (Promise-based open/confirm/cancel)
|
||||
│
|
||||
├── domain/
|
||||
│ └── screen-share.config.ts Quality presets and types (re-exported from shared-kernel)
|
||||
│
|
||||
├── feature/
|
||||
│ ├── screen-share-viewer/ Single-stream video player with fullscreen + volume
|
||||
│ └── screen-share-workspace/ Multi-stream grid workspace
|
||||
│ ├── screen-share-workspace.component.ts Grid layout, featured/thumbnail streams, mini-window mode
|
||||
│ ├── screen-share-stream-tile.component.ts Individual stream tile with fullscreen/volume controls
|
||||
│ ├── screen-share-playback.service.ts Per-user mute/volume state for screen share audio
|
||||
│ └── screen-share-workspace.models.ts ScreenShareWorkspaceStreamItem
|
||||
│
|
||||
└── index.ts Barrel exports
|
||||
```
|
||||
|
||||
## Service relationships
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
SSF[ScreenShareFacade]
|
||||
Picker[ScreenShareSourcePickerService]
|
||||
RSF[RealtimeSessionFacade]
|
||||
Config[screen-share.config]
|
||||
Viewer[ScreenShareViewerComponent]
|
||||
Workspace[ScreenShareWorkspaceComponent]
|
||||
Tile[ScreenShareStreamTileComponent]
|
||||
Playback[ScreenSharePlaybackService]
|
||||
|
||||
SSF --> RSF
|
||||
Viewer --> SSF
|
||||
Workspace --> SSF
|
||||
Workspace --> Playback
|
||||
Workspace --> Tile
|
||||
Picker --> Config
|
||||
|
||||
click SSF "application/screen-share.facade.ts" "Proxy to RealtimeSessionFacade" _blank
|
||||
click Picker "application/screen-share-source-picker.service.ts" "Electron source picker" _blank
|
||||
click RSF "../../infrastructure/realtime/realtime-session.service.ts" "Low-level WebRTC composition root" _blank
|
||||
click Viewer "feature/screen-share-viewer/screen-share-viewer.component.ts" "Single-stream player" _blank
|
||||
click Workspace "feature/screen-share-workspace/screen-share-workspace.component.ts" "Multi-stream workspace" _blank
|
||||
click Tile "feature/screen-share-workspace/screen-share-stream-tile.component.ts" "Stream tile" _blank
|
||||
click Playback "feature/screen-share-workspace/screen-share-playback.service.ts" "Per-user volume state" _blank
|
||||
click Config "domain/screen-share.config.ts" "Quality presets" _blank
|
||||
```
|
||||
|
||||
## Starting a screen share
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant Controls as VoiceControls
|
||||
participant Facade as ScreenShareFacade
|
||||
participant Realtime as RealtimeSessionFacade
|
||||
participant Picker as SourcePickerService
|
||||
|
||||
User->>Controls: Click "Share Screen"
|
||||
|
||||
alt Electron
|
||||
Controls->>Picker: open(sources)
|
||||
Picker-->>Controls: selected source + includeSystemAudio
|
||||
end
|
||||
|
||||
Controls->>Facade: startScreenShare(options)
|
||||
Facade->>Realtime: startScreenShare(options)
|
||||
Note over Realtime: Captures screen via platform strategy
|
||||
Note over Realtime: Waits for SCREEN_SHARE_REQUEST from viewers
|
||||
Realtime-->>Facade: MediaStream
|
||||
|
||||
User->>Controls: Click "Stop"
|
||||
Controls->>Facade: stopScreenShare()
|
||||
Facade->>Realtime: stopScreenShare()
|
||||
```
|
||||
|
||||
## Source picker (Electron)
|
||||
|
||||
`ScreenShareSourcePickerService` manages a Promise-based flow for Electron desktop capture. `open()` sets a signal with the available sources, and the UI renders a picker dialog. When the user selects a source, `confirm(sourceId, includeSystemAudio)` resolves the Promise. `cancel()` rejects with an `AbortError`.
|
||||
|
||||
Sources are classified as either `screen` or `window` based on the source ID prefix or name. The `includeSystemAudio` preference is persisted to voice settings storage.
|
||||
|
||||
## Quality presets
|
||||
|
||||
Screen share quality is configured through presets defined in the shared kernel:
|
||||
|
||||
| Preset | Resolution | Framerate |
|
||||
|---|---|---|
|
||||
| `low` | Reduced | Lower FPS |
|
||||
| `balanced` | Medium | Medium FPS |
|
||||
| `high` | Full | High FPS |
|
||||
|
||||
The quality dialog can be shown before each share (`askScreenShareQuality` setting) or skipped to use the last chosen preset.
|
||||
|
||||
## Viewer component
|
||||
|
||||
`ScreenShareViewerComponent` is a single-stream video player. It supports:
|
||||
|
||||
- Fullscreen toggle (browser Fullscreen API with CSS fallback)
|
||||
- Volume control for remote streams (delegated to `VoicePlaybackService`)
|
||||
- Local shares are always muted to avoid feedback
|
||||
- Focus events from other components via a `viewer:focus` custom DOM event
|
||||
- Auto-stop when the watched user stops sharing or the stream's video tracks end
|
||||
|
||||
## Workspace component
|
||||
|
||||
`ScreenShareWorkspaceComponent` is the multi-stream grid view inside the voice workspace panel. It handles:
|
||||
|
||||
- Listing all active screen shares (local + remote) sorted with remote first
|
||||
- Featured/widescreen mode for a single focused stream with thumbnail sidebar
|
||||
- Mini-window mode (draggable, position-clamped to viewport)
|
||||
- Auto-hide header chrome in widescreen mode (2.2 s timeout, revealed on pointer move)
|
||||
- On-demand remote stream requests via `syncRemoteScreenShareRequests`
|
||||
- Per-stream volume and mute via `ScreenSharePlaybackService`
|
||||
- Voice controls (mute, deafen, disconnect, share toggle) integrated into the workspace header
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Hidden
|
||||
Hidden --> Expanded: open()
|
||||
Expanded --> GridView: multiple shares, no focus
|
||||
Expanded --> WidescreenView: single share or focused stream
|
||||
WidescreenView --> GridView: showAllStreams()
|
||||
GridView --> WidescreenView: focusShare(peerKey)
|
||||
Expanded --> Minimized: minimize()
|
||||
Minimized --> Expanded: restore()
|
||||
Expanded --> Hidden: close()
|
||||
Minimized --> Hidden: close()
|
||||
```
|
||||
Reference in New Issue
Block a user