From c0347b0360562d170e6edce351d9a26311330fb8 Mon Sep 17 00:00:00 2001 From: devaryakjha Date: Mon, 23 Oct 2023 20:51:44 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Updated=20UI=20for=20media=20detail?= =?UTF-8?q?s=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/icon/shuffle.svg | 5 +++ .../ui/library_widgets/library_app_bar.dart | 17 ++++++++-- .../library/ui/library_widgets/page.dart | 30 +++++++++++----- .../cubit/user_library_cubit.dart | 7 ++++ .../cubit/user_library_state.dart | 6 ++++ lib/gen/assets.gen.dart | 6 +++- lib/widgets/add_to_library.dart | 34 +++++++++++++++++++ lib/widgets/download_button.dart | 4 +-- .../full_screen_player.dart | 2 +- .../shuffle_mode_toggle.dart | 22 +++++++----- 10 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 assets/icon/shuffle.svg create mode 100644 lib/widgets/add_to_library.dart diff --git a/assets/icon/shuffle.svg b/assets/icon/shuffle.svg new file mode 100644 index 0000000..f71a3ce --- /dev/null +++ b/assets/icon/shuffle.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/lib/features/library/ui/library_widgets/library_app_bar.dart b/lib/features/library/ui/library_widgets/library_app_bar.dart index 378e072..bb39891 100644 --- a/lib/features/library/ui/library_widgets/library_app_bar.dart +++ b/lib/features/library/ui/library_widgets/library_app_bar.dart @@ -42,9 +42,20 @@ class LibraryAppBar extends StatelessWidget { ), child: FlexibleSpaceBar( centerTitle: true, - title: state.showTitleInAppBar - ? Text(state.title, style: context.textTheme.headlineSmall) - : null, + title: AnimatedCrossFade( + crossFadeState: state.showTitleInAppBar + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + firstChild: const SizedBox.shrink(), + secondChild: Text( + state.title, + style: context.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0.5, + ), + ), + duration: const Duration(milliseconds: 100), + ), collapseMode: CollapseMode.pin, background: AnimatedContainer( duration: kThemeAnimationDuration, diff --git a/lib/features/library/ui/library_widgets/page.dart b/lib/features/library/ui/library_widgets/page.dart index 4aec7dd..6e1b96c 100644 --- a/lib/features/library/ui/library_widgets/page.dart +++ b/lib/features/library/ui/library_widgets/page.dart @@ -7,11 +7,13 @@ import 'package:varanasi_mobile_app/cubits/player/player_cubit.dart'; import 'package:varanasi_mobile_app/features/library/cubit/library_cubit.dart'; import 'package:varanasi_mobile_app/features/library/ui/library_widgets/library_app_bar.dart'; import 'package:varanasi_mobile_app/models/playable_item.dart'; +import 'package:varanasi_mobile_app/utils/extensions/extensions.dart'; import 'package:varanasi_mobile_app/utils/extensions/media_query.dart'; +import 'package:varanasi_mobile_app/widgets/add_to_library.dart'; import 'package:varanasi_mobile_app/widgets/download_button.dart'; import 'package:varanasi_mobile_app/widgets/media_list.dart'; import 'package:varanasi_mobile_app/widgets/play_pause_button.dart'; -import 'package:varanasi_mobile_app/widgets/typography.dart'; +import 'package:varanasi_mobile_app/widgets/player/full_screen_player/shuffle_mode_toggle.dart'; class LibraryContent extends StatefulHookWidget { /// The source of the library content @@ -107,20 +109,31 @@ class _LibraryContentState extends State { LibraryAppBar(state: state, padding: padding), SliverToBoxAdapter( child: Padding( - key: titleKey, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 16, ).copyWith(right: 84), - child: Row( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Typography( - state.title, - secondary: state.subtitle, + Text( + state.title, + style: context.textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.bold, + letterSpacing: 0.5, ), ), - DownloadPlaylist(playlist: state.playlist), + Text(state.subtitle), + Row( + key: titleKey, + children: [ + AddToLibrary(state.playlist), + DownloadPlaylist(playlist: state.playlist), + const Spacer(), + const ShuffleModeToggle(iconSize: 24), + ], + ), ], ), ), @@ -166,6 +179,7 @@ class _LibraryContentState extends State { ); }, isPlaying: isThisPlaylistPlaying, + size: 36, ), ) ], diff --git a/lib/features/user-library/cubit/user_library_cubit.dart b/lib/features/user-library/cubit/user_library_cubit.dart index dad21fd..7a5552d 100644 --- a/lib/features/user-library/cubit/user_library_cubit.dart +++ b/lib/features/user-library/cubit/user_library_cubit.dart @@ -47,4 +47,11 @@ class UserLibraryCubit extends AppCubit { final library = _repository.getLibraries(); emit(UserLibraryLoaded(library: library)); } + + Future removeFromLibrary(MediaPlaylist playlist) async { + _repository.deleteLibrary(playlist.toUserLibrary()); + final library = _repository.getLibraries(); + emit(UserLibraryLoaded(library: library)); + AppSnackbar.show("Removed from library"); + } } diff --git a/lib/features/user-library/cubit/user_library_state.dart b/lib/features/user-library/cubit/user_library_state.dart index f587519..63381a9 100644 --- a/lib/features/user-library/cubit/user_library_state.dart +++ b/lib/features/user-library/cubit/user_library_state.dart @@ -32,4 +32,10 @@ class UserLibraryLoaded extends UserLibraryState { (library) => library is Favorite, orElse: () => const Favorite.empty(), ) as Favorite; + + bool get isEmpty => library.isEmpty; + + bool isAdded(MediaPlaylist playlist) { + return library.any((a) => playlist.id == a.id); + } } diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart index e1ca7d9..918cb58 100644 --- a/lib/gen/assets.gen.dart +++ b/lib/gen/assets.gen.dart @@ -39,6 +39,9 @@ class $AssetsIconGen { $AssetsIconNavGen get nav => const $AssetsIconNavGen(); + /// File path: assets/icon/shuffle.svg + SvgGenImage get shuffle => const SvgGenImage('assets/icon/shuffle.svg'); + /// List of all assets List get values => [ appIcon, @@ -46,7 +49,8 @@ class $AssetsIconGen { circularLoader, download, downloadFilled, - downloading + downloading, + shuffle ]; } diff --git a/lib/widgets/add_to_library.dart b/lib/widgets/add_to_library.dart new file mode 100644 index 0000000..ff7d8f6 --- /dev/null +++ b/lib/widgets/add_to_library.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:varanasi_mobile_app/features/user-library/cubit/user_library_cubit.dart'; +import 'package:varanasi_mobile_app/models/media_playlist.dart'; + +class AddToLibrary extends StatelessWidget { + final MediaPlaylist playlist; + const AddToLibrary(this.playlist, {super.key}); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is! UserLibraryLoaded) return const SizedBox.shrink(); + final isAdded = state.isAdded(playlist); + AnimatedIcons.add_event; + return IconButton( + onPressed: () { + final cubit = context.read(); + if (isAdded) { + cubit.removeFromLibrary(playlist); + } else { + cubit.addToLibrary(playlist); + } + }, + icon: isAdded + ? const Icon(Icons.check_circle_rounded) + : const Icon(Icons.add_circle_outline_rounded), + iconSize: 30, + ); + }, + ); + } +} diff --git a/lib/widgets/download_button.dart b/lib/widgets/download_button.dart index c6e5b99..9fea6fd 100644 --- a/lib/widgets/download_button.dart +++ b/lib/widgets/download_button.dart @@ -97,8 +97,8 @@ class DownloadPlaylist extends StatelessWidget { downloading: downloading, downloaded: downloaded, progress: progress, + dimension: 26, ), - iconSize: 24, ); }); } @@ -120,7 +120,7 @@ class DownloadStatus extends StatelessWidget { final double dimension; final bool hideStopIconOnIos; - double get iconSize => dimension * 0.6; + double get iconSize => dimension * 0.8; @override Widget build(BuildContext context) { diff --git a/lib/widgets/player/full_screen_player/full_screen_player.dart b/lib/widgets/player/full_screen_player/full_screen_player.dart index c189d1c..7de0ad7 100644 --- a/lib/widgets/player/full_screen_player/full_screen_player.dart +++ b/lib/widgets/player/full_screen_player/full_screen_player.dart @@ -94,7 +94,7 @@ class _PlayerState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - ShuffleModeToggle(audioHandler: audioHandler), + const ShuffleModeToggle(), SkipToPrevious(queueState: queueState), PlayPauseMediaButton( backgroundColor: Colors.white, diff --git a/lib/widgets/player/full_screen_player/shuffle_mode_toggle.dart b/lib/widgets/player/full_screen_player/shuffle_mode_toggle.dart index 07b51f5..0664df5 100644 --- a/lib/widgets/player/full_screen_player/shuffle_mode_toggle.dart +++ b/lib/widgets/player/full_screen_player/shuffle_mode_toggle.dart @@ -2,21 +2,25 @@ import 'package:audio_service/audio_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:varanasi_mobile_app/cubits/player/player_cubit.dart'; +import 'package:varanasi_mobile_app/gen/assets.gen.dart'; import 'package:varanasi_mobile_app/utils/extensions/theme.dart'; -import 'package:varanasi_mobile_app/utils/player/audio_handler_impl.dart'; class ShuffleModeToggle extends StatelessWidget { const ShuffleModeToggle({ super.key, - required this.audioHandler, + this.iconSize = 32, }); - final AudioHandlerImpl audioHandler; + final double iconSize; + + double get smallSize => iconSize * 0.18; @override Widget build(BuildContext context) { + final audioHandler = context.read().audioHandler; return StreamBuilder( stream: audioHandler.playbackState.map((event) => event.shuffleMode), + initialData: AudioServiceShuffleMode.none, builder: (context, snapshot) { final shuffleEnabled = ![null, AudioServiceShuffleMode.none].contains(snapshot.data); @@ -35,14 +39,16 @@ class ShuffleModeToggle extends StatelessWidget { icon: Badge( alignment: Alignment.bottomCenter, isLabelVisible: shuffleEnabled, - backgroundColor: context.colorScheme.primary, - child: const Padding( - padding: EdgeInsets.symmetric(vertical: 4.0), - child: Icon(Icons.shuffle), + smallSize: smallSize, + child: Assets.icon.shuffle.svg( + width: iconSize, + height: iconSize, + color: + shuffleEnabled ? context.colorScheme.primary : Colors.white, ), ), color: shuffleEnabled ? context.colorScheme.primary : null, - iconSize: 32, + iconSize: iconSize, ); }, );