Skip to content

2 Architecture Overview

ankrypht edited this page Jul 16, 2025 · 1 revision

Page: Architecture Overview

Architecture Overview

Relevant source files

The following files were used as context for generating this wiki page:

This document provides a high-level overview of the AudioScape system architecture, covering the core frameworks, navigation patterns, state management, and external service integrations that comprise the music streaming application.

For detailed information about specific UI components and screens, see User Interface System. For in-depth coverage of the music playback functionality, see Music Playback System. For data management and persistence details, see Data and State Management.

System Architecture

AudioScape is built on React Native with Expo, implementing a modular architecture that separates concerns across navigation, state management, audio processing, and external service integration.

Core Framework Stack

graph TB
    subgraph "Foundation Layer"
        EXPO["expo (Framework)"]
        RN["react-native"]
        ROUTER["expo-router"]
    end
    
    subgraph "Navigation Layer"
        STACK["Stack Navigator"]
        TABS["Tabs Navigator"]
        MODALS["Modal Screens"]
    end
    
    subgraph "State Management"
        REDUX["Redux Store (library.tsx)"]
        MUSIC_CTX["MusicPlayerContext"]
        LYRICS_CTX["LyricsProvider"]
    end
    
    subgraph "Audio Engine"
        TRACK_PLAYER["react-native-track-player"]
        BG_SERVICE["playbackService"]
    end
    
    EXPO --> RN
    RN --> ROUTER
    ROUTER --> STACK
    ROUTER --> TABS
    ROUTER --> MODALS
    
    REDUX --> MUSIC_CTX
    MUSIC_CTX --> TRACK_PLAYER
    TRACK_PLAYER --> BG_SERVICE
Loading

Sources: app/_layout.tsx:10-34, app/(tabs)/_layout.tsx:11-14, components/MusicPlayerContext.tsx:10-27, store/library.tsx:9-10

Application Layer Architecture

The application follows a provider-based architecture where global contexts wrap the entire app to manage cross-cutting concerns:

graph TD
    ROOT["RootLayout (app/_layout.tsx)"] --> PROVIDERS["Global Providers"]
    
    subgraph "Provider Stack"
        REDUX_PROV["Redux Provider"]
        MUSIC_PROV["MusicPlayerProvider"] 
        LYRICS_PROV["LyricsProvider"]
        SAFE_AREA["SafeAreaProvider"]
        GESTURE["GestureHandlerRootView"]
    end
    
    PROVIDERS --> REDUX_PROV
    REDUX_PROV --> MUSIC_PROV
    MUSIC_PROV --> LYRICS_PROV
    LYRICS_PROV --> SAFE_AREA
    SAFE_AREA --> GESTURE
    
    GESTURE --> NAV_STACK["Navigation Stack"]
    
    subgraph "Navigation Structure"
        TABS_SCREEN["(tabs) - Main App"]
        PLAYER_MODAL["player - Music Player"]
        MODAL_SCREENS["(modals)/* - Action Modals"]
    end
    
    NAV_STACK --> TABS_SCREEN
    NAV_STACK --> PLAYER_MODAL
    NAV_STACK --> MODAL_SCREENS
Loading

Sources: app/_layout.tsx:105-181, components/MusicPlayerContext.tsx:97-99, store/library.tsx:265-269

Navigation Architecture

The navigation system uses expo-router with a stack-based approach, implementing both tab navigation for main content and modal presentations for contextual actions.

Route Structure

graph TD
    ROOT_LAYOUT["_layout.tsx"] --> MAIN_STACK["Stack Navigator"]
    
    MAIN_STACK --> TABS_GROUP["(tabs)/_layout.tsx"]
    MAIN_STACK --> PLAYER["player.tsx"]
    MAIN_STACK --> MODALS["(modals)/*"]
    
    subgraph "Tab Navigation"
        TABS_GROUP --> HOME_TAB["home/*"]
        TABS_GROUP --> FAV_TAB["favorites.tsx"]
        TABS_GROUP --> PLAYLIST_TAB["playlists.tsx"] 
        TABS_GROUP --> DOWNLOAD_TAB["downloads.tsx"]
        TABS_GROUP --> FLOATING["FloatingPlayer"]
    end
    
    subgraph "Modal System"
        MODALS --> QUEUE_M["queue.tsx"]
        MODALS --> LYRICS_M["lyrics.tsx"]
        MODALS --> MENU_M["menu.tsx"]
        MODALS --> PLAYLIST_M["addToPlaylist.tsx"]
        MODALS --> DELETE_M["deletePlaylist.tsx"]
    end
    
    subgraph "Home Stack"
        HOME_TAB --> HOME_INDEX["index.tsx"]
        HOME_TAB --> ARTIST["artist/[id].tsx"]
        HOME_TAB --> ALBUM["album/[id].tsx"]
        HOME_TAB --> SEARCH["search.tsx"]
    end
Loading

Sources: app/_layout.tsx:118-171, app/(tabs)/_layout.tsx:23-140, app/(modals)/menu.tsx:47

Tab Bar Configuration

The tab navigation implements a custom design with gradient background and floating player integration:

