// ignore_for_file: prefer_const_literals_to_create_immutables, avoid_print import 'dart:convert'; import 'package:fipy/models/track.dart'; import 'package:fipy/providers/home.dart'; import 'package:fipy/providers/player.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:miniplayer/miniplayer.dart'; import 'package:provider/provider.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key, required this.title}) : super(key: key); final String title; @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { String radio = 'fip_groove'; @override Widget build(BuildContext context) { HomeProvider hp = Provider.of(context, listen: false); final MiniplayerController controller = MiniplayerController(); return RawKeyboardListener( autofocus: true, focusNode: FocusNode(), onKey: (RawKeyEvent event) { if (event.runtimeType == RawKeyDownEvent && event.data.logicalKey.keyId == 32) //Enter Key ID from keyboard { print('tata'); hp.player?.playing ?? false ? hp.player?.pause() : hp.player?.play(); } }, child: Stack( children: [ Scaffold( body: RawScrollbar( thumbColor: Colors.grey[600], radius: const Radius.circular(20), thickness: 12, // thumbVisibility: true, mainAxisMargin: 70, child: SingleChildScrollView( child: Column( children: [ Container( color: Colors.grey[900], height: 50, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ DropdownButton( dropdownColor: Colors.grey[900], value: radio, style: TextStyle( fontSize: 15, color: Colors.grey[300]), underline: const SizedBox(), iconSize: 22, onChanged: (String? newRadio) { setState(() { radio = newRadio!; }); }, items: hp.radioList), const SizedBox(width: 50), DropdownButton( dropdownColor: Colors.grey[900], value: hp.userPageNbr.toString(), style: TextStyle( fontSize: 15, color: Colors.grey[300]), underline: const SizedBox(), iconSize: 22, onChanged: (String? newPageNumber) { setState(() { hp.userPageNbr = int.parse(newPageNumber!); }); }, items: hp.pageList), ]), ), FutureBuilder>( future: hp.getTracks(radio), builder: ( BuildContext context, AsyncSnapshot> snapshot, ) { print(snapshot.connectionState); if (snapshot.connectionState == ConnectionState.waiting) { return Stack(children: [ Container( height: 10000, width: 10000, color: const Color(0xFF121212)), Center( child: Column(children: [ const SizedBox(height: 20), SizedBox( height: 30, width: 30, child: CircularProgressIndicator( color: Colors.amber[100], ), ), ]), ), ]); } else if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { return Stack(children: [ Container( height: 10000, width: 10000, color: const Color(0xFF121212)), Center( child: Column(children: [ const SizedBox(height: 20), Text( 'Error: ' + snapshot.error.toString(), style: TextStyle(color: Colors.grey[500]), ), ]), ), ]); } else if (snapshot.hasData) { return Table( columnWidths: { 0: const FlexColumnWidth(4), 1: const FlexColumnWidth(2), 2: const FlexColumnWidth(1), }, defaultVerticalAlignment: TableCellVerticalAlignment.middle, children: snapshot.data! .map( (item) => _buildTableRow(item, context)) .toList() ..insert( 0, _buildTableRow( Track( number: -1, title: 'TITRE', artiste: 'ARTISTE', album: 'ALBUM', id: 'URL'), context), ), ); } else { return const Text('Empty data'); } } else { return Text('State: ${snapshot.connectionState}'); } }, ), const SizedBox(height: 70) ], ), )), ), Consumer(builder: (context, playerProvider, _) { TextEditingController trackTitle = TextEditingController(); TextEditingController trackArtiste = TextEditingController(); trackTitle.text = hp.currentTrack?.title ?? ''; trackArtiste.text = hp.currentTrack?.artiste ?? ''; return Miniplayer( controller: controller, backgroundColor: Colors.grey[900]!, minHeight: 70, maxHeight: 70, builder: (height, percentage) { return Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ hp.currentTrack?.imageUrl != '' && hp.currentTrack?.imageUrl != null ? Image.network( hp.currentTrack!.imageUrl!, width: 70, ) : const SizedBox(width: 70), Expanded( child: Column(children: [ SizedBox( height: 20, child: TextField( enabled: false, maxLines: 1, controller: trackTitle, decoration: const InputDecoration( border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, disabledBorder: InputBorder.none, contentPadding: EdgeInsets.only(left: 15), ), style: TextStyle( fontSize: 14, color: Colors.grey[300], ), ), ), SizedBox( height: 20, child: TextField( enabled: false, maxLines: 1, controller: trackArtiste, decoration: const InputDecoration( border: InputBorder.none, focusedBorder: InputBorder.none, enabledBorder: InputBorder.none, disabledBorder: InputBorder.none, contentPadding: EdgeInsets.only(left: 15), ), style: TextStyle( fontSize: 12, color: Colors.grey[500], ), ), ), ]), ), Column(children: [ const Spacer(), Row(children: [ const SizedBox(width: 70), Column(children: [ IconButton( padding: const EdgeInsets.all(0), icon: Icon(Icons.skip_previous, color: Colors.grey[500], size: 32), onPressed: () { if (hp.currentTrack != null && hp.currentTrack!.number > 1) { hp.currentTrack = hp.trackList.firstWhere( (element) => element.number == hp.currentTrack!.number - 1); hp.playTrack(context, hp.currentTrack!); } }), ]), const SizedBox(width: 1), ElevatedButton( onPressed: () { hp.player?.playing ?? false ? hp.player?.pause() : hp.player?.play(); // playerProvider.reload(); }, child: Icon( hp.player?.playing ?? false ? Icons.pause : Icons.play_arrow, color: Colors.grey[900], size: 30), style: ElevatedButton.styleFrom( shape: const CircleBorder(), padding: const EdgeInsets.all(12), primary: Colors.grey[300], onPrimary: Colors.grey[900], ), ), Column(children: [ IconButton( padding: const EdgeInsets.all(0), icon: Icon(Icons.skip_next, color: Colors.grey[500], size: 32), onPressed: () { if (hp.currentTrack != null && hp.currentTrack!.number < hp.trackList.last.number) { hp.currentTrack = hp.trackList.firstWhere( (element) => element.number == hp.currentTrack!.number + 1); hp.playTrack(context, hp.currentTrack!); } }), // const SizedBox(height: 7), ]), ]), const Spacer(), Row(children: [ const SizedBox(width: 70), Text( timeFormat(hp.player?.position ?? const Duration(seconds: 0)), style: TextStyle(color: Colors.grey[500], fontSize: 12), ), const SizedBox(width: 3), SliderTheme( data: const SliderThemeData( thumbShape: RoundSliderThumbShape(enabledThumbRadius: 2), overlayShape: RoundSliderThumbShape(enabledThumbRadius: 5), trackHeight: 2, ), child: SizedBox( width: 300, child: Slider( value: double.parse( hp.player?.position.inSeconds.toString() ?? '0'), max: double.parse( hp.player?.duration.inSeconds.toString() ?? '2000'), onChanged: (double value) { if (hp.player?.position != null) { hp.player!.position = Duration(seconds: value.toInt()); playerProvider.reload(); } }, activeColor: Colors.grey[400], inactiveColor: Colors.grey[700], ), ), ), const SizedBox(width: 3), Text( timeFormat(hp.player?.duration ?? const Duration(seconds: 0)), style: TextStyle(color: Colors.grey[500], fontSize: 12), ), ]), const Spacer(), ]), const Spacer(), SliderTheme( data: const SliderThemeData( thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7), overlayShape: RoundSliderThumbShape(enabledThumbRadius: 8), trackHeight: 2.5, ), child: SizedBox( width: 130, child: Slider( value: hp.player?.volume ?? 1, max: 1, onChanged: (double value) { if (hp.player?.volume != null) { hp.player!.volume = value; playerProvider.reload(); } }, activeColor: Colors.grey[400], inactiveColor: Colors.grey[700], ), ), ), const SizedBox(width: 20) ], ); }, ); }) ], ), ); } } Widget trackLine(Track track) { return SizedBox( height: 30, child: Row( children: [Text(track.title + ' - ' + track.artiste)], ), ); } TableRow _buildTableRow(Track track, BuildContext context) { DownloadProvider downloadProvider = Provider.of(context, listen: false); HomeProvider hp = Provider.of(context, listen: false); int isDownloading = -1; final textStyle = TextStyle( fontWeight: track.number == -1 ? FontWeight.w200 : FontWeight.normal, color: Colors.grey[500], fontSize: track.number == -1 ? 15 : 14); const rowPadding = EdgeInsets.all(10); final yt = YoutubeExplode(); return TableRow( decoration: const BoxDecoration( color: Color(0xFF121212), ), children: [ TableCell( child: Padding( padding: rowPadding, child: InkWell( onTap: () async { if (track.number != -1) { hp.playTrack(context, track); } }, child: Row(children: [ track.number != -1 ? track.image == '' ? const SizedBox(width: 40) : Image.memory(base64Decode(track.image!), height: 40) : const SizedBox(), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Consumer( builder: (context, playerProvider, _) { return Text(track.title, style: TextStyle( fontWeight: FontWeight.normal, color: hp.currentTrack?.title == track.title && hp.currentTrack?.artiste == track.artiste ? Colors.green : Colors.grey[350], fontSize: 14)); }), const SizedBox(height: 2), if (track.number != -1) Text(track.artiste, style: TextStyle( fontWeight: FontWeight.normal, color: Colors.grey[500], fontSize: 13)) ]), ]), )), ), TableCell( child: Padding( padding: rowPadding, child: Text(track.album ?? '', style: textStyle), ), ), TableCell( child: Padding( padding: rowPadding, child: InkWell( onTap: () async { isDownloading = track.number; downloadProvider.reload(); if (track.id == null) { final secondMatch = track.artiste == '' ? track.album : track.artiste; final resultUrl = await yt.search .search(track.title + ' ' + secondMatch!); track.id = resultUrl.first.id.value; } if (track.id != null) { hp.downloadMusic(context, track); } isDownloading = -1; yt.close(); downloadProvider.reload(); }, child: track.number == -1 ? Text('TÉLÉCHARGER', style: textStyle) : Consumer(builder: (context, _, __) { return Row(children: [ const SizedBox(width: 37), isDownloading == track.number ? SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.grey[500], ), ) : Icon(Icons.download, color: Colors.grey[500]), ]); }))), ), ]); } String timeFormat(Duration d) { String dd = d.toString().split('.').first; String minutes = dd.toString().split(':')[1]; String seconds = dd.toString().split(':')[2]; return '$minutes:$seconds'; }