Shared Components
Audience: End users, system administrators, technical stakeholders Last Updated: 2026-04-06 Version: 2.0.0
Table of Contents
- Overview
- Key Concepts
- Media Item Display
- Full Player Ecosystem
- Seekbar System
- Modal & Dialogue System
- Loading States & Skeletons
- Layout & Page Structure
- Text Handling & Marquee
- Animations & Directives
- Formatting Pipes
- Debug & Diagnostic Tools
- Performance optimisation
- Technical Specifications
- Related Documentation
Overview
The Llamafin app includes a comprehensive library of 69 reusable UI components, 5 interactive directives, and 7 data formatting pipes. These shared building blocks create a consistent, polished user experience across every page of the application.
Why It Matters
Rather than recreating common UI patterns for each page, the app uses a unified component library that ensures:
- Visual Consistency: Every list, grid, and card looks the same across the app
- Performance: Components are optimised for smooth animations on all devices
- Maintainability: Improvements to a shared component benefit the entire app
- Accessibility: Consistent keyboard navigation and screen reader support
Component Categories
| Category | Count | Purpose |
|---|---|---|
| Media Item Display | 5 | Rendering songs, albums, artists, playlists |
| Full Player Ecosystem | 12 | Full-screen player, mini-player, controls |
| Seekbar System | 6 | Playback progress with 4 visual styles |
| Modal & Dialogue System | 13 | Settings, playlists, filters, downloads |
| Loading States & Skeletons | 7 | Placeholders during data loading |
| Layout & Page Structure | 5 | Page headers, library layouts, FABs |
| Text Handling & Marquee | 4 | Scrolling text for long titles |
| Animations & Directives | 5 | Animated numbers, long-press, custom scrollbars |
| Formatting Pipes | 7 | Time, file size, image URL resolution |
| Debug & Diagnostic Tools | 7 | Performance monitoring, server discovery |
| Other (profile, progress, etc.) | 8 | Profile pictures, charts, popovers |
Key Concepts
Standalone Components
All 69 components are standalone, meaning they can be imported and used independently without needing a shared module. This modern Angular approach provides:
- Cleaner imports (no module overhead)
- Better tree-shaking (unused components are excluded from builds)
- Easier testing (no module configuration needed)
Change Detection Strategy
Every component uses OnPush change detection, the most performant strategy in Angular. This means components only re-render when their inputs actually change, rather than checking on every application event. For a music player with frequent state updates (seeking, progress, Visualisations), this is essential for smooth 60fps performance.
Settings-Driven UI
Many components automatically adapt their appearance based on user settings:
- Seekbar Style: Users can choose between default, waveform, bars, or spectrogram seekbars
- Spinner Animation: 25+ animation types for loading indicators
- Text Overflow: Marquee vs. sliding vs. simple text scrolling
- Theme Colours: Components adapt to the app's dominant colour from album artwork
Media Item Display
What It Does
The media item display system renders your music library in multiple visual formats depending on context and user preference.
Component Breakdown
| Component | What It Renders | When You See It |
|---|---|---|
| Audio Item | Full media card with artwork, title, artist, duration, download status, and actions | Library browsing (lists, grids, album tracks, playlist tracks) |
| Audio Item Simple | Lightweight text-only item | Up-next queue in the full player |
| Audio Item Image | Album artwork with fallback chain | Inside Audio Item components |
| Audio Item Detail Avatar | Large artwork for detail pages | Library detail pages |
| Audio Item Menu | Context menu with 25+ actions | Long-press on any media item |
Display Modes
The main Audio Item component adapts to four different display modes:
| Mode | Appearance | Use Case |
|---|---|---|
| List | Horizontal row with thumbnail | Compact browsing on all screen sizes |
| Grid | Square card with artwork on top | Visual browsing on tablets/desktops |
| Album Track | Numbered track with duration | Browsing tracks within an album |
| Playlist Track | Track with position and duration | Viewing playlist contents |
Available Actions
Long-pressing any media item opens a context menu with actions appropriate to the item type:
Playback Actions: Play, Shuffle, Play Next, Add to Queue, Instant Mix
Organisation Actions: Add to Playlist, Remove from Playlist, Delete Playlist, Move to Top/Bottom/Custom Position
Navigation Actions: Go to Album, Go to Artist, Go to Playlist, Go to Genre, Go to Folder
Download Actions: Download (with quality options), Pause/Resume/Cancel/Repair/Reset Download, Delete Download
Sharing Actions: Share (native sharing), Delete from Server
Analysis Actions: Process Lyrics, Process Sonic Analysis
Other: Toggle Favorite
How It Works
When you browse your library, the app:
- Fetches Items: Retrieves albums, artists, songs, or playlists from the server or local cache
- Renders via Library Layout: The layout engine decides whether to show a list, grid, or carousel based on your settings and screen size
- Displays Each Item: Each item renders with artwork (resolved from local files or server), metadata, and action buttons
- Handles Interactions: Taps play the item, long-presses open the context menu, and multi-select enables bulk actions
Full Player Ecosystem
What It Does
The full-screen player is the centerpiece of the Llamafin experience. It provides immersive playback Visualisation with album artwork, vinyl turntable animations, audio visualizers, synced lyrics, and comprehensive playback controls.
Component Breakdown
| Component | What It Shows | Interaction |
|---|---|---|
| Full Player Page | Main modal page hosting all player elements | Swipe left/right to cycle views |
| Play Cover | Album artwork in the player | Tap to cycle views |
| Play Record | Vinyl record that spins during playback | Tap to cycle views |
| Play Turntable | Interactive DJ turntable with tonearm | Tap to cycle views |
| Play Visualiser | MilkDrop/Butterchurn audio visualizer | Tap to cycle views |
| Play Lyrics | Synced lyrics with auto-scroll and beat glow | Tap to cycle views |
| Playback Controls | Seekbar, play/pause, skip, volume | Direct interaction |
| Player Up Next | Queue, recently played, and similar songs | Scroll and select |
| Mini Player | Collapsed player at bottom of app | Tap to open full player |
| Play Menu | In-player context menu | Tap menu icon |
| Play DJ Menu | DJ mode selection | Tap DJ icon |
View Cycling
The full player features a 3-page swipe carousel:
| Page | What You See | How to Navigate |
|---|---|---|
| Cover | Album artwork, vinyl record/turntable | Default view, swipe right to go to Visualiser |
| Visualiser | MilkDrop/Butterchurn audio Visualisation | Swipe left to go to Cover, right to go to Lyrics |
| Lyrics | Synced lyrics with active line highlighting | Swipe left to go to Visualiser |
Tap the album artwork to cycle through views: Cover → Record → Turntable → Visualiser → Lyrics → back to Cover.
Turntable Themes
The DJ turntable component supports four visual themes:
| Theme | Style Description |
|---|---|
| Modern | Clean, minimal design with flat colours |
| Vintage | Classic turntable with wood grain accents |
| DJ | Professional DJ setup with mixer elements |
| Audiophile | High-end audiophile aesthetic |
Quality tiers (auto, high, medium, low) adjust the SVG detail level for performance on different devices.
Mini Player
The mini player sits at the bottom of every screen (except the full player) and shows:
- Current track name and artist
- Progress bar
- Play/pause button
- Next track button
Tap the mini player to open the full-screen player modal.
Seekbar System
What It Does
The seekbar system lets you navigate through a track with four distinct visual styles, each powered by audio analysis data when available.
Seekbar Styles
| Style | What It Looks Like | Requirements | Best For |
|---|---|---|---|
| Default | Standard progress bar with spinning thumb | None (always available) | General use, all tracks |
| Waveform | Audio waveform Visualisation | Sonic analysis data | Seeing the song's audio shape |
| Bars | Loudness-based bar Visualisation | Sonic analysis data | Seeing loudness variations |
| Spectrogram | Pre-generated or live spectrogram image | Sonic analysis SVG or live data | Detailed frequency analysis |
How Seek Selection Works
The app automatically chooses which seekbar to show based on:
- Your Setting: Choose your preferred style in Settings → Appearance
- Data Availability: If sonic analysis data isn't available for the current track, the app falls back to the default seekbar
- Performance: On lower-powered devices, the app may simplify rendering for smoother performance
Seekbar Features
| Feature | Description |
|---|---|
| Drag Seeking | Drag your finger along the seekbar to jump to any position |
| Buffered Progress | Shows how much of the track has been downloaded (gray bar behind the progress) |
| Beat Reactivity | Seekbar animations react to the music's beat (spinning thumb, glowing strokes, brightening bars) |
| Magnifier on Drag | Some seekbar styles show a zoomed-in view while dragging for precision |
| Ghost Playhead | Hover over the seekbar to see where you'd seek without committing |
Additional Playback Icons
| Icon | What It Shows |
|---|---|
| Dynamic Skip Icon | Shows skip forward/backward with configurable seconds (e.g., "+10s", "-10s") |
| Playback Speed Icon | Visual indicator of current playback speed (1x, 1.25x, 1.5x, etc.) with motion blur at high speeds |
Modal & Dialogue System
What It Does
The app includes 13 specialized modal dialogues for various tasks like managing playlists, configuring settings, and controlling downloads.
Modal Inventory
| Modal | When It Appears | Key Features |
|---|---|---|
| Add to Playlist | You choose "Add to Playlist" on a song | Browse playlists, create new, load more |
| Playlist List Item | Inside Add to Playlist modal | Shows playlist artwork and track count |
| Choose Library | Multiple libraries available | Select which music library to browse |
| Colour Picker | Customising theme colours | Canvas-based colour field, hue slider, hex input |
| Create Playlist | You choose "Create New Playlist" | Name input, public/private toggle, character counter |
| Download Options | You choose "Download" on an album | Slider to select number of tracks, quality options |
| Filter | You tap the filter icon on a library page | Genres, years, tags, ratings, favorites |
| Selection | You open a multi-select filter | Single/multi-select, infinite scroll, custom values, search |
| Manage Sources | You manage server connections | List servers, select, delete with confirmation |
| View Sort | You tap the sort icon | Context-aware sort options, list/grid toggle |
| Select Visualizer | You choose a visualizer in the player | Lists available visualizers, WebGL check |
| Sleep Timer | You set a sleep timer | Presets (15/30/45/60 min), custom minutes, datetime picker |
| Cast Menu | You tap the cast icon | Jellyfin sessions, P2P peers, local device |
How Modals Work
All modals follow a consistent pattern:
- Opening: You tap a button that triggers the modal
- Interaction: The modal presents options and captures your selection
- Closing: You confirm or cancel, and the modal closes with a smooth two-stage animation (backdrop fade → content slide)
- Result: The parent component receives your selection and acts accordingly
Filter Modal Details
The filter modal lets you narrow down your library view:
| Filter Type | What It Does |
|---|---|
| Genres | Select one or more genres to show |
| Years | Filter by release year range |
| Tags | Filter by Jellyfin tags |
| Ratings | Filter by star rating |
| Favorites Only | Show only favorited items |
Filters work in both online and offline modes, using locally cached filter data when disconnected.
Loading States & Skeletons
What It Does
While data loads from the server or local cache, the app shows placeholder animations so the interface feels responsive and never "stuck."
Skeleton Types
| Context | What It Shows |
|---|---|
| List | Horizontal placeholder rows with thumbnail blocks |
| Grid | Square placeholder cards in a grid layout |
| Detail Header | Large placeholder for album/artist header |
| Detail Page | Full page placeholder for detail view |
| Text Block | Lines of placeholder text |
| Text Header | Bold placeholder text for headers |
Skeleton Animations
| Animation Type | Visual Effect |
|---|---|
| Shimmer | Sweeping light gradient across placeholders |
| Pulse | Gentle opacity pulsing |
| Rainbow Wave | Rainbow gradient sweep (fun, eye-catching) |
| Scanline | Horizontal scanline effect |
| Static | No animation, static gray placeholders |
| None | No skeleton, blank space |
Spinner System
The app includes a smart spinner that chooses between the built-in Ionic spinner and a custom canvas-based spinner with 25+ animation types:
| Animation Category | Examples |
|---|---|
| Classic | Ring, Bars, Pulse |
| Wave-Based | Wave, Equalizer, Oscilloscope, Spectrum Circular |
| Particle-Based | Particles, DNA, Plasma, Constellation, Binary Rain |
| Geometric | Hexagon, Kaleidoscope, Radar, Orbit, Tunnel |
| Creative | Lava Lamp, Vinyl, Clock, Fibonacci, Neon Sign, Lightning, Fire, Glitch, Matrix, Vortex, Ripple |
The spinner automatically adapts to:
- Audio Frequency Data: Some spiners react to the music's beat
- Light/Dark Backgrounds: Automatically adjusts spinner colour for visibility
- Reduced Motion Preference: Respects your device's "Reduce Motion" accessibility setting
Loading Shell
During app boot, a dedicated loading shell shows:
- Progress indicator with active task description
- Rotating tips while loading
- Haptic feedback heartbeat
- Force offline mode skip option
- Retry button
- "Continue Anyway" button for stalled loads
- Export diagnostics button for troubleshooting
Layout & Page Structure
What It Does
Shared layout components provide consistent page structure across the entire app.
Component Breakdown
| Component | Where You See It | What It Provides |
|---|---|---|
| Page Header | Top of every page | Title, back button, network health indicator, sonic analysis indicator, multi-select popover, cast button, export popover, camera cutout compensation |
| Library Layout | All library browsing pages | List/grid/carousel rendering of media items, disc headers, pagination, infinite scroll, reordering |
| Library FAB | Bottom-right of library pages | Context-specific actions (play, shuffle, instant mix, sort, filter, download, scroll to top) |
| Multi-Select Popover | When items are selected | Bulk actions (play next, add to queue, add to playlist, delete, refresh) |
| Alphabet Sidebar | A-Z library views | Quick jump to any letter of the alphabet |
Page Header Features
The page header automatically shows:
- Back Button: Returns to the previous page
- Title: Page name in your selected language
- Loading Indicator: Spins while data loads
- Network Health: Green/yellow/red dot showing connection status
- Sonic Analysis Indicator: Shows when audio analysis data is available
- Camera Cutout Compensation: Adjusts padding on devices with notches
- Cast Button: Appears when remote playback targets are available
- Export Button: Opens popover with diagnostic export options
Library Layout Rendering
The library layout engine automatically chooses the best rendering approach:
| Factor | Decision |
|---|---|
| User Setting | List mode vs. grid mode |
| Screen Size | Number of columns in grid mode |
| Item Count | Carousel for small sets, list/grid for large |
| Item Type | Special rendering for albums, artists, playlists |
| Download Status | Download badge, quality indicator |
| Sonic Analysis | Analysis badge on analyzed tracks |
Text Handling & Marquee
What It Does
Long song titles, album names, and artist names are handled gracefully with automatic scrolling or truncation.
Text Display Modes
| Mode | Behaviour | When Used |
|---|---|---|
| Overflowing Text | Smart delegate to best marquee type | Default for most text |
| Sliding Text | CSS-based slide animation from right to left | When user prefers subtle animation |
| Simple Marquee | Lightweight continuous scroll | For short text that barely overflows |
| Fast Marquee | Full-featured scroll with fade edges | For long text that clearly overflows |
Marquee Features
| Feature | Description |
|---|---|
| Pause on Hover | Hover over text to pause scrolling |
| Pause on Click | Click to pause, click again to resume |
| Fade Edges | Gradient masks create smooth fade at edges |
| Resize Awareness | Automatically adjusts when screen size changes |
| Content Change Detection | Detects when text changes and restarts animation |
Animations & Directives
What They Do
Five custom directives add interactive behaviors to any element they're applied to.
Directive Inventory
| Directive | Selector | What It Does | Where You See It |
|---|---|---|---|
| Count Up | [countUp] | Animates counting from 0 to a target number | Statistics displays, download counts |
| Animated Number | [animatedNumber] | Smoothly transitions between numeric values | Live device metrics, progress displays |
| Custom Scrollbar | [appCustomScrollbar] | Styles scrollbars with app's accent colour, auto-hide | All scrollable content areas |
| Long Press | [long-press] | Distinguishes between tap and long-press gestures | Media items (tap to play, long-press for menu) |
| Right Click | [rightClick] | Captures right-click events, prevents default context menu | Desktop contexts where right-click menus are useful |
Count Up Animation
When a number appears on screen (like a download count or library size), it animates from 0 to the target value using a quadratic ease-out curve (fast start, slow end). The animation completes in 2 seconds by default.
Animated Number
Similar to count-up, but stateful — it remembers the last displayed value and animates from there. Useful for live metrics that change frequently. Emits intermediate values so other components can react to the animation.
Custom Scrollbar
The custom scrollbar automatically:
- Styles the scrollbar with the app's dominant colour (extracted from album artwork)
- Shows the scrollbar when you start scrolling
- Hides the scrollbar after 1 second of inactivity
- Updates the colour dynamically when the dominant colour changes
Long Press
On touch devices, the long-press gesture distinguishes between:
- Tap (quick touch, release within 300ms): Triggers the primary action (e.g., play)
- Long Press (hold for 300ms without moving finger more than 15px): Opens the context menu
- Drag (move finger more than 15px): No action (prevents accidental triggers)
Formatting Pipes
What They Do
Seven pipes transform raw data into human-readable formats throughout the app.
Pipe Inventory
| Pipe Name | What It Formats | Example Input → Output |
|---|---|---|
truncate | Shortens long text to a character limit | "Very Long Song Name" (limit 15) → "Very Long Song..." |
ticksToTimeString | Converts Jellyfin ticks to time string | 36000000000 → "10h" or "30m 45s" |
bytes | Converts bytes to human-readable size | 1572864 → "1.5 MB" |
imageUrl | Resolves image URLs with offline fallback | Album DTO → "blob:..." or "https://..." |
shortNumber | Formats large numbers with bit-rate suffixes | 1500000 → "1.5Mbit" |
safeHtml | Safely renders HTML content | "<b>Bold</b>" → rendered as bold text |
localMediaBlob | Loads bundled media assets as object URLs | "assets/sound/click.mp3" → SafeUrl |
Ticks To Time String
Jellyfin stores time in "ticks" (100-nanosecond units). This pipe converts ticks into a compact, human-readable format:
| Ticks Value | Output |
|---|---|
| 0 | 0s |
| 45,000,000 | 45s |
| 1,800,000,000 | 30m |
| 1,845,000,000 | 30m 45s |
| 86,400,000,000 | 1d |
| 93,600,000,000 | 1d 2h |
The pipe uses your selected language for unit abbreviations (e.g., "d" for days, "h" for hours).
Image URL Resolution
The imageUrl pipe handles the complex task of resolving album artwork:
- Local File: If the item is downloaded, it loads from the local file system
- Remote Server: If online, it builds the Jellyfin image URL with appropriate quality settings
- Artist Image: Special handling for artist portraits
- Fallback: If no image is available, it generates an SVG placeholder with the item's initials
Debug & Diagnostic Tools
What They Do
Seven debug overlay components are available for development and troubleshooting (typically hidden in production builds).
Debug Overlay Inventory
| Overlay | What It Monitors | Update Interval |
|---|---|---|
| Performance Overlay | CPU usage (system and app), disk free space | Every 2 seconds |
| Memory Overlay | JavaScript heap, app RAM, system RAM | Every 2 seconds |
| FPS Overlay | Current, minimum, and maximum frame rate | Every frame (60fps) |
| Audio Debug | Current track, playback status, errors, stream type | Real-time |
| Consolidated Debug Overlay | Combines all above overlays into one | Varies by sub-overlay |
| Stream Pool Debug | Audio stream pool size, crossfading state, individual stream states | Every 500ms |
| Server Discovery | Network server discovery UI with progress | Real-time during discovery |
Server Discovery
The server discovery component helps you find Jellyfin servers on your local network:
- Manual URL Entry: Type in a server URL and test the connection
- Auto-Discovery: Scans the local network for Jellyfin servers
- Progress Indicator: Shows discovery progress
- Server Type Selection: Choose the type of server (Jellyfin, Emby, etc.)
- Start/Stop Controls: Start and stop discovery at any time
Performance optimisation
How Components Stay Fast
The shared component system includes several built-in performance optimizations:
| Technique | What It Does | Impact |
|---|---|---|
| OnPush Change Detection | Components only re-render when inputs change | Dramatically reduces unnecessary checks |
| Outside NgZone | Heavy animations run outside Angular's change detection | Prevents global re-renders during animations |
| RAF with FPS Capping | requestAnimationFrame loops cap at specified FPS | Prevents GPU overload on complex Visualisations |
| Throttle/Debounce | Limits frequency of user input handling | Prevents excessive seeks and API calls |
| Destroy Notifier | Clean unsubscribe from all observables on component destruction | Prevents memory leaks |
| Canvas Over DOM | Complex Visualisations use Canvas instead of DOM elements | Faster rendering for seekbars, spinners, visualizers |
| Standalone Components | Only imported components are bundled | Smaller app size, faster initial load |
Memory Management
- Object URLs: Created for local media blobs, cleaned up when components are destroyed
- RAF Loops: Cancelled on component destruction
- Gesture Listeners: Disposed when components are removed
- Subscriptions: Automatically unsubscribed via
takeUntil(destroy$)pattern
Technical Specifications
Component Statistics
| Metric | Value |
|---|---|
| Total Components | 69 |
| Total Directives | 5 |
| Total Pipes | 7 |
| Standalone Components | 69 (100%) |
| Standalone Directives | 5 (100%) |
| Standalone Pipes | 7 (100%) |
| OnPush Components | 69 (100%) |
| Largest Component | WaveformSeekbarComponent (747 lines) |
| Smallest Component | AlphabetSidebarComponent (30 lines) |
| Average Component Size | ~180 lines |
Seekbar Specifications
| Seekbar Type | Rendering Method | Data Required | Features |
|---|---|---|---|
| Default | HTML/CSS | None | Beat-reactive thumb, drag seeking |
| Waveform | Canvas | Sonic analysis data | 3 rendering styles, magnifier, ghost playhead |
| Bars | Canvas | Sonic analysis data | Loudness bars, magnifier, ghost playhead |
| Spectrogram Static | SVG | Pre-generated SVG URL | Gradient filters, progress colouring |
| Spectrogram Live | Canvas | Live Visualisation data | Time-lens, particle system, HSL mapping |
Spinner Animation Types (25+)
ring, bars, pulse, wave, glitch, particles, dna, plasma, orbit, equalizer, radar, vortex, matrix, hexagon, ripple, spectrum-circular, lava-lamp, tunnel, kaleidoscope, constellation, vinyl, oscilloscope, binary-rain, clock, fibonacci, neon-sign, lightning, fire
Skeleton Animation Types
shimmer, pulse, rainbow-wave, scanline, static, none
Turntable Themes
modern, vintage, dj, audiophile
Turntable Quality Tiers
auto, high, medium, low
Related Documentation
- UI Components - Modal system, alerts, toasts, popovers
- Player & Queue - Full player page, queue management
- Library Management - Library browsing with shared layout components
- Sonic Analysis - Waveform and bars seekbars with analysis data
- Settings System - Appearance settings that drive component behaviour
Last Updated: 2026-04-06 Version: 2.0.0