Tab Route Icon Component
Home home home/home-outline Home content and search
Favorites favorites heart/heart-outline Liked songs
Playlists playlists list/list-outline User playlists
Downloads downloads download/download-outline Offline content

Sources: app/(tabs)/_layout.tsx:67-117

State Management Architecture

The application employs a dual-state approach combining Redux for persistent data and React Context for transient playback state.

State Flow Diagram

graph LR
    subgraph "UI Components"
        PLAYER_UI["PlayerScreen"]
        TAB_UI["Tab Screens"]  
        MODAL_UI["Modal Components"]
    end
    
    subgraph "Context Layer"
        MUSIC_CTX["MusicPlayerContext"]
        LYRICS_CTX["LyricsProvider"]
    end
    
    subgraph "Redux Store"
        LIB_STATE["LibraryState"]
        FAV_SLICE["favoriteTracks"]
        PLAYLIST_SLICE["playlists"]
        DOWNLOAD_SLICE["downloadedTracks"]
    end
    
    subgraph "Persistence"
        FILE_SYS["FileSystem (libraryData.json)"]
        MMKV_STORE["MMKV Storage"]
    end
    
    subgraph "Audio Engine"
        TRACK_PLAYER["TrackPlayer"]
        QUEUE_MGR["Queue Management"]
    end
    
    PLAYER_UI --> MUSIC_CTX
    TAB_UI --> LIB_STATE
    MODAL_UI --> MUSIC_CTX
    MODAL_UI --> LIB_STATE
    
    MUSIC_CTX --> TRACK_PLAYER
    MUSIC_CTX --> QUEUE_MGR
    
    LIB_STATE --> FILE_SYS
    MUSIC_CTX --> MMKV_STORE
    
    TRACK_PLAYER --> QUEUE_MGR
Loading

Sources: components/MusicPlayerContext.tsx:33-45, store/library.tsx:16-21, store/library.tsx:55-62

Redux State Structure

The LibraryState interface defines the persistent data model:

interface LibraryState {
  favoriteTracks: Song[];
  playlists: Record<string, Song[]>;
  downloadedTracks: DownloadedSongMetadata[];
  activeDownloads: Record<string, { song: Song; progress: number }>;
}

Sources: store/library.tsx:16-21, store/library.tsx:26-35

External Service Integration

AudioScape integrates with multiple external services for content delivery, lyrics, and app management.

Service Integration Architecture

graph TB
    subgraph "AudioScape Core"
        MUSIC_CTX["MusicPlayerContext"]
        DOWNLOAD_SVC["Download Service"]
        UPDATE_SVC["Update System"]
    end
    
    subgraph "YouTube Integration"
        YT_API["YouTube 'po token' API"]
        INNERTUBE["innertube Service"]
        YT_JS["YouTube.js Library"]
    end
    
    subgraph "Content Services"
        LRCLIB["LrcLib Lyrics API"]
        FIREBASE["Firebase Services"]
    end
    
    subgraph "Infrastructure"
        GITHUB["GitHub Releases"]
        RENDER["Render.com Hosting"]
    end
    
    MUSIC_CTX --> YT_API
    MUSIC_CTX --> LRCLIB
    
    YT_API --> INNERTUBE
    INNERTUBE --> YT_JS
    
    DOWNLOAD_SVC --> YT_API
    UPDATE_SVC --> GITHUB
    
    YT_API -.->|"Hosted on"| RENDER
    UPDATE_SVC --> FIREBASE
Loading

Sources: components/MusicPlayerContext.tsx:18, services/youtube.ts, app/(modals)/menu.tsx:26

API Integration Points

Service Purpose Integration Point
YouTube Music API Stream audio content getInfo(), innertube
LrcLib Synchronized lyrics LyricsProvider
Firebase Remote config, messaging Global initialization
GitHub API App updates UpdateModal

Sources: components/MusicPlayerContext.tsx:432-496, app/_layout.tsx:82-84

Core Component Interactions

The system's core functionality emerges from the interaction between the MusicPlayerContext, Redux store, and TrackPlayer:

Playback Flow

sequenceDiagram
    participant UI as "UI Component"
    participant CTX as "MusicPlayerContext"
    participant TP as "TrackPlayer"
    participant YT as "YouTube API"
    participant REDUX as "Redux Store"
    
    UI->>CTX: playAudio(song, playlist?)
    CTX->>YT: getInfo(songId)
    YT-->>CTX: Track metadata + stream URL
    CTX->>TP: add(trackInfo)
    CTX->>TP: play()
    CTX->>CTX: addPlaylistTracksInBackground()
    CTX->>REDUX: Update favorites/playlists
    REDUX->>REDUX: saveToFile()
Loading

Sources: components/MusicPlayerContext.tsx:507-600, components/MusicPlayerContext.tsx:135-273, store/library.tsx:55-62

The architecture provides clear separation of concerns while maintaining efficient data flow between the UI layer, business logic contexts, persistent storage, and external services. The modular design enables independent testing and maintenance of each subsystem while ensuring consistent user experience across the application.

Clone this wiki locally