Catalog Browsing
Relevant source files
The following files were used as context for generating this wiki page:
- Sources/Spotty/Spotify/HomeLibraryStore.swift
- Sources/Spotty/Spotify/CatalogMetadataRepository.swift
- Sources/Spotty/Spotify/CatalogMapping.swift
- Sources/Spotty/Spotify/PartnerAPI.swift
- Sources/SpottyDomain/CatalogModels.swift
- Sources/Spotty/Views/HomeView.swift
- Tests/SpottyBoundaryTests/MediaDetailStoreChecks.swift
- Tests/SpottyBoundaryTests/SearchStoreChecks.swift
Catalog Browsing facilitates the discovery and navigation of Spotify content, including the Home page, search results, and personal library items such as playlists, albums, and artists. The system transforms raw GraphQL data from Spotify's "Pathfinder" API into structured domain models used for native macOS rendering.
The architecture separates concerns into a layered flow: the PartnerAPI handles network transport, CatalogMapping converts transport objects to domain entities, and specialized stores like HomeLibraryStore and SearchStore manage state and view-lifecycle events.
Architecture and Data Flow
The browsing system coordinates data between the Spotify backend and the SwiftUI interface using the following sequence:
The diagram shows the standard lifecycle of a catalog request, from user intent to metadata enrichment.
Sources: Sources/Spotty/Spotify/HomeLibraryStore.swift:145-160, Sources/Spotty/Spotify/CatalogMetadataRepository.swift:129-150
Core Components
HomeLibraryStore
HomeLibraryStore manages launch-critical content and account-scoped library state. It performs concurrent loads for the Home view, user profile, and sidebar playlists.
- Lazy Loading: Albums, artists, and liked tracks are loaded only when requested to optimize initial startup.
- State Management: Tracks
loadingSections,loadedSections, and section-specific errors to drive UI states likeLoadingStateandEmptyState. - Session Safety: Uses
CatalogSessionSnapshotandaccountEpochto ensure that data from previous sessions or different accounts does not overwrite current state.
Sources: Sources/Spotty/Spotify/HomeLibraryStore.swift:14-43, Sources/Spotty/Spotify/HomeLibraryStore.swift:88-121
CatalogMetadataRepository
This repository acts as a session-scoped lookup and enrichment engine. It retains track metadata based on its source (e.g., Search, Playlist, or Queue) and fetches additional attributes.
- Track Enrichment: Automatically requests BPM, Camelot Key, and Popularity in batches of 100 tracks.
- Cache Trimming: Limits the attribute cache to 20,000 entries to prevent excessive memory usage.
- Source Priority: Higher-value catalog sources (like searched items) take precedence over provisional metadata from the playback queue.
Sources: Sources/Spotty/Spotify/CatalogMetadataRepository.swift:16-33, Sources/Spotty/Spotify/CatalogMetadataRepository.swift:129-135
PartnerAPI
PartnerAPI executes GraphQL queries against api-partner.spotify.com/pathfinder/v2/query.
- Persisted Queries: Uses SHA-256 hashes of queries instead of sending full document strings.
- Pagination: Uses a generic
paginatefunction to walk paged responses for playlists and library lists until all entities are retrieved. - Mutation Handling: Recognizes
PathfinderMutationResultto detect failures hidden within HTTP 200 responses.
Sources: Sources/Spotty/Spotify/PartnerAPI.swift:94-110, Sources/Spotty/Spotify/PartnerAPI.swift:198-220
Data Models
Catalog data is normalized into three primary structures defined in SpottyDomain.
| Model | Purpose | Key Fields |
|---|---|---|
CatalogTrack | Represents a playable track in a list. | uri, title, artist, duration, addedAt |
CatalogItem | A generic card for albums, artists, or playlists. | kind, artworkURL, ownerURI |
CatalogSection | Represents a "Shelf" or grouping on the Home page. | title, items |
Sources: Sources/SpottyDomain/CatalogModels.swift:9-25, Sources/SpottyDomain/CatalogModels.swift:51-70
Search Logic
The SearchStore manages the user's search intent with specific timing constraints to prevent excessive API calls.
This flowchart illustrates the debounce and admission logic used in SearchStore.
Sources: Tests/SpottyBoundaryTests/SearchStoreChecks.swift:108-140
Metadata Enrichment Process
When tracks are loaded into the catalog, the CatalogMetadataRepository initiates a batch enrichment process.
- Identification: Extracts all
spotify:track:URIs from the loaded collection. - Filtering: Excludes URIs already in the cache or currently in-flight.
- Batching: Groups URIs into batches of 100 for API efficiency.
- Fetch: Requests
TrackAttributes(Popularity, BPM, Camelot Key) from theattributesProvider. - Update: Merges new attributes into the repository and increments the
trackAttributesRevisionto trigger UI updates.
Sources: Sources/Spotty/Spotify/CatalogMetadataRepository.swift:129-160, Sources/Spotty/Spotify/CatalogMetadataRepository.swift:179-196
UI Components
HomeView
Displays the Home page using LazyVStack to handle large amounts of shelf data efficiently. It supports two shelf styles:
- Quick Access: Smaller cards for recently played or pinned items (top of the page).
- Media Shelf: Horizontal scrolling rows for albums, artists, and recommendations.
Sources: Sources/Spotty/Views/HomeView.swift:18-50, Sources/Spotty/Views/HomeView.swift:85-102
MediaDetailHeader
A shared component that provides identity for albums, artists, and playlists. It adapts its layout (compact vs. horizontal) based on available width and the specific MediaDetailHeaderStyle.
Sources: Sources/Spotty/Views/MediaDetailHeader.swift:10-40
Catalog Browsing provides a robust framework for navigating Spotify's vast content library by combining efficient GraphQL transport, predictive metadata enrichment, and a session-safe state management system.