Skip to content

Commit

Permalink
fix: add favs to playlistsview + friends (#981)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier authored Oct 26, 2024
1 parent 5293dca commit 89ed1ff
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 96 deletions.
5 changes: 4 additions & 1 deletion lib/common/view/copy_clipboard_content.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -58,7 +59,9 @@ class _CopyClipboardContentState extends State<CopyClipboardContent> {
),
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,
),
Expand Down
26 changes: 20 additions & 6 deletions lib/local_audio/view/playlists_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PlaylistsView extends StatelessWidget {
Widget build(BuildContext context) {
final lists = [
kNewPlaylistPageId,
kLikedAudiosPageId,
...(playlists ?? []),
];

Expand All @@ -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<LibraryModel>().push(
builder: (_) => PlaylistPage(
Expand All @@ -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,
),
],
),
);
Expand Down
73 changes: 47 additions & 26 deletions lib/playlists/view/manual_add_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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<LibraryModel>(),
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<LibraryModel>(),
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),
);
},
),
),
);
}
Expand Down Expand Up @@ -204,10 +221,14 @@ class _PlaylistContentState extends State<PlaylistContent> {
if (widget.allowRename && widget.playlistName != null)
ImportantButton(
onPressed: () {
widget.libraryModel.updatePlaylistName(
widget.playlistName!,
_controller.text,
);
di<LocalAudioModel>().localAudioindex =
LocalAudioView.playlists.index;
widget.libraryModel
..pushNamed(pageId: kLocalAudioPageId)
..updatePlaylistName(
widget.playlistName!,
_controller.text,
);
Navigator.of(context).pop();
},
child: Text(
Expand Down
17 changes: 11 additions & 6 deletions lib/radio/view/radio_history_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,17 @@ class RadioHistoryList extends StatelessWidget with WatchItMixin {
final e = di<PlayerModel>()
.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,
);
},
);
},
Expand Down
154 changes: 100 additions & 54 deletions lib/radio/view/radio_history_tile.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<String, MpvMetaData> 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<RadioModel>().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<LibraryModel>();
if (libraryModel.selectedPageId == entry.value.icyUrl) return;

await di<RadioModel>().init();
di<SearchModel>().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<String, MpvMetaData> 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<RadioModel>().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,
Expand All @@ -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<LibraryModel>();
if (libraryModel.selectedPageId == entry.value.icyUrl) return;

await di<RadioModel>().init();
di<SearchModel>().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,
),
);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/search/search_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}

Expand Down

0 comments on commit 89ed1ff

Please sign in to comment.