From 89ed1ff5b55a69b67ec63407d09153a854a6f6e6 Mon Sep 17 00:00:00 2001 From: Frederik Feichtmeier Date: Sat, 26 Oct 2024 17:55:30 +0200 Subject: [PATCH] fix: add favs to playlistsview + friends (#981) --- lib/common/view/copy_clipboard_content.dart | 5 +- lib/local_audio/view/playlists_view.dart | 26 +++- lib/playlists/view/manual_add_dialog.dart | 73 ++++++---- lib/radio/view/radio_history_list.dart | 17 ++- lib/radio/view/radio_history_tile.dart | 154 +++++++++++++------- lib/search/search_model.dart | 6 +- 6 files changed, 185 insertions(+), 96 deletions(-) diff --git a/lib/common/view/copy_clipboard_content.dart b/lib/common/view/copy_clipboard_content.dart index c673a930c..668d40414 100644 --- a/lib/common/view/copy_clipboard_content.dart +++ b/lib/common/view/copy_clipboard_content.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:yaru/yaru.dart'; import '../../extensions/build_context_x.dart'; import '../../l10n/l10n.dart'; @@ -58,7 +59,9 @@ class _CopyClipboardContentState extends State { ), if (widget.showActions) StreamProviderRow( - iconColor: theme.snackBarTheme.actionTextColor, + iconColor: theme.snackBarTheme.backgroundColor != null + ? contrastColor(theme.snackBarTheme.backgroundColor!) + : theme.colorScheme.primary, onSearch: widget.onSearch, text: widget.text, ), diff --git a/lib/local_audio/view/playlists_view.dart b/lib/local_audio/view/playlists_view.dart index 860419ab0..a98562485 100644 --- a/lib/local_audio/view/playlists_view.dart +++ b/lib/local_audio/view/playlists_view.dart @@ -25,6 +25,7 @@ class PlaylistsView extends StatelessWidget { Widget build(BuildContext context) { final lists = [ kNewPlaylistPageId, + kLikedAudiosPageId, ...(playlists ?? []), ]; @@ -38,7 +39,8 @@ class PlaylistsView extends StatelessWidget { onTap: () => id == kNewPlaylistPageId ? showDialog( context: context, - builder: (context) => const ManualAddDialog(), + builder: (context) => + const ManualAddDialog(onlyPlaylists: true), ) : di().push( builder: (_) => PlaylistPage( @@ -63,12 +65,24 @@ class PlaylistsView extends StatelessWidget { ), child: Icon(Iconz.plus), ) - : RoundImageContainer( - images: const {}, - fallBackText: id, - ), + : id == kLikedAudiosPageId + ? Container( + decoration: BoxDecoration( + color: + context.colorScheme.primary.withOpacity(0.3), + shape: BoxShape.circle, + ), + child: Icon(Iconz.heart), + ) + : RoundImageContainer( + images: const {}, + fallBackText: id, + ), ), - if (id != kNewPlaylistPageId) ArtistVignette(text: id), + if (id != kNewPlaylistPageId && id != kLikedAudiosPageId) + ArtistVignette( + text: id, + ), ], ), ); diff --git a/lib/playlists/view/manual_add_dialog.dart b/lib/playlists/view/manual_add_dialog.dart index 46fc058ed..8c9aec733 100644 --- a/lib/playlists/view/manual_add_dialog.dart +++ b/lib/playlists/view/manual_add_dialog.dart @@ -7,13 +7,21 @@ import '../../common/view/common_widgets.dart'; import '../../common/view/global_keys.dart'; import '../../common/view/icons.dart'; import '../../common/view/theme.dart'; +import '../../constants.dart'; import '../../external_path/external_path_service.dart'; import '../../l10n/l10n.dart'; import '../../library/library_model.dart'; +import '../../local_audio/local_audio_model.dart'; +import '../../local_audio/view/local_audio_view.dart'; import '../../podcasts/podcast_model.dart'; class ManualAddDialog extends StatelessWidget { - const ManualAddDialog({super.key}); + const ManualAddDialog({ + super.key, + this.onlyPlaylists = false, + }); + + final bool onlyPlaylists; @override Widget build(BuildContext context) { @@ -30,31 +38,40 @@ class ManualAddDialog extends StatelessWidget { content: SizedBox( height: 200, width: 400, - child: Navigator( - // ignore: deprecated_member_use - onPopPage: (route, result) => route.didPop(result), - key: manualAddNavigatorKey, - initialRoute: '/chose', - onGenerateRoute: (settings) { - Widget page = switch (settings.name) { - '/addPlaylist' => PlaylistContent( + child: onlyPlaylists + ? Padding( + padding: const EdgeInsets.only(top: 20), + child: PlaylistContent( playlistName: context.l10n.createNewPlaylist, libraryModel: di(), allowCreate: true, ), - '/addPodcast' => const AddPodcastContent(), - '/addStation' => const AddStationContent(), - _ => const SelectAddContent() - }; - - return PageRouteBuilder( - barrierDismissible: true, - pageBuilder: (_, __, ___) => page, - reverseTransitionDuration: const Duration(seconds: 0), - transitionDuration: const Duration(milliseconds: 0), - ); - }, - ), + ) + : Navigator( + // ignore: deprecated_member_use + onPopPage: (route, result) => route.didPop(result), + key: manualAddNavigatorKey, + initialRoute: '/chose', + onGenerateRoute: (settings) { + Widget page = switch (settings.name) { + '/addPlaylist' => PlaylistContent( + playlistName: context.l10n.createNewPlaylist, + libraryModel: di(), + allowCreate: true, + ), + '/addPodcast' => const AddPodcastContent(), + '/addStation' => const AddStationContent(), + _ => const SelectAddContent() + }; + + return PageRouteBuilder( + barrierDismissible: true, + pageBuilder: (_, __, ___) => page, + reverseTransitionDuration: const Duration(seconds: 0), + transitionDuration: const Duration(milliseconds: 0), + ); + }, + ), ), ); } @@ -204,10 +221,14 @@ class _PlaylistContentState extends State { if (widget.allowRename && widget.playlistName != null) ImportantButton( onPressed: () { - widget.libraryModel.updatePlaylistName( - widget.playlistName!, - _controller.text, - ); + di().localAudioindex = + LocalAudioView.playlists.index; + widget.libraryModel + ..pushNamed(pageId: kLocalAudioPageId) + ..updatePlaylistName( + widget.playlistName!, + _controller.text, + ); Navigator.of(context).pop(); }, child: Text( diff --git a/lib/radio/view/radio_history_list.dart b/lib/radio/view/radio_history_list.dart index 9f92bab7f..9fcd14cf3 100644 --- a/lib/radio/view/radio_history_list.dart +++ b/lib/radio/view/radio_history_list.dart @@ -51,12 +51,17 @@ class RadioHistoryList extends StatelessWidget with WatchItMixin { final e = di() .filteredRadioHistory(filter: filter) .elementAt(reversedIndex); - return RadioHistoryTile( - simpleTile: simpleList, - entry: e, - selected: current?.icyTitle != null && - current?.icyTitle == e.value.icyTitle, - ); + return simpleList + ? RadioHistoryTile.simple( + entry: e, + selected: current?.icyTitle != null && + current?.icyTitle == e.value.icyTitle, + ) + : RadioHistoryTile( + entry: e, + selected: current?.icyTitle != null && + current?.icyTitle == e.value.icyTitle, + ); }, ); }, diff --git a/lib/radio/view/radio_history_tile.dart b/lib/radio/view/radio_history_tile.dart index 54e322b00..588c8ad84 100644 --- a/lib/radio/view/radio_history_tile.dart +++ b/lib/radio/view/radio_history_tile.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/constants.dart'; +import 'package:yaru/yaru.dart'; import '../../common/data/audio.dart'; import '../../common/data/mpv_meta_data.dart'; @@ -19,58 +20,118 @@ import '../radio_model.dart'; import 'icy_image.dart'; import 'station_page.dart'; +enum _RadioHistoryTileVariant { regular, simple } + class RadioHistoryTile extends StatelessWidget { const RadioHistoryTile({ super.key, required this.entry, required this.selected, - this.simpleTile = false, + }) : _variant = _RadioHistoryTileVariant.regular; + + const RadioHistoryTile.simple({ + super.key, + required this.entry, + required this.selected, + }) : _variant = _RadioHistoryTileVariant.simple; + + final _RadioHistoryTileVariant _variant; + final MapEntry entry; + final bool selected; + + @override + Widget build(BuildContext context) { + return switch (_variant) { + _RadioHistoryTileVariant.simple => _SimpleRadioHistoryTile( + key: ValueKey(entry.value.icyTitle), + entry: entry, + selected: selected, + ), + _RadioHistoryTileVariant.regular => ListTile( + key: ValueKey(entry.value.icyTitle), + selected: selected, + selectedColor: context.theme.contrastyPrimary, + contentPadding: + const EdgeInsets.symmetric(horizontal: kYaruPagePadding), + leading: IcyImage( + key: ValueKey(entry.value.icyTitle), + height: yaruStyled ? 34 : 40, + width: yaruStyled ? 34 : 40, + mpvMetaData: entry.value, + ), + trailing: IconButton( + tooltip: context.l10n.metadata, + onPressed: () => showDialog( + context: context, + builder: (context) { + final image = di().getCover(entry.value.icyTitle); + return MpvMetadataDialog( + mpvMetaData: entry.value, + image: image, + ); + }, + ), + icon: Icon( + Iconz.info, + ), + ), + title: TapAbleText( + overflow: TextOverflow.visible, + maxLines: 10, + text: entry.value.icyTitle, + onTap: () => showSnackBar( + context: context, + content: CopyClipboardContent(text: entry.value.icyTitle), + ), + ), + subtitle: TapAbleText( + text: entry.value.icyName, + onTap: () async { + final libraryModel = di(); + if (libraryModel.selectedPageId == entry.value.icyUrl) return; + + await di().init(); + di().radioNameSearch(entry.value.icyName).then((v) { + if (v?.firstOrNull?.stationUUID != null) { + libraryModel.push( + builder: (_) => + StationPage(station: Audio.fromStation(v.first)), + pageId: v!.first.stationUUID, + ); + } + }); + }, + ), + ) + }; + } +} + +class _SimpleRadioHistoryTile extends StatelessWidget { + const _SimpleRadioHistoryTile({ + super.key, + required this.entry, + required this.selected, }); final MapEntry entry; - final bool selected, simpleTile; + final bool selected; @override Widget build(BuildContext context) { return ListTile( key: ValueKey(entry.value.icyTitle), selected: selected, - selectedColor: simpleTile - ? context.theme.colorScheme.onSurface - : context.theme.contrastyPrimary, + selectedColor: context.theme.colorScheme.onSurface, contentPadding: const EdgeInsets.symmetric(horizontal: kYaruPagePadding), - leading: simpleTile - ? Visibility( - visible: selected, - child: const Text('>'), - ) - : IcyImage( - key: ValueKey(entry.value.icyTitle), - height: yaruStyled ? 34 : 40, - width: yaruStyled ? 34 : 40, - mpvMetaData: entry.value, - ), - trailing: simpleTile - ? Visibility( - visible: selected, - child: const Text('<'), - ) - : IconButton( - tooltip: context.l10n.metadata, - onPressed: () => showDialog( - context: context, - builder: (context) { - final image = di().getCover(entry.value.icyTitle); - return MpvMetadataDialog( - mpvMetaData: entry.value, - image: image, - ); - }, - ), - icon: Icon( - Iconz.info, - ), - ), + leading: Visibility( + visible: selected, + child: const Text('>'), + ), + trailing: Visibility( + visible: selected, + child: const Text('<'), + ), title: TapAbleText( overflow: TextOverflow.visible, maxLines: 10, @@ -80,23 +141,8 @@ class RadioHistoryTile extends StatelessWidget { content: CopyClipboardContent(text: entry.value.icyTitle), ), ), - subtitle: TapAbleText( - text: entry.value.icyName, - onTap: () async { - final libraryModel = di(); - if (libraryModel.selectedPageId == entry.value.icyUrl) return; - - await di().init(); - di().radioNameSearch(entry.value.icyName).then((v) { - if (v?.firstOrNull?.stationUUID != null) { - libraryModel.push( - builder: (_) => - StationPage(station: Audio.fromStation(v.first)), - pageId: v!.first.stationUUID, - ); - } - }); - }, + subtitle: Text( + entry.value.icyName, ), ); } diff --git a/lib/search/search_model.dart b/lib/search/search_model.dart index ead514b56..34120a713 100644 --- a/lib/search/search_model.dart +++ b/lib/search/search_model.dart @@ -150,12 +150,12 @@ class SearchModel extends SafeChangeNotifier { genres: search?.genres, artists: search?.artists, playlists: (query != null && query.isNotEmpty) - ? _libraryService.playlists.keys.toList() - : _libraryService.playlists.keys + ? _libraryService.playlists.keys .where( - (e) => e.toLowerCase().contains(query?.toLowerCase() ?? ''), + (e) => e.toLowerCase().contains(query.toLowerCase()), ) .toList() + : null ); }