mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-13 07:46:40 +02:00
feat: add recent access history, artist screen redesign, and extension improvements
Recent Access History: - Quick access to recently visited artists, albums, playlists, and tracks - Tap search bar to show recent access list - Stays visible after keyboard dismiss, exit with back button - Persists across app restarts (SharedPreferences) - X button to remove items, Clear All button for all Artist Screen Redesign: - Full-width header image with gradient overlay - Monthly listeners display with compact notation - Popular section with top 5 tracks and download status - Extension artists skip Spotify/Deezer fetch (no rate limit errors) Go Backend: - GetArtistWithExtensionJSON now returns top_tracks, header_image, listeners Bug Fixes: - Search bar unfocus when tapping outside - Keyboard not appearing on Settings navigation return - Recent access artist navigation uses correct screen for extensions - Extension artist screen correctly parses and forwards top tracks Localization: - Added recentPlaylistInfo, errorGeneric strings - Multi-language support via Crowdin Extensions: - YT Music: v1.5.0 (top_tracks in getArtist) - Spotify Web: v1.6.0
This commit is contained in:
+62
-4
@@ -1657,10 +1657,12 @@ func HandleURLWithExtensionJSON(url string) (string, error) {
|
||||
// Add artist info if present
|
||||
if result.Artist != nil {
|
||||
artistResponse := map[string]interface{}{
|
||||
"id": result.Artist.ID,
|
||||
"name": result.Artist.Name,
|
||||
"image_url": result.Artist.ImageURL,
|
||||
"provider_id": result.Artist.ProviderID,
|
||||
"id": result.Artist.ID,
|
||||
"name": result.Artist.Name,
|
||||
"image_url": result.Artist.ImageURL,
|
||||
"header_image": result.Artist.HeaderImage,
|
||||
"listeners": result.Artist.Listeners,
|
||||
"provider_id": result.Artist.ProviderID,
|
||||
}
|
||||
|
||||
// Add albums if present
|
||||
@@ -1686,6 +1688,29 @@ func HandleURLWithExtensionJSON(url string) (string, error) {
|
||||
artistResponse["albums"] = albums
|
||||
}
|
||||
|
||||
// Add top tracks if present
|
||||
if len(result.Artist.TopTracks) > 0 {
|
||||
topTracks := make([]map[string]interface{}, len(result.Artist.TopTracks))
|
||||
for i, track := range result.Artist.TopTracks {
|
||||
topTracks[i] = map[string]interface{}{
|
||||
"id": track.ID,
|
||||
"name": track.Name,
|
||||
"artists": track.Artists,
|
||||
"album_name": track.AlbumName,
|
||||
"album_artist": track.AlbumArtist,
|
||||
"duration_ms": track.DurationMS,
|
||||
"images": track.ResolvedCoverURL(),
|
||||
"release_date": track.ReleaseDate,
|
||||
"track_number": track.TrackNumber,
|
||||
"disc_number": track.DiscNumber,
|
||||
"isrc": track.ISRC,
|
||||
"provider_id": track.ProviderID,
|
||||
"spotify_id": track.SpotifyID,
|
||||
}
|
||||
}
|
||||
artistResponse["top_tracks"] = topTracks
|
||||
}
|
||||
|
||||
response["artist"] = artistResponse
|
||||
}
|
||||
|
||||
@@ -1920,6 +1945,39 @@ func GetArtistWithExtensionJSON(extensionID, artistID string) (string, error) {
|
||||
"provider_id": artist.ProviderID,
|
||||
}
|
||||
|
||||
// Add header image if present
|
||||
if artist.HeaderImage != "" {
|
||||
response["header_image"] = artist.HeaderImage
|
||||
}
|
||||
|
||||
// Add listeners if present
|
||||
if artist.Listeners > 0 {
|
||||
response["listeners"] = artist.Listeners
|
||||
}
|
||||
|
||||
// Add top tracks if present
|
||||
if len(artist.TopTracks) > 0 {
|
||||
topTracks := make([]map[string]interface{}, len(artist.TopTracks))
|
||||
for i, track := range artist.TopTracks {
|
||||
topTracks[i] = map[string]interface{}{
|
||||
"id": track.ID,
|
||||
"name": track.Name,
|
||||
"artists": track.Artists,
|
||||
"album_name": track.AlbumName,
|
||||
"album_artist": track.AlbumArtist,
|
||||
"duration_ms": track.DurationMS,
|
||||
"images": track.ResolvedCoverURL(),
|
||||
"release_date": track.ReleaseDate,
|
||||
"track_number": track.TrackNumber,
|
||||
"disc_number": track.DiscNumber,
|
||||
"isrc": track.ISRC,
|
||||
"provider_id": track.ProviderID,
|
||||
"spotify_id": track.SpotifyID,
|
||||
}
|
||||
}
|
||||
response["top_tracks"] = topTracks
|
||||
}
|
||||
|
||||
jsonBytes, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -30,7 +30,7 @@ type ExtTrackMetadata struct {
|
||||
DiscNumber int `json:"disc_number,omitempty"`
|
||||
ISRC string `json:"isrc,omitempty"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ItemType string `json:"item_type,omitempty"` // track, album, or playlist - for extension search results
|
||||
ItemType string `json:"item_type,omitempty"` // track, album, or playlist - for extension search results
|
||||
AlbumType string `json:"album_type,omitempty"` // album, single, ep, compilation
|
||||
// Enrichment fields from Odesli/song.link
|
||||
TidalID string `json:"tidal_id,omitempty"`
|
||||
@@ -63,11 +63,14 @@ type ExtAlbumMetadata struct {
|
||||
|
||||
// ExtArtistMetadata represents artist metadata from an extension
|
||||
type ExtArtistMetadata struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
Albums []ExtAlbumMetadata `json:"albums,omitempty"`
|
||||
ProviderID string `json:"provider_id"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
HeaderImage string `json:"header_image,omitempty"` // Header image for artist page background
|
||||
Listeners int `json:"listeners,omitempty"` // Monthly listeners
|
||||
Albums []ExtAlbumMetadata `json:"albums,omitempty"`
|
||||
TopTracks []ExtTrackMetadata `json:"top_tracks,omitempty"` // Popular tracks
|
||||
ProviderID string `json:"provider_id"`
|
||||
}
|
||||
|
||||
// ExtSearchResult represents search results from an extension
|
||||
@@ -1252,6 +1255,10 @@ func (p *ExtensionProviderWrapper) HandleURL(url string) (*ExtURLHandleResult, e
|
||||
handleResult.Artist.Albums[i].Tracks[j].ProviderID = p.extension.ID
|
||||
}
|
||||
}
|
||||
// Set provider ID on top tracks
|
||||
for i := range handleResult.Artist.TopTracks {
|
||||
handleResult.Artist.TopTracks[i].ProviderID = p.extension.ID
|
||||
}
|
||||
}
|
||||
|
||||
return &handleResult, nil
|
||||
|
||||
Reference in New Issue
Block a user