Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use audio lists instead of sets for performance #825

Merged
merged 1 commit into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/common/view/avatar_play_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class AvatarPlayButton extends StatelessWidget with WatchItMixin {
required this.pageId,
});

final Set<Audio> audios;
final List<Audio> audios;
final String pageId;

@override
Expand Down
4 changes: 2 additions & 2 deletions lib/common/view/like_all_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import 'package:watch_it/watch_it.dart';
class LikeAllIcon extends StatelessWidget with WatchItMixin {
const LikeAllIcon({super.key, required this.audios});

final Set<Audio> audios;
final List<Audio> audios;

@override
Widget build(BuildContext context) {
final likedAudios = watchPropertyValue((LibraryModel m) => m.likedAudios);
final libraryModel = di<LibraryModel>();

final liked = likedAudios.containsAll(audios);
final liked = Set.from(likedAudios).containsAll(audios);
return IconButton(
onPressed: () => liked
? libraryModel.removeLikedAudios(audios)
Expand Down
2 changes: 1 addition & 1 deletion lib/common/view/like_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class RadioLikeIcon extends StatelessWidget with WatchItMixin {
? libraryModel.unStarStation(audio!.url!, popOnUnstar)
: libraryModel.addStarredStation(
audio!.url!,
{audio!},
[audio!],
);
};
}
Expand Down
4 changes: 2 additions & 2 deletions lib/common/view/sliver_audio_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class SliverAudioPage extends StatelessWidget {
});

final String pageId;
final Set<Audio>? audios;
final List<Audio>? audios;
final AudioPageType audioPageType;

final String? pageTitle;
Expand Down Expand Up @@ -111,7 +111,7 @@ class SliverAudioPage extends StatelessWidget {
SliverAudioPageControlPanel(
controlPanel: controlPanel ??
AvatarPlayButton(
audios: audios ?? {},
audios: audios ?? [],
pageId: pageId,
),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/common/view/sliver_audio_tile_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class SliverAudioTileList extends StatelessWidget with WatchItMixin {
required this.audioPageType,
});

final Set<Audio> audios;
final List<Audio> audios;
final String pageId;
final AudioPageType audioPageType;
final void Function(String text)? onSubTitleTab;
Expand Down
16 changes: 8 additions & 8 deletions lib/external_path/external_path_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ExternalPathService {
readMetadata(File(path), getImage: true).then(
(data) => _playerService.startPlaylist(
listName: path,
audios: {Audio.fromMetadata(path: path, data: data)},
audios: [Audio.fromMetadata(path: path, data: data)],
),
);
} catch (_) {}
Expand All @@ -59,16 +59,16 @@ class ExternalPathService {
readMetadata(File(xfile!.path), getImage: true).then(
(metadata) => _playerService.startPlaylist(
listName: xfile.path,
audios: {Audio.fromMetadata(path: xfile.path, data: metadata)},
audios: [Audio.fromMetadata(path: xfile.path, data: metadata)],
),
);
});
} on Exception catch (_) {}
}
}

