feat: download button on each track

This commit is contained in:
Kingkor Roy Tirtho 2023-06-25 17:03:36 +06:00
parent 28abed9ab3
commit 925fa86271
5 changed files with 37 additions and 17 deletions

View File

@ -6,7 +6,7 @@ import 'package:spotube/hooks/use_brightness_value.dart';
import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/platform.dart';
class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget { class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget {
final List<String> tabs; final List<Widget> tabs;
const ThemedButtonsTabBar({Key? key, required this.tabs}) : super(key: key); const ThemedButtonsTabBar({Key? key, required this.tabs}) : super(key: key);
@override @override
@ -48,9 +48,7 @@ class ThemedButtonsTabBar extends HookWidget implements PreferredSizeWidget {
unselectedLabelStyle: theme.textTheme.labelLarge?.copyWith( unselectedLabelStyle: theme.textTheme.labelLarge?.copyWith(
color: theme.colorScheme.primary, color: theme.colorScheme.primary,
), ),
tabs: tabs.map((tab) { tabs: tabs,
return Tab(text: " $tab ");
}).toList(),
), ),
); );
} }

View File

@ -16,6 +16,7 @@ import 'package:spotube/extensions/context.dart';
import 'package:spotube/models/local_track.dart'; import 'package:spotube/models/local_track.dart';
import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/authentication_provider.dart';
import 'package:spotube/provider/blacklist_provider.dart'; import 'package:spotube/provider/blacklist_provider.dart';
import 'package:spotube/provider/download_manager_provider.dart';
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
import 'package:spotube/services/mutations/mutations.dart'; import 'package:spotube/services/mutations/mutations.dart';
import 'package:spotube/utils/type_conversion_utils.dart'; import 'package:spotube/utils/type_conversion_utils.dart';
@ -31,6 +32,7 @@ enum TrackOptionValue {
playNext, playNext,
favorite, favorite,
details, details,
download,
} }
class TrackOptions extends HookConsumerWidget { class TrackOptions extends HookConsumerWidget {
@ -75,7 +77,8 @@ class TrackOptions extends HookConsumerWidget {
final playback = ref.watch(ProxyPlaylistNotifier.notifier); final playback = ref.watch(ProxyPlaylistNotifier.notifier);
final scaffoldMessenger = ScaffoldMessenger.of(context); final scaffoldMessenger = ScaffoldMessenger.of(context);
final auth = ref.watch(AuthenticationNotifier.provider); final auth = ref.watch(AuthenticationNotifier.provider);
ref.watch(downloadManagerProvider);
final downloadManager = ref.watch(downloadManagerProvider.notifier);
final blacklist = ref.watch(BlackListNotifier.provider); final blacklist = ref.watch(BlackListNotifier.provider);
final favorites = useTrackToggleLike(track, ref); final favorites = useTrackToggleLike(track, ref);
@ -171,6 +174,9 @@ class TrackOptions extends HookConsumerWidget {
builder: (context) => TrackDetailsDialog(track: track), builder: (context) => TrackDetailsDialog(track: track),
); );
break; break;
case TrackOptionValue.download:
await downloadManager.enqueue(track);
break;
} }
}, },
icon: const Icon(SpotubeIcons.moreHorizontal), icon: const Icon(SpotubeIcons.moreHorizontal),
@ -256,12 +262,18 @@ class TrackOptions extends HookConsumerWidget {
value: TrackOptionValue.removeFromPlaylist, value: TrackOptionValue.removeFromPlaylist,
leading: (removeTrack.isMutating || !removeTrack.hasData) && leading: (removeTrack.isMutating || !removeTrack.hasData) &&
removingTrack.value == track.uri removingTrack.value == track.uri
? const Center( ? const CircularProgressIndicator()
child: CircularProgressIndicator(),
)
: const Icon(SpotubeIcons.removeFilled), : const Icon(SpotubeIcons.removeFilled),
title: Text(context.l10n.remove_from_playlist), title: Text(context.l10n.remove_from_playlist),
), ),
PopSheetEntry(
value: TrackOptionValue.download,
enabled: downloadManager.activeItem?.id != track.id!,
leading: downloadManager.activeItem?.id == track.id!
? const CircularProgressIndicator()
: const Icon(SpotubeIcons.download),
title: Text(context.l10n.download_track),
),
PopSheetEntry( PopSheetEntry(
value: TrackOptionValue.blacklist, value: TrackOptionValue.blacklist,
leading: const Icon(SpotubeIcons.playlistRemove), leading: const Icon(SpotubeIcons.playlistRemove),

View File

@ -19,8 +19,8 @@ class HomePage extends HookConsumerWidget {
leadingWidth: double.infinity, leadingWidth: double.infinity,
leading: ThemedButtonsTabBar( leading: ThemedButtonsTabBar(
tabs: [ tabs: [
context.l10n.personalized, Tab(text: " ${context.l10n.personalized} "),
context.l10n.genre, Tab(text: " ${context.l10n.genre} "),
], ],
), ),
), ),

View File

@ -9,11 +9,15 @@ import 'package:spotube/components/library/user_downloads.dart';
import 'package:spotube/components/library/user_playlists.dart'; import 'package:spotube/components/library/user_playlists.dart';
import 'package:spotube/components/shared/themed_button_tab_bar.dart'; import 'package:spotube/components/shared/themed_button_tab_bar.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/provider/download_manager_provider.dart';
class LibraryPage extends HookConsumerWidget { class LibraryPage extends HookConsumerWidget {
const LibraryPage({Key? key}) : super(key: key); const LibraryPage({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final downloadingCount =
ref.watch(downloadManagerProvider.select((s) => s.length));
return DefaultTabController( return DefaultTabController(
length: 5, length: 5,
child: SafeArea( child: SafeArea(
@ -23,11 +27,17 @@ class LibraryPage extends HookConsumerWidget {
centerTitle: true, centerTitle: true,
leading: ThemedButtonsTabBar( leading: ThemedButtonsTabBar(
tabs: [ tabs: [
context.l10n.playlists, Tab(text: " ${context.l10n.playlists} "),
context.l10n.tracks, Tab(text: " ${context.l10n.tracks} "),
context.l10n.downloads, Tab(
context.l10n.artists, child: Badge(
context.l10n.albums, isLabelVisible: downloadingCount > 0,
label: Text(downloadingCount.toString()),
child: Text(" ${context.l10n.downloads} "),
),
),
Tab(text: " ${context.l10n.artists} "),
Tab(text: " ${context.l10n.albums} "),
], ],
), ),
leadingWidth: double.infinity, leadingWidth: double.infinity,

View File

@ -46,8 +46,8 @@ class LyricsPage extends HookConsumerWidget {
final tabbar = ThemedButtonsTabBar( final tabbar = ThemedButtonsTabBar(
tabs: [ tabs: [
context.l10n.synced, Tab(text: " ${context.l10n.synced} "),
context.l10n.plain, Tab(text: " ${context.l10n.plain} "),
], ],
); );