diff options
author | Lisandro Pérez Meyer <lpmeyer@ics.com> | 2023-11-14 17:20:58 -0300 |
---|---|---|
committer | Lisandro Pérez Meyer <lpmeyer@ics.com> | 2023-11-14 17:31:12 -0300 |
commit | 70ec8a79a121471a004e7e4c23157d10157e136f (patch) | |
tree | a4f9c0a4fac4e4274ec4324a289b6ef62e1c5653 /lib/presentation/screens/media_player |
Initial cleanup push.
Based on agldemo2024 on commit 2a5dc04d801134338150c3f6afc67eaa65599763
Disable device preview.
Disable Lottie animation.
The original commit was b3c493c340fcb4bb0a937692838fc830bec3e9ea
but I am just keeping this change, because the json did not really
needed to change. I think.
Signed-off-by: Lisandro Pérez Meyer <lpmeyer@ics.com>
Diffstat (limited to 'lib/presentation/screens/media_player')
10 files changed, 1191 insertions, 0 deletions
diff --git a/lib/presentation/screens/media_player/fm_player.dart b/lib/presentation/screens/media_player/fm_player.dart new file mode 100644 index 0000000..31a22ae --- /dev/null +++ b/lib/presentation/screens/media_player/fm_player.dart @@ -0,0 +1,76 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class FMPlayer extends StatefulWidget { + const FMPlayer({super.key}); + + @override + State<FMPlayer> createState() => _FMPlayerState(); +} + +class _FMPlayerState extends State<FMPlayer> { + String selectedNav = "Standard"; + List<String> navItems = [ + "Standard", + "HD", + ]; + String tableName = "Presets"; + List<PlayListModel> playList = [ + PlayListModel(songName: "93.1 The Mountain", albumName: "93.1"), + PlayListModel(songName: "Mix 94.1", albumName: "94.1 MHz"), + PlayListModel(songName: "96.3 KKLZ", albumName: "96.3 MHz"), + ]; + String selectedPlayListSongName = "93.1 The Mountain"; + @override + Widget build(BuildContext context) { + double fmSignalHeight = 460; + double fmSignalWidth = 460; + + return Container( + padding: const EdgeInsets.only(left: 7, right: 7), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + SegmentedButtons( + navItems: navItems, + selectedNav: selectedNav, + ), + const SizedBox( + height: 32, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + "assets/AlbumArtFM.png", + width: fmSignalWidth, + height: fmSignalHeight, + ) + ], + ), + const SizedBox( + height: 40, + ), + Column( + children: [ + const MediaControls( + songName: "87.9", + songLengthStart: "87.9 MHz", + songLengthStop: "87.9 MHz", + type: "fm", + ), + const SizedBox( + height: 70, + ), + PlayListTable( + playList: playList, + selectedPlayListSongName: selectedPlayListSongName, + tableName: tableName, + type: "fm", + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/presentation/screens/media_player/media_content.dart b/lib/presentation/screens/media_player/media_content.dart new file mode 100644 index 0000000..9a0ce19 --- /dev/null +++ b/lib/presentation/screens/media_player/media_content.dart @@ -0,0 +1,82 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class MediaPlayer extends StatefulWidget { + const MediaPlayer({super.key}); + + @override + State<MediaPlayer> createState() => _MediaPlayerState(); +} + +class _MediaPlayerState extends State<MediaPlayer> { + String selectedNav = "Bluetooth"; + List<String> navItems = ["Bluetooth", "SD", "USB"]; + + late String songName = "Feel Good Inc."; + + String tableName = "2000’s Dance Hits"; + List<PlayListModel> playList = [ + PlayListModel(songName: "Feel Good Inc.", albumName: "Gorillaz"), + PlayListModel( + songName: "Hips Don’t Lie", albumName: "Shakira, Wyclef Jean"), + PlayListModel(songName: "AG1", albumName: "Paid Advertisement"), + PlayListModel(songName: "Hey Ya!", albumName: "Outkast"), + PlayListModel(songName: "One, Two, Step", albumName: "Ciara, Missy Elliot"), + PlayListModel(songName: "Don’t Trust Me", albumName: "3OH!3"), + PlayListModel(songName: "Feel Good Inc.", albumName: "Gorillaz"), + PlayListModel(songName: "Feel Good Inc.", albumName: "Gorillaz"), + PlayListModel(songName: "Feel Good Inc.", albumName: "Gorillaz"), + PlayListModel(songName: "Feel Good Inc.", albumName: "Gorillaz"), + ]; + String selectedPlayListSongName = "Feel Good Inc."; + + @override + Widget build(BuildContext context) { + double albumArtSize = 460; + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // const PlayerNavigation(), + SegmentedButtons( + navItems: navItems, + selectedNav: selectedNav, + ), + const SizedBox( + height: 32, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + "assets/AlbumArtMedia.png", + width: albumArtSize, + height: albumArtSize, + ) + ], + ), + const SizedBox( + height: 40, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + MediaControls( + songName: songName, + songLengthStart: "-1:23", + songLengthStop: "5:03", + type: "media", + ), + const SizedBox( + height: 72, + ), + PlayListTable( + playList: playList, + selectedPlayListSongName: selectedPlayListSongName, + tableName: tableName, + type: "media", + ), + ], + ) + ], + ); + } +} diff --git a/lib/presentation/screens/media_player/media_controls.dart b/lib/presentation/screens/media_player/media_controls.dart new file mode 100644 index 0000000..0686187 --- /dev/null +++ b/lib/presentation/screens/media_player/media_controls.dart @@ -0,0 +1,413 @@ +import 'package:flutter_ics_homescreen/core/utils/helpers.dart'; +import 'package:flutter_ics_homescreen/export.dart'; +import 'package:flutter_ics_homescreen/presentation/screens/media_player/widgets/gradient_progress_indicator.dart'; + +class MediaControls extends StatefulWidget { + const MediaControls( + {super.key, + required this.type, + required this.songName, + required this.songLengthStart, + required this.songLengthStop}); + + final String type; + final String songName; + final String songLengthStart; + final String songLengthStop; + + @override + State<MediaControls> createState() => _MediaControlsState(); +} + +class _MediaControlsState extends State<MediaControls> { + late String songName; + late String songLengthStart; + late String songLengthStop; + final String albumName = "Gorillaz"; + + int songProgress = 20; + + @override + void initState() { + songName = widget.songName; + songLengthStart = widget.songLengthStart; + songLengthStop = widget.songLengthStop; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Material( + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + songName, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + shadows: [Helpers.dropShadowRegular], + fontSize: 44), + ), + if (widget.type == "media") + MediaControlSubDetails( + albumName: albumName, + ) + else if (widget.type == "fm") + const FMPlayerSubDetails(), + if (widget.type == "media") + Column(children: [ + GradientProgressIndicator( + percent: songProgress, + type: "media", + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + AGLDemoColors.jordyBlueColor, + AGLDemoColors.jordyBlueColor.withOpacity(0.8), + ]), + backgroundColor: AGLDemoColors.gradientBackgroundDarkColor, + ), + // const LinearProgressIndicator( + // backgroundColor: AGLDemoColors.gradientBackgroundDarkColor, + // color: Colors.white70, + // minHeight: 8, + // value: 0.7, + // ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + songLengthStart, + style: TextStyle( + color: Colors.white, + fontSize: 26, + shadows: [Helpers.dropShadowRegular]), + ), + Text( + songLengthStop, + style: TextStyle( + color: Colors.white, + fontSize: 26, + shadows: [Helpers.dropShadowRegular]), + ) + ], + ), + ), + ]) + else if (widget.type == "fm") + FMPlayerSlider( + minHertz: songLengthStart, + maxHertz: songLengthStop, + songProgress: songProgress, + ), + if (widget.type == "media") const MediaPlayerActions() + ], + ), + ); + } +} + +class MediaControlSubDetails extends StatefulWidget { + const MediaControlSubDetails({super.key, required this.albumName}); + final String albumName; + + @override + State<MediaControlSubDetails> createState() => _MediaControlSubDetailsState(); +} + +class _MediaControlSubDetailsState extends State<MediaControlSubDetails> { + bool isShuffleEnabled = false; + bool isRepeatEnabled = false; + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.albumName, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 40, + shadows: [Helpers.dropShadowRegular]), + ), + Row( + children: [ + InkWell( + customBorder: const CircleBorder(), + onTap: () { + setState(() { + isShuffleEnabled = !isShuffleEnabled; + }); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/${isShuffleEnabled ? "ShufflePressed.svg" : "Shuffle.svg"}", + width: 48, + ))), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + setState(() { + isRepeatEnabled = !isRepeatEnabled; + }); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/${isRepeatEnabled ? "RepeatPressed.svg" : "Repeat.svg"}", + width: 48, + ))), + ], + ) + ], + ); + } +} + +class FMPlayerSubDetails extends StatefulWidget { + const FMPlayerSubDetails({ + super.key, + }); + + @override + State<FMPlayerSubDetails> createState() => _FMPlayerSubDetailsState(); +} + +class _FMPlayerSubDetailsState extends State<FMPlayerSubDetails> { + onPressed({required String type}) {} + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(bottom: 5), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text( + "Tune", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 40, + shadows: [Helpers.dropShadowRegular]), + ), + const SizedBox( + width: 25, + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + onPressed(type: "scanLeft"); + }, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_back, + size: 48, + color: AGLDemoColors.periwinkleColor, + ))), + const SizedBox( + width: 25, + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + onPressed(type: "scanRight"); + }, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_forward, + color: AGLDemoColors.periwinkleColor, + size: 48, + ))), + ], + ), + Row( + children: [ + Text( + "Scan", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 40, + shadows: [Helpers.dropShadowRegular]), + ), + const SizedBox( + width: 25, + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + onPressed(type: "scanLeft"); + }, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_back, + color: AGLDemoColors.periwinkleColor, + size: 48, + ))), + const SizedBox( + width: 25, + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + onPressed(type: "scanRight"); + }, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon( + Icons.arrow_forward, + color: AGLDemoColors.periwinkleColor, + size: 48, + ))), + ], + ) + ], + ), + ); + } +} + +class MediaPlayerActions extends StatefulWidget { + const MediaPlayerActions({super.key}); + + @override + State<MediaPlayerActions> createState() => _MediaPlayerActionsState(); +} + +class _MediaPlayerActionsState extends State<MediaPlayerActions> { + bool isPressed = false; + bool isPlaying = true; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + customBorder: const CircleBorder(), + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/SkipPrevious.svg", + width: 48, + ), + )), + const SizedBox( + width: 120, + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + setState(() { + isPlaying = !isPlaying; + }); + }, + onTapDown: (details) { + setState(() { + isPressed = true; + }); + }, + onTapUp: (details) { + isPressed = false; + + }, + child: Container( + width: 64, + height: 64, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: + isPressed ? Colors.white : AGLDemoColors.periwinkleColor, + boxShadow: [Helpers.boxDropShadowRegular]), + child: Icon( + isPlaying ? Icons.pause : Icons.play_arrow, + color: AGLDemoColors.resolutionBlueColor, + size: 60, + ), + )), + const SizedBox( + width: 120, + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () {}, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/SkipNext.svg", + width: 48, + ), + )), + ], + ); + } +} + +class FMPlayerSlider extends StatefulWidget { + const FMPlayerSlider( + {super.key, + required this.minHertz, + required this.maxHertz, + required this.songProgress}); + final String minHertz; + final String maxHertz; + final int songProgress; + + @override + State<FMPlayerSlider> createState() => _FMPlayerSliderState(); +} + +class _FMPlayerSliderState extends State<FMPlayerSlider> { + @override + Widget build(BuildContext context) { + return Row( + children: [ + Text( + widget.minHertz, + style: TextStyle( + color: Colors.white, + fontSize: 26, + shadows: [Helpers.dropShadowRegular]), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 40), + child: GradientProgressIndicator( + percent: widget.songProgress, + height: 10, + type: "fm", + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + AGLDemoColors.jordyBlueColor, + AGLDemoColors.jordyBlueColor.withOpacity(0.8), + ]), + backgroundColor: AGLDemoColors.gradientBackgroundDarkColor, + ), + ), + ), + Text( + widget.maxHertz, + style: TextStyle( + color: Colors.white, + fontSize: 26, + shadows: [Helpers.dropShadowRegular]), + ) + ], + ); + } +} diff --git a/lib/presentation/screens/media_player/media_player.dart b/lib/presentation/screens/media_player/media_player.dart new file mode 100644 index 0000000..9ec31e2 --- /dev/null +++ b/lib/presentation/screens/media_player/media_player.dart @@ -0,0 +1,99 @@ +import 'package:flutter_ics_homescreen/presentation/screens/media_player/fm_player.dart'; + +import '/export.dart'; +import 'widgets/media_volume_bar.dart'; + +class MediaPlayerPage extends StatelessWidget { + const MediaPlayerPage({super.key}); + + static Page<void> page() => + const MaterialPage<void>(child: MediaPlayerPage()); + @override + Widget build(BuildContext context) { + Size size = MediaQuery.sizeOf(context); + + return Stack( + children: [ + // SizedBox( + // width: size.width, + // height: size.height, + // //color: Colors.black, + // // decoration: + // // BoxDecoration(gradient: AGLDemoColors.gradientBackgroundColor), + // child: SvgPicture.asset( + // 'assets/MediaPlayerBackground.svg', + // alignment: Alignment.center, + // fit: BoxFit.cover, + // //width: 200, + // //height: 200, + // ), + // ), + SizedBox( + width: size.width, + height: size.height, + // color: Colors.black, + child: SvgPicture.asset( + 'assets/MediaPlayerBackgroundTextures.svg', + // alignment: Alignment.center, + fit: BoxFit.cover, + //width: 200, + //height: 200, + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 50, horizontal: 50), + child: MediaPlayerBackground(), + ) + //const MediaPlayer(), + ], + ); + } +} + +class MediaPlayerBackground extends StatefulWidget { + const MediaPlayerBackground({super.key}); + + @override + State<MediaPlayerBackground> createState() => _MediaPlayerBackgroundState(); +} + +class _MediaPlayerBackgroundState extends State<MediaPlayerBackground> { + String selectedNav = "My Media"; + onPressed(type) { + setState(() { + selectedNav = type; + }); + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + children: [ + const SizedBox( + height: 55, + ), + PlayerNavigation( + onPressed: (val) { + onPressed(val); + }, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 144), + child: SingleChildScrollView( + child: selectedNav == "My Media" + ? const MediaPlayer() + : selectedNav == "FM" + ? const FMPlayer() + : Container(), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 144, vertical: 23.5), + child: CustomVolumeSlider(), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/media_player/my_media.dart b/lib/presentation/screens/media_player/my_media.dart new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/presentation/screens/media_player/my_media.dart diff --git a/lib/presentation/screens/media_player/play_list_table.dart b/lib/presentation/screens/media_player/play_list_table.dart new file mode 100644 index 0000000..b17cfca --- /dev/null +++ b/lib/presentation/screens/media_player/play_list_table.dart @@ -0,0 +1,154 @@ +import 'package:flutter_ics_homescreen/core/utils/helpers.dart'; +import 'package:flutter_ics_homescreen/export.dart'; + +class PlayListTable extends StatefulWidget { + const PlayListTable( + {super.key, + required this.type, + required this.tableName, + required this.playList, + required this.selectedPlayListSongName}); + final String type; + final String tableName; + final List<PlayListModel> playList; + final String selectedPlayListSongName; + + @override + State<PlayListTable> createState() => _PlayListTableState(); +} + +class _PlayListTableState extends State<PlayListTable> { + bool isAudioSettingsEnabled = false; + late String tableName; + late List<PlayListModel> playList; + late String selectedPlayListSongName; + @override + void initState() { + tableName = widget.tableName; + playList = widget.playList; + selectedPlayListSongName = widget.selectedPlayListSongName; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Material( + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text( + tableName, + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + fontSize: 40), + ), + if (widget.type == "media") + InkWell( + customBorder: const CircleBorder(), + onTap: () {}, + child: Opacity( + opacity: 0.5, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/AppleMusic.svg", + width: 32, + )), + )), + ], + ), + InkWell( + customBorder: const CircleBorder(), + onTap: () { + setState(() { + isAudioSettingsEnabled = !isAudioSettingsEnabled; + }); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SvgPicture.asset( + "assets/${isAudioSettingsEnabled ? "AudioSettingsPressed.svg" : "AudioSettings.svg"}", + width: 48, + ))) + ], + ), + SizedBox( + height: 325, + child: SingleChildScrollView( + child: Column( + children: playList.map((index) { + return Container( + height: 100, + margin: const EdgeInsets.symmetric(vertical: 4), + decoration: BoxDecoration( + border: Border( + left: selectedPlayListSongName == index.songName + ? const BorderSide( + color: Colors.white, width: 4) + : BorderSide.none), + gradient: LinearGradient( + colors: selectedPlayListSongName == index.songName + ? [ + AGLDemoColors.neonBlueColor, + AGLDemoColors.neonBlueColor + .withOpacity(0.15) + ] + : [ + Colors.black, + Colors.black.withOpacity(0.20) + ])), + child: InkWell( + onTap: () { + setState(() { + selectedPlayListSongName = index.songName; + }); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 17, horizontal: 24), + child: Row( + children: [ + Expanded( + flex: 6, + child: Text( + index.songName, + style: TextStyle( + color: Colors.white, + fontSize: 40, + shadows: [Helpers.dropShadowRegular]), + )), + Expanded( + flex: 4, + child: Text( + index.albumName, + style: TextStyle( + color: Colors.white, + fontSize: 26, + shadows: [Helpers.dropShadowRegular]), + )) + ], + ), + ), + ), + ); + }).toList()), + ), + ), + ], + )); + } +} + +class PlayListModel { + final String songName; + final String albumName; + + PlayListModel({required this.songName, required this.albumName}); +} diff --git a/lib/presentation/screens/media_player/player_navigation.dart b/lib/presentation/screens/media_player/player_navigation.dart new file mode 100644 index 0000000..8e09e53 --- /dev/null +++ b/lib/presentation/screens/media_player/player_navigation.dart @@ -0,0 +1,80 @@ +import 'package:flutter_ics_homescreen/core/utils/helpers.dart'; +import 'package:flutter_ics_homescreen/export.dart'; + +class PlayerNavigation extends StatefulWidget { + const PlayerNavigation({super.key, required this.onPressed}); + final Function onPressed; + + @override + State<PlayerNavigation> createState() => _PlayerNavigationState(); +} + +class _PlayerNavigationState extends State<PlayerNavigation> { + List<String> navItems = ["My Media", "FM", "AM", "XM"]; + String selectedNav = "My Media"; + @override + Widget build(BuildContext context) { + return Row( + children: navItems + .map((e) => Expanded( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 2), + decoration: BoxDecoration( + gradient: LinearGradient(colors: [ + selectedNav == e + ? AGLDemoColors.neonBlueColor + : AGLDemoColors.buttonFillEnabledColor, + AGLDemoColors.gradientBackgroundDarkColor + ], begin: Alignment.topCenter, end: Alignment.bottomCenter), + // color: selectedNav == e + // ? AGLDemoColors.neonBlueColor + // : AGLDemoColors.buttonFillEnabledColor, + ), + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + setState(() { + selectedNav = e; + }); + widget.onPressed(selectedNav); + }, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 7), + decoration: BoxDecoration( + border: Border( + left: selectedNav == e + ? const BorderSide(color: Colors.white12) + : BorderSide.none, + right: selectedNav == e + ? const BorderSide(color: Colors.white12) + : BorderSide.none, + top: BorderSide( + color: selectedNav == e + ? Colors.white + : Colors.white24, + width: selectedNav == e ? 2 : 1))), + child: Text( + e, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 26, + shadows: [ + selectedNav == e + ? Helpers.dropShadowRegular + : Helpers.dropShadowBig + ], + color: selectedNav == e + ? Colors.white + : AGLDemoColors.periwinkleColor, + fontWeight: selectedNav == e + ? FontWeight.w700 + : FontWeight.w500), + ), + ), + ), + ), + ))) + .toList()); + } +} diff --git a/lib/presentation/screens/media_player/segmented_buttons.dart b/lib/presentation/screens/media_player/segmented_buttons.dart new file mode 100644 index 0000000..e649be3 --- /dev/null +++ b/lib/presentation/screens/media_player/segmented_buttons.dart @@ -0,0 +1,82 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class SegmentedButtons extends StatefulWidget { + const SegmentedButtons( + {super.key, required this.navItems, required this.selectedNav}); + + final List<String> navItems; + final String selectedNav; + @override + State<SegmentedButtons> createState() => _SegmentedButtonsState(); +} + +class _SegmentedButtonsState extends State<SegmentedButtons> { + late List<String> navItems; + late String selectedNav; + + @override + void initState() { + navItems = widget.navItems; + selectedNav = widget.selectedNav; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + margin: const EdgeInsets.only(top: 40), + padding: const EdgeInsets.all(3), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + offset: const Offset(0, 4), + blurRadius: 4, + color: Colors.black.withOpacity(0.25)) + ], + borderRadius: BorderRadius.circular(40), + color: AGLDemoColors.buttonFillEnabledColor, + border: Border.all(color: Colors.white12), + ), + child: Row( + children: navItems + .map((e) => Container( + padding: const EdgeInsets.symmetric( + vertical: 24, horizontal: 32), + decoration: BoxDecoration( + borderRadius: selectedNav == e + ? BorderRadius.circular(40) + : BorderRadius.zero, + color: selectedNav == e + ? AGLDemoColors.backgroundInsetColor + : null, + ), + child: InkWell( + borderRadius: BorderRadius.circular(40), + onTap: () { + setState(() { + selectedNav = e; + }); + }, + child: Text( + e, + style: TextStyle( + color: selectedNav == e + ? Colors.white + : AGLDemoColors.periwinkleColor, + fontSize: 26, + fontWeight: selectedNav == e + ? FontWeight.w700 + : FontWeight.w500), + ), + ), + )) + .toList(), + ), + ), + ], + ); + } +} diff --git a/lib/presentation/screens/media_player/widgets/gradient_progress_indicator.dart b/lib/presentation/screens/media_player/widgets/gradient_progress_indicator.dart new file mode 100644 index 0000000..24aa244 --- /dev/null +++ b/lib/presentation/screens/media_player/widgets/gradient_progress_indicator.dart @@ -0,0 +1,88 @@ +import 'package:flutter_ics_homescreen/core/utils/helpers.dart'; +import 'package:flutter_ics_homescreen/export.dart'; + +class GradientProgressIndicator extends StatelessWidget { + ///it can be anything between 0 to 100 + final int percent; + final Gradient gradient; + final Color backgroundColor; + final double height; + final String type; + + const GradientProgressIndicator( + {required this.percent, + required this.gradient, + required this.backgroundColor, + Key? key, + this.height = 16, + required this.type}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Flexible( + flex: percent, + fit: FlexFit.tight, + child: Container( + height: height, + margin: const EdgeInsets.all(1), + decoration: BoxDecoration( + border: Border.all( + color: AGLDemoColors.neonBlueColor.withOpacity(0.5), + width: 1), + gradient: gradient, + borderRadius: + BorderRadius.all(Radius.circular(type == "fm" ? 16 : 2)), + ), + alignment: Alignment.centerRight, + ), + ), + type == "media" + ? Container( + height: height, + width: 2, + color: Colors.white, + ) + : Container( + height: 64, + width: 64, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + Helpers.boxDropShadowRegular, + ], + color: AGLDemoColors.periwinkleColor), + child: Container( + height: 32, + width: 32, + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + Helpers.boxDropShadowRegular, + ], + border: Border.all( + color: AGLDemoColors.neonBlueColor, width: 2), + color: AGLDemoColors.periwinkleColor), + ), + ), + Flexible( + fit: FlexFit.tight, + flex: 100 - percent, + child: Container( + decoration: BoxDecoration( + color: backgroundColor, + border: Border.all( + color: AGLDemoColors.neonBlueColor.withOpacity(0.5), + width: 1), + borderRadius: const BorderRadius.all(Radius.circular(2)), + ), + child: SizedBox(height: height), + ), + ), + ], + ); + } +} diff --git a/lib/presentation/screens/media_player/widgets/media_volume_bar.dart b/lib/presentation/screens/media_player/widgets/media_volume_bar.dart new file mode 100644 index 0000000..f8d58e6 --- /dev/null +++ b/lib/presentation/screens/media_player/widgets/media_volume_bar.dart @@ -0,0 +1,117 @@ +import 'package:flutter_ics_homescreen/presentation/custom_icons/custom_icons.dart'; + +import '../../../../export.dart'; +import '../../settings/settings_screens/audio_settings/widget/slider_widgets.dart'; + +class CustomVolumeSlider extends ConsumerStatefulWidget { + const CustomVolumeSlider({ + super.key, + }); + + @override + CustomVolumeSliderState createState() => CustomVolumeSliderState(); +} + +class CustomVolumeSliderState extends ConsumerState<CustomVolumeSlider> { + void _increase() { + setState(() { + if (_currentVal < 20) { + _currentVal++; + ref.read(audioStateProvider.notifier).setVolume(_currentVal); + } + }); + } + + void _dercrease() { + setState(() { + if (_currentVal > 0) { + _currentVal--; + ref.read(audioStateProvider.notifier).setVolume(_currentVal); + } + }); + } + + double _currentVal = 5; + @override + Widget build(BuildContext context) { + final volumeValue = + ref.watch(audioStateProvider.select((audio) => audio.volume)); + + return Column( + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + decoration: const ShapeDecoration( + color: AGLDemoColors.buttonFillEnabledColor, + shape: StadiumBorder( + side: BorderSide( + color: Color(0xFF5477D4), + width: 0.5, + )), + ), + height: 160, + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 10.0), + child: SizedBox( + width: 50, + child: IconButton( + padding: EdgeInsets.zero, + onPressed: () { + _dercrease(); + }, + icon: const Icon( + CustomIcons.vol_min, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + ), + Expanded( + child: SliderTheme( + data: SliderThemeData( + overlayShape: SliderComponentShape.noOverlay, + valueIndicatorShape: SliderComponentShape.noOverlay, + activeTickMarkColor: Colors.transparent, + inactiveTickMarkColor: Colors.transparent, + inactiveTrackColor: AGLDemoColors.backgroundInsetColor, + thumbShape: const PolygonSliderThumb( + sliderValue: 3, thumbRadius: 23), + //trackHeight: 5, + ), + child: Slider( + divisions: 20, + min: 0, + max: 20, + value: volumeValue, + onChanged: (newValue) { + ref.read(audioStateProvider.notifier).setVolume(newValue); + _currentVal = newValue; + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 10.0), + child: SizedBox( + width: 60, + child: IconButton( + padding: EdgeInsets.zero, + onPressed: () { + _increase(); + }, + icon: const Icon( + CustomIcons.vol_max, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + ), + ], + ), + ), + ], + ); + } +} |