Repository: KRTirtho/spotube
File: lib/extensions/track.dart (Dart)

Code before:
      album: album?.name,
      albumArtist: artists?.map((a) => a.name).join(", "),
      year: album?.releaseDate != null
          ? int.tryParse(album!.releaseDate!.split("-").first) ?? 1969
          : 1969,
      trackNumber: trackNumber,
      discNumber: discNumber,
      durationMs: durationMs?.toDouble() ?? 0.0,
      fileSize: BigInt.from(fileLength),
      trackTotal: album?.tracks?.length ?? 0,
      picture: imageBytes != null
          ? Picture(
              data: imageBytes,
              // Spotify images are always JPEGs
              mimeType: 'image/jpeg',
            )
          : null,
    );
  }
}

extension TrackSimpleExtensions on TrackSimple {
  Future<Track> asTrack(AlbumSimple album, ref) async {
    try {
      final spotify = ref.read(spotifyProvider);
      return await spotify.invoke((api) => api.tracks.get(id!));
    } catch (e, stack) {
      // Ignore errors and create the track locally
      AppLogger.reportError(e, stack);

      Track track = Track();
      track.name = name;
      track.album = album;	
      track.artists = artists;	
      track.availableMarkets = availableMarkets;	
      track.discNumber = discNumber;	
      track.durationMs = durationMs;	
      track.explicit = explicit;	
      track.externalUrls = externalUrls;	
      track.href = href;	
      track.id = id;	
      track.isPlayable = isPlayable;	
      track.linkedFrom = linkedFrom;	
      track.name = name;	
      track.previewUrl = previewUrl;	
      track.trackNumber = trackNumber;	
      track.type = type;	
      track.uri = uri;	
      return track;
    }
  }

Review comment (suggestion):
This will make a request for each track of an album. Instead, just delete this extension method and replace it with [get-several-track](https://developer.spotify.com/documentation/web-api/reference/get-several-tracks) (`spotify.tracks.list(<ids>)` for dart)

Or create an extension method on `Iterable<TrackSimple>` where you map the ids of the `TrackSimple` then get the tracks using  `spotify.tracks.list(<ids>)`

`TrackSimple.asTrack` is used in 
- [lib/modules/album/album_card.dart](https://github.com/KRTirtho/spotube/blob/0ec9f3535bf9c927d81cb67e62aa35da36648c98/lib/modules/album/album_card.dart#L57)
- [lib/provider/spotify/album/tracks.dart](https://github.com/KRTirtho/spotube/blob/0ec9f3535bf9c927d81cb67e62aa35da36648c98/lib/provider/spotify/album/tracks.dart#L36)

Code after:
      album: album?.name,
      albumArtist: artists?.map((a) => a.name).join(", "),
      year: album?.releaseDate != null
          ? int.tryParse(album!.releaseDate!.split("-").first) ?? 1969
          : 1969,
      trackNumber: trackNumber,
      discNumber: discNumber,
      durationMs: durationMs?.toDouble() ?? 0.0,
      fileSize: BigInt.from(fileLength),
      trackTotal: album?.tracks?.length ?? 0,
      picture: imageBytes != null
          ? Picture(
              data: imageBytes,
              // Spotify images are always JPEGs
              mimeType: 'image/jpeg',
            )
          : null,
    );
  }
}

extension IterableTrackSimpleExtensions on Iterable<TrackSimple> {
  Future<List<Track>> asTracks(AlbumSimple album, ref) async {
    try {
      final spotify = ref.read(spotifyProvider);
      final tracks = await spotify.invoke(
        (api) => api.tracks.list(map((trackSimple) => trackSimple.id!).toList()));
      return tracks.toList();
    } catch (e, stack) {
      // Ignore errors and create the track locally
      AppLogger.reportError(e, stack);

      List<Track> tracks = [];
      for (final trackSimple in this) {
        Track track = Track();
        track.album = album;
        track.name = trackSimple.name;
        track.artists = trackSimple.artists;
        track.availableMarkets = trackSimple.availableMarkets;
        track.discNumber = trackSimple.discNumber;
        track.durationMs = trackSimple.durationMs;
        track.explicit = trackSimple.explicit;
        track.externalUrls = trackSimple.externalUrls;
        track.href = trackSimple.href;
        track.id = trackSimple.id;
        track.isPlayable = trackSimple.isPlayable;
        track.linkedFrom = trackSimple.linkedFrom;
        track.previewUrl = trackSimple.previewUrl;
        track.trackNumber = trackSimple.trackNumber;
        track.type = trackSimple.type;
        track.uri = trackSimple.uri;