diff --git a/lib/app/view/create_master_items.dart b/lib/app/view/create_master_items.dart new file mode 100644 index 000000000..de5db08f1 --- /dev/null +++ b/lib/app/view/create_master_items.dart @@ -0,0 +1,140 @@ +import 'package:flutter/material.dart'; +import 'package:watch_it/watch_it.dart'; + +import '../../app_config.dart'; +import '../../common/data/audio_type.dart'; +import '../../common/page_ids.dart'; +import '../../common/view/icons.dart'; +import '../../common/view/side_bar_fall_back_image.dart'; +import '../../common/view/theme.dart'; +import '../../custom_content/view/custom_content_page.dart'; +import '../../extensions/string_x.dart'; +import '../../home/home_page.dart'; +import '../../l10n/l10n.dart'; +import '../../library/library_model.dart'; +import '../../local_audio/view/album_page.dart'; +import '../../local_audio/view/local_audio_page.dart'; +import '../../playlists/view/liked_audio_page.dart'; +import '../../playlists/view/playlist_page.dart'; +import '../../podcasts/view/lazy_podcast_page.dart'; +import '../../podcasts/view/podcast_page_side_bar_icon.dart'; +import '../../podcasts/view/podcast_page_title.dart'; +import '../../podcasts/view/podcasts_page.dart'; +import '../../radio/view/radio_page.dart'; +import '../../radio/view/station_page.dart'; +import '../../radio/view/station_page_icon.dart'; +import '../../radio/view/station_title.dart'; +import '../../search/view/search_page.dart'; +import '../../settings/view/settings_page.dart'; +import 'main_page_icon.dart'; +import 'master_items.dart'; + +List createMasterItems() { + final libraryModel = di(); + return [ + MasterItem( + titleBuilder: (context) => Text(context.l10n.search), + pageBuilder: (_) => const SearchPage(), + iconBuilder: (_) => Icon(Iconz.search), + pageId: PageIDs.searchPage, + ), + MasterItem( + titleBuilder: (context) => Text(context.l10n.local), + pageBuilder: (_) => const LocalAudioPage(), + iconBuilder: (selected) => MainPageIcon( + audioType: AudioType.local, + selected: selected, + ), + pageId: PageIDs.localAudio, + ), + MasterItem( + titleBuilder: (context) => Text(context.l10n.radio), + pageBuilder: (_) => const RadioPage(), + iconBuilder: (selected) => MainPageIcon( + audioType: AudioType.radio, + selected: selected, + ), + pageId: PageIDs.radio, + ), + MasterItem( + titleBuilder: (context) => Text(context.l10n.podcasts), + pageBuilder: (_) => const PodcastsPage(), + iconBuilder: (selected) => MainPageIcon( + audioType: AudioType.podcast, + selected: selected, + ), + pageId: PageIDs.podcasts, + ), + if (AppConfig.isMobilePlatform) + MasterItem( + titleBuilder: (context) => Text(context.l10n.settings), + iconBuilder: (selected) => + Icon(selected ? Iconz.settingsFilled : Iconz.settings), + pageBuilder: (context) => const SettingsPage(), + pageId: PageIDs.settings, + ), + if (AppConfig.isMobilePlatform) + MasterItem( + titleBuilder: (context) => Text(context.l10n.home), + iconBuilder: (selected) => + Icon(selected ? Iconz.homeFilled : Iconz.home), + pageBuilder: (context) => const HomePage(), + pageId: PageIDs.homePage, + ), + MasterItem( + iconBuilder: (selected) => Icon(Iconz.plus), + titleBuilder: (context) => Text(context.l10n.add), + pageBuilder: (_) => const CustomContentPage(), + pageId: PageIDs.customContent, + ), + MasterItem( + titleBuilder: (context) => Text(context.l10n.likedSongs), + pageId: PageIDs.likedAudios, + pageBuilder: (_) => const LikedAudioPage(), + subtitleBuilder: (context) => Text(context.l10n.playlist), + iconBuilder: (selected) => LikedAudioPageIcon(selected: selected), + ), + for (final id in libraryModel.playlistIDs) + MasterItem( + titleBuilder: (context) => Text(id), + subtitleBuilder: (context) => Text(context.l10n.playlist), + pageId: id, + pageBuilder: (_) => PlaylistPage(pageId: id), + iconBuilder: (selected) => SideBarFallBackImage( + color: getAlphabetColor(id), + child: Icon(Iconz.playlist), + ), + ), + for (final feedUrl in libraryModel.podcastFeedUrls) + MasterItem( + titleBuilder: (_) => PodcastPageTitle( + feedUrl: feedUrl, + ), + subtitleBuilder: (context) => PodcastPageSubTitle(feedUrl: feedUrl), + pageId: feedUrl, + pageBuilder: (_) => LazyPodcastPage(feedUrl: feedUrl), + iconBuilder: (selected) => PodcastPageSideBarIcon(feedUrl: feedUrl), + ), + for (final id in libraryModel.favoriteAlbums) + MasterItem( + titleBuilder: (context) => Text(id.albumOfId), + subtitleBuilder: (context) => Text(id.artistOfId), + pageId: id, + pageBuilder: (_) => AlbumPage(id: id), + iconBuilder: (selected) => AlbumPageSideBarIcon( + albumId: id, + ), + ), + for (final uuid in libraryModel.starredStations.where((e) => e.isNotEmpty)) + MasterItem( + titleBuilder: (context) => StationTitle(uuid: uuid), + subtitleBuilder: (context) => Text(context.l10n.station), + pageId: uuid, + pageBuilder: (_) => StationPage(uuid: uuid), + iconBuilder: (selected) => StationPageIcon( + uuid: uuid, + selected: selected, + ), + ), + ]; +} diff --git a/lib/app/view/desktop_home_page.dart b/lib/app/view/desktop_home_page.dart index e65e6a175..531f1bf33 100644 --- a/lib/app/view/desktop_home_page.dart +++ b/lib/app/view/desktop_home_page.dart @@ -38,8 +38,8 @@ class _DesktopHomePageState extends State { builder: (_) => PatchNotesDialog( onClose: () { if ((di().audios?.isNotEmpty ?? false) && - di().playlists.isNotEmpty && - di().pinnedAlbums.isNotEmpty && + di().playlistIDs.isNotEmpty && + di().favoriteAlbums.isNotEmpty && di().isBackupScreenNeeded && !di().wasBackupSaved && mounted) { diff --git a/lib/app/view/master_detail_page.dart b/lib/app/view/master_detail_page.dart index a676d177a..abf1ee76c 100644 --- a/lib/app/view/master_detail_page.dart +++ b/lib/app/view/master_detail_page.dart @@ -3,34 +3,30 @@ import 'dart:io'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; -import 'package:yaru/yaru.dart'; import '../../app_config.dart'; import '../../common/page_ids.dart'; import '../../common/view/back_gesture.dart'; import '../../common/view/global_keys.dart'; -import '../../common/view/header_bar.dart'; import '../../common/view/icons.dart'; import '../../common/view/ui_constants.dart'; import '../../extensions/build_context_x.dart'; import '../../library/library_model.dart'; -import '../../settings/view/settings_action.dart'; -import 'master_items.dart'; -import 'master_tile.dart'; +import 'create_master_items.dart'; +import 'master_panel.dart'; -class MasterDetailPage extends StatelessWidget with WatchItMixin { +class MasterDetailPage extends StatelessWidget { const MasterDetailPage({super.key}); @override Widget build(BuildContext context) { - final libraryModel = watchIt(); - final masterItems = createMasterItems(libraryModel: libraryModel); + final libraryModel = di(); final drawer = Drawer( width: kMasterDetailSideBarWidth, child: Stack( children: [ - MasterPanel(masterItems: masterItems, libraryModel: libraryModel), + const MasterPanel(), Positioned( left: Platform.isMacOS ? 5 : null, top: 5, @@ -55,11 +51,7 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin { drawer: Platform.isMacOS ? null : drawer, body: Row( children: [ - if (context.showMasterPanel) - MasterPanel( - masterItems: masterItems, - libraryModel: libraryModel, - ), + if (context.showMasterPanel) const MasterPanel(), if (context.showMasterPanel) const VerticalDivider(), Expanded( child: Navigator( @@ -68,6 +60,7 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin { key: libraryModel.masterNavigatorKey, observers: [libraryModel], onGenerateRoute: (settings) { + final masterItems = createMasterItems(); final page = (masterItems.firstWhereOrNull( (e) => e.pageId == settings.name, ) ?? @@ -88,66 +81,3 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin { ); } } - -class MasterPanel extends StatelessWidget { - const MasterPanel({ - super.key, - required this.masterItems, - required this.libraryModel, - }); - - final List masterItems; - final LibraryModel libraryModel; - - @override - Widget build(BuildContext context) { - return SizedBox( - width: kMasterDetailSideBarWidth, - child: Column( - children: [ - const HeaderBar( - includeBackButton: false, - includeSidebarButton: false, - backgroundColor: Colors.transparent, - style: YaruTitleBarStyle.undecorated, - adaptive: false, - title: Text(AppConfig.appTitle), - ), - Expanded( - child: ListView.separated( - itemCount: masterItems.length, - itemBuilder: (context, index) { - final item = masterItems.elementAt(index); - return MasterTile( - key: ValueKey(item.pageId), - onTap: () { - libraryModel.push(pageId: item.pageId); - - if (!context.showMasterPanel) { - if (Platform.isMacOS) { - masterScaffoldKey.currentState?.closeEndDrawer(); - } else { - masterScaffoldKey.currentState?.closeDrawer(); - } - } - }, - pageId: item.pageId, - libraryModel: libraryModel, - leading: item.iconBuilder - ?.call(libraryModel.selectedPageId == item.pageId), - title: item.titleBuilder(context), - subtitle: item.subtitleBuilder?.call(context), - selected: libraryModel.selectedPageId == item.pageId, - ); - }, - separatorBuilder: (_, __) => const SizedBox( - height: 5, - ), - ), - ), - const SettingsButton.tile(), - ], - ), - ); - } -} diff --git a/lib/app/view/master_items.dart b/lib/app/view/master_items.dart index 989db7c3a..7ec67acfa 100644 --- a/lib/app/view/master_items.dart +++ b/lib/app/view/master_items.dart @@ -1,31 +1,5 @@ -import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import '../../app_config.dart'; -import '../../common/data/audio_type.dart'; -import '../../common/page_ids.dart'; -import '../../common/view/icons.dart'; -import '../../common/view/side_bar_fall_back_image.dart'; -import '../../common/view/theme.dart'; -import '../../custom_content/view/custom_content_page.dart'; -import '../../home/home_page.dart'; -import '../../l10n/l10n.dart'; -import '../../library/library_model.dart'; -import '../../local_audio/view/album_page.dart'; -import '../../local_audio/view/local_audio_page.dart'; -import '../../playlists/view/liked_audio_page.dart'; -import '../../playlists/view/playlist_page.dart'; -import '../../podcasts/view/lazy_podcast_page.dart'; -import '../../podcasts/view/podcast_page_side_bar_icon.dart'; -import '../../podcasts/view/podcast_page_title.dart'; -import '../../podcasts/view/podcasts_page.dart'; -import '../../radio/view/radio_page.dart'; -import '../../radio/view/station_page.dart'; -import '../../radio/view/station_page_icon.dart'; -import '../../search/view/search_page.dart'; -import '../../settings/view/settings_page.dart'; -import 'main_page_icon.dart'; - class MasterItem { MasterItem({ required this.titleBuilder, @@ -41,135 +15,3 @@ class MasterItem { final Widget Function(bool selected)? iconBuilder; final String pageId; } - -List createMasterItems({required LibraryModel libraryModel}) { - return [ - MasterItem( - titleBuilder: (context) => Text(context.l10n.search), - pageBuilder: (_) => const SearchPage(), - iconBuilder: (_) => Icon(Iconz.search), - pageId: PageIDs.searchPage, - ), - MasterItem( - titleBuilder: (context) => Text(context.l10n.local), - pageBuilder: (_) => const LocalAudioPage(), - iconBuilder: (selected) => MainPageIcon( - audioType: AudioType.local, - selected: selected, - ), - pageId: PageIDs.localAudio, - ), - MasterItem( - titleBuilder: (context) => Text(context.l10n.radio), - pageBuilder: (_) => const RadioPage(), - iconBuilder: (selected) => MainPageIcon( - audioType: AudioType.radio, - selected: selected, - ), - pageId: PageIDs.radio, - ), - MasterItem( - titleBuilder: (context) => Text(context.l10n.podcasts), - pageBuilder: (_) => const PodcastsPage(), - iconBuilder: (selected) => MainPageIcon( - audioType: AudioType.podcast, - selected: selected, - ), - pageId: PageIDs.podcasts, - ), - if (AppConfig.isMobilePlatform) - MasterItem( - titleBuilder: (context) => Text(context.l10n.settings), - iconBuilder: (selected) => - Icon(selected ? Iconz.settingsFilled : Iconz.settings), - pageBuilder: (context) => const SettingsPage(), - pageId: PageIDs.settings, - ), - if (AppConfig.isMobilePlatform) - MasterItem( - titleBuilder: (context) => Text(context.l10n.home), - iconBuilder: (selected) => - Icon(selected ? Iconz.homeFilled : Iconz.home), - pageBuilder: (context) => const HomePage(), - pageId: PageIDs.homePage, - ), - MasterItem( - iconBuilder: (selected) => Icon(Iconz.plus), - titleBuilder: (context) => Text(context.l10n.add), - pageBuilder: (_) => const CustomContentPage(), - pageId: PageIDs.customContent, - ), - MasterItem( - titleBuilder: (context) => Text(context.l10n.likedSongs), - pageId: PageIDs.likedAudios, - pageBuilder: (_) => const LikedAudioPage(), - subtitleBuilder: (context) => Text(context.l10n.playlist), - iconBuilder: (selected) => LikedAudioPageIcon(selected: selected), - ), - for (final playlist in libraryModel.playlists.entries) - MasterItem( - titleBuilder: (context) => Text(playlist.key), - subtitleBuilder: (context) => Text(context.l10n.playlist), - pageId: playlist.key, - pageBuilder: (_) => PlaylistPage(pageId: playlist.key), - iconBuilder: (selected) => SideBarFallBackImage( - color: getAlphabetColor(playlist.key), - child: Icon( - Iconz.playlist, - ), - ), - ), - for (final podcast in libraryModel.podcasts.entries) - MasterItem( - titleBuilder: (_) => PodcastPageTitle( - feedUrl: podcast.key, - title: podcast.value.firstOrNull?.album ?? - podcast.value.firstOrNull?.title ?? - podcast.value.firstOrNull.toString(), - ), - subtitleBuilder: (context) => Text( - podcast.value.firstOrNull?.artist ?? context.l10n.podcast, - ), - pageId: podcast.key, - pageBuilder: (_) => LazyPodcastPage(feedUrl: podcast.key), - iconBuilder: (selected) => PodcastPageSideBarIcon( - imageUrl: podcast.value.firstOrNull?.albumArtUrl ?? - podcast.value.firstOrNull?.imageUrl, - ), - ), - for (final album in libraryModel.pinnedAlbums.entries) - MasterItem( - titleBuilder: (context) => Text( - album.value.firstOrNull?.album ?? album.key, - ), - subtitleBuilder: (context) => - Text(album.value.firstOrNull?.artist ?? context.l10n.album), - pageId: album.key, - pageBuilder: (_) => AlbumPage( - album: album.value, - id: album.key, - ), - iconBuilder: (selected) => AlbumPageSideBarIcon( - audio: album.value.firstOrNull, - ), - ), - for (final station in libraryModel.starredStations.entries - .where((e) => e.value.isNotEmpty)) - MasterItem( - titleBuilder: (context) => - Text(station.value.first.title ?? station.key), - subtitleBuilder: (context) { - return Text(context.l10n.station); - }, - pageId: station.key, - pageBuilder: (_) => StationPage( - station: station.value.first, - ), - iconBuilder: (selected) => StationPageIcon( - imageUrl: station.value.first.imageUrl, - fallBackColor: getAlphabetColor(station.value.first.title ?? 'a'), - selected: selected, - ), - ), - ]; -} diff --git a/lib/app/view/master_panel.dart b/lib/app/view/master_panel.dart new file mode 100644 index 000000000..4ec14e0b8 --- /dev/null +++ b/lib/app/view/master_panel.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:watch_it/watch_it.dart'; +import 'package:yaru/yaru.dart'; + +import '../../app_config.dart'; +import '../../common/view/header_bar.dart'; +import '../../common/view/ui_constants.dart'; +import '../../library/library_model.dart'; +import '../../settings/view/settings_action.dart'; +import 'create_master_items.dart'; +import 'master_tile.dart'; + +class MasterPanel extends StatelessWidget { + const MasterPanel({super.key}); + + @override + Widget build(BuildContext context) => const SizedBox( + width: kMasterDetailSideBarWidth, + child: Column( + children: [ + HeaderBar( + includeBackButton: false, + includeSidebarButton: false, + backgroundColor: Colors.transparent, + style: YaruTitleBarStyle.undecorated, + adaptive: false, + title: Text(AppConfig.appTitle), + ), + Expanded(child: MasterList()), + SettingsButton.tile(), + ], + ), + ); +} + +class MasterList extends StatelessWidget with WatchItMixin { + const MasterList({super.key}); + + @override + Widget build(BuildContext context) { + watchPropertyValue((LibraryModel m) => m.playlistsLength); + watchPropertyValue((LibraryModel m) => m.starredStationsLength); + watchPropertyValue((LibraryModel m) => m.favoriteAlbumsLength); + watchPropertyValue((LibraryModel m) => m.podcastsLength); + final selectedPageId = + watchPropertyValue((LibraryModel m) => m.selectedPageId); + final masterItems = createMasterItems(); + final libraryModel = di(); + return ListView.separated( + itemCount: masterItems.length, + itemBuilder: (context, index) { + final item = masterItems.elementAt(index); + return MasterTile( + key: ValueKey(item.pageId), + onTap: () => libraryModel.push(pageId: item.pageId), + pageId: item.pageId, + leading: item.iconBuilder?.call(selectedPageId == item.pageId), + title: item.titleBuilder(context), + subtitle: item.subtitleBuilder?.call(context), + selected: selectedPageId == item.pageId, + ); + }, + separatorBuilder: (_, __) => const SizedBox( + height: 5, + ), + ); + } +} diff --git a/lib/app/view/master_tile.dart b/lib/app/view/master_tile.dart index 770569a55..c7beda9f6 100644 --- a/lib/app/view/master_tile.dart +++ b/lib/app/view/master_tile.dart @@ -2,13 +2,16 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; +import '../../common/data/audio.dart'; import '../../common/data/audio_type.dart'; import '../../common/page_ids.dart'; +import '../../common/view/global_keys.dart'; import '../../common/view/icons.dart'; import '../../common/view/spaced_divider.dart'; import '../../common/view/ui_constants.dart'; import '../../extensions/build_context_x.dart'; import '../../library/library_model.dart'; +import '../../local_audio/local_audio_model.dart'; import '../../player/player_model.dart'; import '../../radio/radio_model.dart'; @@ -20,7 +23,6 @@ class MasterTile extends StatelessWidget { required this.title, this.subtitle, this.trailing, - required this.libraryModel, required this.pageId, required this.onTap, }); @@ -30,7 +32,6 @@ class MasterTile extends StatelessWidget { final Widget? title; final Widget? subtitle; final Widget? trailing; - final LibraryModel libraryModel; final String pageId; final void Function() onTap; @@ -38,7 +39,12 @@ class MasterTile extends StatelessWidget { Widget build(BuildContext context) { final yaruMasterTile = YaruMasterTile( title: title, - onTap: onTap, + onTap: () { + masterScaffoldKey.currentState + ?..closeEndDrawer() + ..closeDrawer(); + onTap(); + }, selected: selected, leading: leading, subtitle: subtitle, @@ -56,7 +62,6 @@ class MasterTile extends StatelessWidget { selected: selected, pageId: pageId, tile: tile, - libraryModel: libraryModel, ); } } @@ -99,13 +104,11 @@ class _PlayAbleMasterTile extends StatefulWidget required this.pageId, required this.tile, this.selected, - required this.libraryModel, }); final String pageId; final Widget tile; final bool? selected; - final LibraryModel libraryModel; @override State<_PlayAbleMasterTile> createState() => __PlayAbleMasterTileState(); @@ -116,9 +119,7 @@ class __PlayAbleMasterTileState extends State<_PlayAbleMasterTile> { @override Widget build(BuildContext context) { - final audios = widget.libraryModel.getAudiosById(widget.pageId); - - if (audios == null || audios.isEmpty) { + if (PageIDs.permanent.contains(widget.pageId)) { return widget.tile; } @@ -128,26 +129,6 @@ class __PlayAbleMasterTileState extends State<_PlayAbleMasterTile> { final isPlaying = watchPropertyValue((PlayerModel m) => m.isPlaying); final playerModel = di(); - void onPlay() { - if (audios.first.audioType == AudioType.radio) { - di().clickStation(audios.first); - } - if (isEnQueued) { - isPlaying ? playerModel.pause() : playerModel.resume(); - } else { - playerModel - .startPlaylist( - audios: audios, - listName: widget.pageId, - ) - .then( - (_) => widget.libraryModel.removePodcastUpdate( - widget.pageId, - ), - ); - } - } - return MouseRegion( onEnter: (e) => setState(() => _hovered = true), onExit: (e) => setState(() => _hovered = false), @@ -161,7 +142,26 @@ class __PlayAbleMasterTileState extends State<_PlayAbleMasterTile> { child: CircleAvatar( radius: kTinyButtonSize / 2, child: IconButton( - onPressed: onPlay, + onPressed: () async { + final audios = await getAudiosById(widget.pageId); + if (audios?.firstOrNull?.audioType == AudioType.radio) { + di().clickStation(audios?.firstOrNull); + } + if (isEnQueued) { + isPlaying ? playerModel.pause() : playerModel.resume(); + } else if (audios != null) { + playerModel + .startPlaylist( + audios: audios, + listName: widget.pageId, + ) + .then( + (_) => di().removePodcastUpdate( + widget.pageId, + ), + ); + } + }, icon: Icon( isPlaying && isEnQueued ? Iconz.pause : Iconz.playFilled, size: kTinyButtonIconSize, @@ -174,4 +174,17 @@ class __PlayAbleMasterTileState extends State<_PlayAbleMasterTile> { ), ); } + + Future?> getAudiosById(String pageId) async { + final libraryModel = di(); + + if (libraryModel.isStarredStation(pageId)) { + var audio = await di().getStationByUUID(pageId); + return audio == null ? [] : [audio]; + } + + return libraryModel.getPodcast(pageId) ?? + libraryModel.getPlaylistById(pageId) ?? + di().findAlbum(pageId); + } } diff --git a/lib/app/view/mobile_musicpod_app.dart b/lib/app/view/mobile_musicpod_app.dart index 8aa0b0c29..77dab6834 100644 --- a/lib/app/view/mobile_musicpod_app.dart +++ b/lib/app/view/mobile_musicpod_app.dart @@ -11,7 +11,7 @@ import '../../common/view/theme.dart'; import '../../l10n/l10n.dart'; import '../../library/library_model.dart'; import '../../settings/settings_model.dart'; -import 'master_items.dart'; +import 'create_master_items.dart'; import 'mobile_page.dart'; class MobileMusicPodApp extends StatelessWidget with WatchItMixin { @@ -25,7 +25,11 @@ class MobileMusicPodApp extends StatelessWidget with WatchItMixin { final phoenix = phoenixTheme(color: accent ?? Colors.greenAccent); final libraryModel = watchIt(); - final masterItems = createMasterItems(libraryModel: libraryModel); + final masterItems = createMasterItems(); + watchPropertyValue((LibraryModel m) => m.playlistsLength); + watchPropertyValue((LibraryModel m) => m.starredStationsLength); + watchPropertyValue((LibraryModel m) => m.favoriteAlbumsLength); + watchPropertyValue((LibraryModel m) => m.podcastsLength); return MaterialApp( navigatorKey: libraryModel.masterNavigatorKey, diff --git a/lib/common/data/audio.dart b/lib/common/data/audio.dart index 68f2b4bbf..38db5746c 100644 --- a/lib/common/data/audio.dart +++ b/lib/common/data/audio.dart @@ -406,16 +406,27 @@ class Audio { String? get albumId { final albumName = album; final artistName = artist; - final id = albumName == null && artistName == null + return albumName == null && artistName == null ? null - : AppConfig.isMobilePlatform - ? '${artistName ?? ''}_${albumName ?? ''}' - : '${artistName ?? ''}:${albumName ?? ''}'; - return AppConfig.isMobilePlatform ? id?.replaceAll(' ', '_') : id; + : '${artistName ?? ''}$albumIdSplitter${albumName ?? ''}'.replaceAll( + albumIdReplacement, + albumIdReplacer, + ); } - bool get hasPathAndId => - albumId?.isNotEmpty == true && + // Note this assumes that no artist or no album includes ___ on their own =) + static const String albumIdSplitter = + '$albumIdReplacer${AppConfig.appId}$albumIdReplacer'; + static const String albumIdReplacer = '___'; + static const String albumIdReplacement = ' '; + + bool get canHaveLocalCover => + albumId != null && + albumId!.isNotEmpty && path != null && audioType == AudioType.local; + + bool get isLocal => audioType == AudioType.local; + bool get isPodcast => audioType == AudioType.podcast; + bool get isRadio => audioType == AudioType.radio; } diff --git a/lib/common/file_names.dart b/lib/common/file_names.dart index 2d954eafb..f1f1306b0 100644 --- a/lib/common/file_names.dart +++ b/lib/common/file_names.dart @@ -1,29 +1,21 @@ class FileNames { static const likedAudios = 'likedAudios.json'; static const playlists = 'playlists.json'; - static const pinnedAlbums = 'finallyFixedPinnedAlbums.json'; static const podcasts = 'podcasts.json'; static const podcastUpdates = 'podcastsupdates.json'; - static const starredStations = 'uuidStarredStations.json'; static const lastPositions = 'lastPositions.json'; static const playerState = 'playerstate.json'; - static const appState = 'appstate.json'; static const downloads = 'downloads.json'; static const feedsWithDownloads = 'feedswithdownloads.json'; - static const coverStore = 'coverStore.json'; static const all = { likedAudios, playlists, - pinnedAlbums, podcasts, podcastUpdates, - starredStations, lastPositions, playerState, - appState, downloads, feedsWithDownloads, - coverStore, }; } diff --git a/lib/common/page_ids.dart b/lib/common/page_ids.dart index b3ec3c665..33fa129bd 100644 --- a/lib/common/page_ids.dart +++ b/lib/common/page_ids.dart @@ -1,7 +1,6 @@ class PageIDs { static const settings = 'settings'; static const homePage = 'homePage'; - static const selectedPage = 'selectedPageId'; static const localAudio = 'localAudio'; static const podcasts = 'podcasts'; static const radio = 'radio'; diff --git a/lib/common/view/audio_filter.dart b/lib/common/view/audio_filter.dart index 60fcc3d4d..7c81bb186 100644 --- a/lib/common/view/audio_filter.dart +++ b/lib/common/view/audio_filter.dart @@ -1,7 +1,6 @@ import 'package:collection/collection.dart'; import '../data/audio.dart'; -import 'package:intl/intl.dart'; enum AudioFilter { trackNumber, @@ -13,20 +12,6 @@ enum AudioFilter { diskNumber; } -int _compareStrings(String a, String b) { - final r = RegExp('\\d+'); - final f = NumberFormat('0' * 16); - final aNew = a.replaceAllMapped( - r, - (match) => f.format(int.tryParse(match[0] ?? '0') ?? 0), - ); - final bNew = b.replaceAllMapped( - r, - (match) => f.format(int.tryParse(match[0] ?? '0') ?? 0), - ); - return aNew.compareTo(bNew); -} - Iterable