Future<(String?, Set<Audio>?)> loadPlaylistFromFile() async {
Set<Audio>? audios;
Future<(String?, List<Audio>?)> loadPlaylistFromFile() async {
List<Audio>? audios;
String? path;

if (Platform.isMacOS || Platform.isLinux || Platform.isWindows) {
Expand All @@ -87,8 +87,8 @@ class ExternalPathService {
return (path, audios);
}

Future<Set<Audio>> _parseM3uPlaylist(String path) async {
final audios = <Audio>{};
Future<List<Audio>> _parseM3uPlaylist(String path) async {
final audios = <Audio>[];
final playlist = await M3uList.loadFromFile(path);

for (var e in playlist.items) {
Expand Down Expand Up @@ -125,8 +125,8 @@ class ExternalPathService {
return audios;
}

Future<Set<Audio>> _parsePlsPlaylist(String path) async {
final audios = <Audio>{};
Future<List<Audio>> _parsePlsPlaylist(String path) async {
final audios = <Audio>[];
final playlist = PlsPlaylist.parse(File(path).readAsStringSync());

for (var e in playlist.entries) {
Expand Down
30 changes: 15 additions & 15 deletions lib/library/library_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class LibraryModel extends SafeChangeNotifier {
super.dispose();
}

Set<Audio>? getAudiosById(String pageId) {
List<Audio>? getAudiosById(String pageId) {
if (pageId == kLikedAudiosPageId) {
return likedAudios;
} else {
Expand All @@ -86,14 +86,14 @@ class LibraryModel extends SafeChangeNotifier {
//
// Liked Audios
//
Set<Audio> get likedAudios => _service.likedAudios;
List<Audio> get likedAudios => _service.likedAudios;

void addLikedAudio(Audio audio, [bool notify = true]) =>
_service.addLikedAudio(audio, notify);

void addLikedAudios(Set<Audio> audios) => _service.addLikedAudios(audios);
void addLikedAudios(List<Audio> audios) => _service.addLikedAudios(audios);

void removeLikedAudios(Set<Audio> audios) =>
void removeLikedAudios(List<Audio> audios) =>
_service.removeLikedAudios(audios);

bool liked(Audio? audio) => audio == null ? false : _service.liked(audio);
Expand All @@ -105,9 +105,9 @@ class LibraryModel extends SafeChangeNotifier {
// Starred stations
//

Map<String, Set<Audio>> get starredStations => _service.starredStations;
Map<String, List<Audio>> get starredStations => _service.starredStations;
int get starredStationsLength => _service.starredStations.length;
void addStarredStation(String url, Set<Audio> audios) =>
void addStarredStation(String url, List<Audio> audios) =>
_service.addStarredStation(url, audios);

void unStarStation(String url, [bool popIt = true]) {
Expand Down Expand Up @@ -145,18 +145,18 @@ class LibraryModel extends SafeChangeNotifier {
// Playlists
//

Map<String, Set<Audio>> get playlists => _service.playlists;
Map<String, List<Audio>> get playlists => _service.playlists;
int get playlistsLength => playlists.length;
List<Audio> getPlaylistAt(int index) =>
playlists.entries.elementAt(index).value.toList();
Set<Audio>? getPlaylistById(String id) => _service.playlists[id];
List<Audio>? getPlaylistById(String id) => _service.playlists[id];

bool isPlaylistSaved(String? name) => playlists.containsKey(name);

Future<void> addPlaylist(String name, Set<Audio> audios) async =>
Future<void> addPlaylist(String name, List<Audio> audios) async =>
_service.addPlaylist(name, audios);

Future<void> updatePlaylist(String id, Set<Audio> audios) async =>
Future<void> updatePlaylist(String id, List<Audio> audios) async =>
_service.updatePlaylist(id, audios);

void removePlaylist(String id) {
Expand Down Expand Up @@ -191,11 +191,11 @@ class LibraryModel extends SafeChangeNotifier {

// Podcasts

Map<String, Set<Audio>> get podcasts => _service.podcasts;
Map<String, List<Audio>> get podcasts => _service.podcasts;
int get podcastsLength => podcasts.length;
void addPodcast(String feedUrl, Set<Audio> audios) =>
void addPodcast(String feedUrl, List<Audio> audios) =>
_service.addPodcast(feedUrl, audios);
void updatePodcast(String feedUrl, Set<Audio> audios) =>
void updatePodcast(String feedUrl, List<Audio> audios) =>
_service.updatePodcast(feedUrl, audios);

void removePodcast(String feedUrl) {
Expand Down Expand Up @@ -228,13 +228,13 @@ class LibraryModel extends SafeChangeNotifier {
// Albums
//

Map<String, Set<Audio>> get pinnedAlbums => _service.pinnedAlbums;
Map<String, List<Audio>> get pinnedAlbums => _service.pinnedAlbums;
int get pinnedAlbumsLength => pinnedAlbums.length;
List<Audio> getAlbumAt(int index) =>
pinnedAlbums.entries.elementAt(index).value.toList();
bool isPinnedAlbum(String name) => pinnedAlbums.containsKey(name);

void addPinnedAlbum(String name, Set<Audio> audios) =>
void addPinnedAlbum(String name, List<Audio> audios) =>
_service.addPinnedAlbum(name, audios);

void removePinnedAlbum(String name) {
Expand Down
55 changes: 25 additions & 30 deletions lib/library/library_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ class LibraryService {
//
// Liked Audios
//
Set<Audio> _likedAudios = {};
Set<Audio> get likedAudios => _likedAudios;
List<Audio> _likedAudios = [];
List<Audio> get likedAudios => _likedAudios;
final _likedAudiosController = StreamController<bool>.broadcast();
Stream<bool> get likedAudiosChanged => _likedAudiosController.stream;

void addLikedAudio(Audio audio, [bool notify = true]) {
if (_likedAudios.contains(audio)) return;
_likedAudios.add(audio);
if (notify) {
writeAudioMap({kLikedAudiosPageId: _likedAudios}, kLikedAudiosFileName)
.then((value) => _likedAudiosController.add(true));
}
}

void addLikedAudios(Set<Audio> audios) {
void addLikedAudios(List<Audio> audios) {
for (var audio in audios) {
addLikedAudio(audio, false);
}
Expand All @@ -45,7 +46,7 @@ class LibraryService {
}
}

void removeLikedAudios(Set<Audio> audios) {
void removeLikedAudios(List<Audio> audios) {
for (var audio in audios) {
removeLikedAudio(audio, false);
}
Expand All @@ -57,13 +58,13 @@ class LibraryService {
// Starred stations
//

Map<String, Set<Audio>> _starredStations = {};
Map<String, Set<Audio>> get starredStations => _starredStations;
Map<String, List<Audio>> _starredStations = {};
Map<String, List<Audio>> get starredStations => _starredStations;
int get starredStationsLength => _starredStations.length;
final _starredStationsController = StreamController<bool>.broadcast();
Stream<bool> get starredStationsChanged => _starredStationsController.stream;

void addStarredStation(String url, Set<Audio> audios) {
void addStarredStation(String url, List<Audio> audios) {
_starredStations.putIfAbsent(url, () => audios);
writeAudioMap(_starredStations, kStarredStationsFileName)
.then((_) => _starredStationsController.add(true));
Expand Down Expand Up @@ -174,20 +175,20 @@ class LibraryService {
// Playlists
//

Map<String, Set<Audio>> _playlists = {};
Map<String, Set<Audio>> get playlists => _playlists;
Map<String, List<Audio>> _playlists = {};
Map<String, List<Audio>> get playlists => _playlists;
final _playlistsController = StreamController<bool>.broadcast();
Stream<bool> get playlistsChanged => _playlistsController.stream;

Future<void> addPlaylist(String id, Set<Audio> audios) async {
Future<void> addPlaylist(String id, List<Audio> audios) async {
if (!_playlists.containsKey(id)) {
_playlists.putIfAbsent(id, () => audios);
await writeAudioMap(_playlists, kPlaylistsFileName)
.then((_) => _playlistsController.add(true));
}
}

Future<void> updatePlaylist(String id, Set<Audio> audios) async {
Future<void> updatePlaylist(String id, List<Audio> audios) async {
if (_playlists.containsKey(id)) {
await writeAudioMap(_playlists, kPlaylistsFileName).then((_) {
_playlists.update(
Expand Down Expand Up @@ -249,24 +250,18 @@ class LibraryService {
});
} else {
writeAudioMap(_playlists, kPlaylistsFileName).then((_) {
_playlists.update(id, (value) => Set.from(audios));
_playlists.update(id, (value) => audios);
_playlistsController.add(true);
});
}
}

void addAudioToPlaylist(String id, Audio audio) {
final playlist = _playlists[id];
if (playlist != null) {
for (var e in playlist) {
if (e.path == audio.path) {
return;
}
}
playlist.add(audio);
writeAudioMap(_playlists, kPlaylistsFileName)
.then((_) => _playlistsController.add(true));
}
if (playlist == null || playlist.contains(audio)) return;
playlist.add(audio);
writeAudioMap(_playlists, kPlaylistsFileName)
.then((_) => _playlistsController.add(true));
}

void removeAudioFromPlaylist(String id, Audio audio) {
Expand Down Expand Up @@ -354,20 +349,20 @@ class LibraryService {

String? _downloadsDir;
String? get downloadsDir => _downloadsDir;
Map<String, Set<Audio>> _podcasts = {};
Map<String, Set<Audio>> get podcasts => _podcasts;
Map<String, List<Audio>> _podcasts = {};
Map<String, List<Audio>> get podcasts => _podcasts;
int get podcastsLength => _podcasts.length;
final _podcastsController = StreamController<bool>.broadcast();
Stream<bool> get podcastsChanged => _podcastsController.stream;

void addPodcast(String feedUrl, Set<Audio> audios) {
void addPodcast(String feedUrl, List<Audio> audios) {
if (_podcasts.containsKey(feedUrl)) return;
_podcasts.putIfAbsent(feedUrl, () => audios);
writeAudioMap(_podcasts, kPodcastsFileName)
.then((_) => _podcastsController.add(true));
}

void updatePodcast(String feedUrl, Set<Audio> audios) {
void updatePodcast(String feedUrl, List<Audio> audios) {
if (feedUrl.isEmpty || audios.isEmpty) return;
_addPodcastUpdate(feedUrl);
_podcasts.update(feedUrl, (value) => audios);
Expand Down Expand Up @@ -411,8 +406,8 @@ class LibraryService {
// Albums
//

Map<String, Set<Audio>> _pinnedAlbums = {};
Map<String, Set<Audio>> get pinnedAlbums => _pinnedAlbums;
Map<String, List<Audio>> _pinnedAlbums = {};
Map<String, List<Audio>> get pinnedAlbums => _pinnedAlbums;
int get pinnedAlbumsLength => _pinnedAlbums.length;
final _albumsController = StreamController<bool>.broadcast();
Stream<bool> get albumsChanged => _albumsController.stream;
Expand All @@ -422,7 +417,7 @@ class LibraryService {

bool isPinnedAlbum(String name) => _pinnedAlbums.containsKey(name);

void addPinnedAlbum(String name, Set<Audio> audios) {
void addPinnedAlbum(String name, List<Audio> audios) {
_pinnedAlbums.putIfAbsent(name, () => audios);
writeAudioMap(_pinnedAlbums, kPinnedAlbumsFileName)
.then((_) => _albumsController.add(true));
Expand Down Expand Up @@ -452,7 +447,7 @@ class LibraryService {

_likedAudios =
(await readAudioMap(kLikedAudiosFileName)).entries.firstOrNull?.value ??
<Audio>{};
<Audio>[];
_favTags = Set.from(
await readStringIterable(filename: kRadioTagFavsFileName) ?? <String>{},
);
Expand Down
2 changes: 1 addition & 1 deletion lib/local_audio/cover_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CoverStore {
Future<void> write() async => writeUint8ListMap(_value, kCoverStore);

Future<void> read() async =>
_value = await computeIsolate(() => readUint8ListMap(kCoverStore)) ?? {};
_value = await computeIsolate(() => readUint8ListMap(kCoverStore)) ?? [];
}

const kCoverStore = 'coverStore.json';
Loading