Client & Uno Platform Architecture¶
The Cantus client is built with Uno Platform, enabling a unified C# and XAML codebase to run natively across Linux (Skia/X11), Windows (WinUI 3), and modern web browsers via WebAssembly.
Client MVVM Pattern¶
The client architecture cleanly isolates presentation logic from real-time network communications:
flowchart TD
subgraph Network Layer
SignalR[SignalRPlaybackClient]
Context[CantusJsonContext Source Generator]
SignalR -.-> Context
end
subgraph MVVM ViewModels
LVM[LyricsViewModel]
LLVM[LyricLineViewModel Collection]
Theme[ThemeManager]
Layout[ResponsiveLayoutManager]
LVM --> LLVM
LVM --> Theme
LVM --> Layout
end
subgraph XAML Views
MainView[MainPage.xaml]
Header[AdaptiveHeaderBar.xaml]
TrackCard[AdaptiveTrackCard.xaml]
LyricsStage[LyricsStageView.xaml]
MobileSettings[MobileSettingsView.xaml]
MainView --> Header
MainView --> TrackCard
MainView --> LyricsStage
MainView --> MobileSettings
end
SignalR -->|PlaybackState / Lyrics / NTP / Sessions| LVM
LVM -->|Direct 1-Level Data Binding| MainView
Core Client Components¶
1. SignalRPlaybackClient¶
- Manages the WebSocket lifecycle: automatic reconnect with exponential backoff, clock synchronization, and dispatching incoming payload events.
- Utilizes
CantusJsonContext(JsonSerializerContext) for AOT / trimmed WebAssembly source-generated JSON deserialization, ensuring zero reflection overhead and maximum runtime reliability. - Runs the 4-timestamp NTP clock synchronization loop.
- Exposes
ReportVisibilityAsync(bool isVisible)to signal document visibility state to the server andRefreshPlaybackAsync()for on-demand poll wakeups.
2. LyricsViewModel¶
- Coordinates overall state: active playback progress, song metadata, lyrics line collection, authorized Spotify sessions, and instrumental breaks.
- Provides flattened 1-level direct visual properties (
BackgroundBrush,SurfaceCardBrush,NoSessionsVisibility,HasSessionsVisibility,CurrentBreakpoint) ensuring thread-safe, compile-time verified XAML{x:Bind}execution across all platforms. - Drives the 60 FPS animation tick loop (
OnTick), evaluating which line should be marked active based on the synchronized clock. - Manages scroll interaction state:
IsUserScrollingPaused,IsAutoScrollEnabled,ResumeAutoScroll(), and theAutoScrollResumedevent.
3. LyricsStageView & Auto-Scroll Controller¶
- Implements intelligent auto-scroll with manual override detection:
- Programmatic Scroll Filtering: Uses a 450ms debounce flag (
_isProgrammaticScroll) to distinguish internal centering adjustments from user-driven mouse wheel, touch, or drag events. - Manual Pause & Auto-Resume: When manual scrolling is detected, pauses auto-scrolling and starts a 3-second
DispatcherTimer(_autoResumeTimer). When the timer expires or the user clicks the floating resume button, it callsResumeAutoScroll()and smooth-scrolls back to the active line. - Dynamic Viewport Padding: Computes top and bottom padding at runtime based on container height so that both the first and final lines of any track can be aligned to the vertical center.
4. WasmInterop Browser Hooks¶
- Embedded JavaScript bridge for Uno WebAssembly:
- Hooks into browser
document.addEventListener("visibilitychange")to track tab focus/minimization. - Relays visibility state into C# via
SignalRPlaybackClient.ReportVisibilityAsync, enabling server-side background poll rate reduction.
5. LyricLineViewModel¶
- Represents an individual lyric line with observable properties for:
IsActive: Whether this line is currently being sung.IsPast: Whether this line has already finished.LineBrush,FontSize,FontWeight, andOpacity: Visual styling dynamically driven by theme and active state.
6. ThemeManager & ResponsiveLayoutManager¶
ThemeManagerextracts dynamic palettes from album artwork bytes and provides WCAG-compliant high-contrast theme brushes.ResponsiveLayoutManagerdynamically classifies viewports intoCompact,Medium,Expanded,LargeDesktop, andFullscreenTvbreakpoints.
Target Runtime Matrix¶
| Platform Target | Runtime Engine | UI Backend | Packaging |
|---|---|---|---|
| WebAssembly (WASM) | .NET 10 WebAssembly | Uno DOM/HTML Engine | Embedded in Docker container (wwwroot). |
| Linux Desktop / Raspberry Pi | .NET 10 CoreCLR | Skia / X11 / Wayland | Standalone native binary / Flatpak. |
| Windows Desktop | .NET 10 CoreCLR | WinUI 3 / Windows App SDK | MSIX / Standalone .exe. |