Imrove startup; Fix layouts; Add time slider;
This commit is contained in:
parent
9fefb780d1
commit
6e39b5435a
|
@ -25,6 +25,7 @@ class FipyApp extends StatelessWidget {
|
|||
providers: [
|
||||
ChangeNotifierProvider(create: (_) => PlayerProvider()),
|
||||
ChangeNotifierProvider(create: (_) => HomeProvider()),
|
||||
ChangeNotifierProvider(create: (_) => DownloadProvider()),
|
||||
],
|
||||
child: MaterialApp(
|
||||
title: 'Fipy',
|
||||
|
|
|
@ -5,3 +5,9 @@ class HomeProvider with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
class DownloadProvider with ChangeNotifier {
|
||||
void reload() {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ PlayerController? player;
|
|||
Track? currentTrack;
|
||||
List<Track> trackList = [];
|
||||
String radio = 'groove';
|
||||
int isDownloading = -1;
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
const HomeScreen({Key? key, required this.title}) : super(key: key);
|
||||
|
@ -51,7 +52,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
onChanged: (String? newRadio) {
|
||||
setState(() {
|
||||
radio = newRadio!;
|
||||
getTracks(radio, hours);
|
||||
// getTracks(radio, hours);
|
||||
});
|
||||
},
|
||||
items: radioList),
|
||||
|
@ -89,6 +90,11 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
return const Text('Error');
|
||||
} 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!
|
||||
|
@ -180,16 +186,24 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
),
|
||||
]),
|
||||
),
|
||||
Column(children: [
|
||||
const Spacer(),
|
||||
Row(children: [
|
||||
Column(children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.skip_previous,
|
||||
color: Colors.grey[500], size: 32),
|
||||
onPressed: () {
|
||||
if (currentTrack != null && currentTrack!.number > 1) {
|
||||
if (currentTrack != null &&
|
||||
currentTrack!.number > 1) {
|
||||
currentTrack = trackList.firstWhere((element) =>
|
||||
element.number == currentTrack!.number - 1);
|
||||
playTrack(context, currentTrack!);
|
||||
}
|
||||
}),
|
||||
const SizedBox(height: 7),
|
||||
]),
|
||||
const SizedBox(width: 8),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
player?.playing ?? false
|
||||
|
@ -202,7 +216,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
? Icons.pause
|
||||
: Icons.play_arrow,
|
||||
color: Colors.grey[900],
|
||||
size: 32),
|
||||
size: 30),
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: const CircleBorder(),
|
||||
padding: const EdgeInsets.all(12),
|
||||
|
@ -210,17 +224,68 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
onPrimary: Colors.grey[900],
|
||||
),
|
||||
),
|
||||
Column(children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.skip_next,
|
||||
color: Colors.grey[500], size: 32),
|
||||
onPressed: () {
|
||||
if (currentTrack != null &&
|
||||
currentTrack!.number < trackList.last.number) {
|
||||
currentTrack!.number <
|
||||
trackList.last.number) {
|
||||
currentTrack = trackList.firstWhere((element) =>
|
||||
element.number == currentTrack!.number + 1);
|
||||
playTrack(context, currentTrack!);
|
||||
}
|
||||
}),
|
||||
const SizedBox(height: 7),
|
||||
]),
|
||||
]),
|
||||
const Spacer(),
|
||||
Row(children: [
|
||||
Text(
|
||||
timeFormat(
|
||||
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(
|
||||
player?.position.inSeconds.toString() ?? '0'),
|
||||
max: double.parse(
|
||||
player?.duration.inSeconds.toString() ??
|
||||
'2000'),
|
||||
onChanged: (double value) {
|
||||
print(value);
|
||||
if (player?.position != null) {
|
||||
player!.position =
|
||||
Duration(seconds: value.toInt());
|
||||
playerProvider.reload();
|
||||
}
|
||||
},
|
||||
activeColor: Colors.grey[400],
|
||||
inactiveColor: Colors.grey[700],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Text(
|
||||
timeFormat(
|
||||
player?.duration ?? const Duration(seconds: 0)),
|
||||
style: TextStyle(color: Colors.grey[500], fontSize: 12),
|
||||
),
|
||||
]),
|
||||
const Spacer(),
|
||||
]),
|
||||
const Spacer(),
|
||||
SliderTheme(
|
||||
data: const SliderThemeData(
|
||||
|
@ -339,8 +404,8 @@ Future<List<Track>> getTracks(String radio, int hours) async {
|
|||
int trackNbr = 0;
|
||||
|
||||
trackList.clear();
|
||||
final yt = YoutubeExplode();
|
||||
List resultUrlPool = [];
|
||||
// final yt = YoutubeExplode();
|
||||
// List resultUrlPool = [];
|
||||
|
||||
for (Map track in data) {
|
||||
track = track['track'];
|
||||
|
@ -358,36 +423,39 @@ Future<List<Track>> getTracks(String radio, int hours) async {
|
|||
Track(number: trackNbr, title: title, artiste: artiste, album: album);
|
||||
trackList.add(thisTrack);
|
||||
|
||||
final secondMatch = artiste == '' ? album : artiste;
|
||||
final resultUrl = yt.search.search(title + ' ' + secondMatch);
|
||||
// final secondMatch = artiste == '' ? album : artiste;
|
||||
// final resultUrl = yt.search.search(title + ' ' + secondMatch);
|
||||
|
||||
resultUrlPool.add(resultUrl);
|
||||
// resultUrlPool.add(resultUrl);
|
||||
|
||||
resultUrl.then((value) {
|
||||
try {
|
||||
trackList[trackNbr - 1].id = value.first.id.value;
|
||||
} catch (e) {
|
||||
print(
|
||||
'Error: ' + trackList[trackNbr - 1].title + ' -> ' + e.toString());
|
||||
}
|
||||
});
|
||||
// resultUrl.then((value) {
|
||||
// try {
|
||||
// trackList[trackNbr - 1].id = value.first.id.value;
|
||||
// } catch (e) {
|
||||
// print(
|
||||
// 'Error: ' + trackList[trackNbr - 1].title + ' -> ' + e.toString());
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
trackList.sort((a, b) => a.number.compareTo(b.number));
|
||||
// trackList.sort((a, b) => a.number.compareTo(b.number));
|
||||
|
||||
final secondMatch =
|
||||
trackList[0].artiste == '' ? trackList[0].album : trackList[0].artiste;
|
||||
yt.search.search(trackList[0].title + ' ' + secondMatch!).then((resultUrl) {
|
||||
trackList[0].id = resultUrl.first.id.value;
|
||||
// final secondMatch =
|
||||
// trackList[0].artiste == '' ? trackList[0].album : trackList[0].artiste;
|
||||
// yt.search.search(trackList[0].title + ' ' + secondMatch!).then((resultUrl) {
|
||||
// trackList[0].id = resultUrl.first.id.value;
|
||||
|
||||
player = Player.network(
|
||||
"https://invidious.fdn.fr/embed/${trackList[0].id}?raw=1&?listen=1");
|
||||
currentTrack = trackList[0];
|
||||
});
|
||||
// player = Player.network(
|
||||
// "https://invidious.fdn.fr/embed/${trackList[0].id}?raw=1&?listen=1");
|
||||
// currentTrack = trackList[0];
|
||||
// });
|
||||
return trackList;
|
||||
}
|
||||
|
||||
TableRow _buildTableRow(Track track, BuildContext context) {
|
||||
DownloadProvider downloadProvider =
|
||||
Provider.of<DownloadProvider>(context, listen: false);
|
||||
|
||||
final textStyle = TextStyle(
|
||||
fontWeight: track.number == -1 ? FontWeight.w200 : FontWeight.normal,
|
||||
color: Colors.grey[500],
|
||||
|
@ -443,6 +511,8 @@ TableRow _buildTableRow(Track track, BuildContext context) {
|
|||
padding: rowPadding,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
isDownloading = track.number;
|
||||
downloadProvider.reload();
|
||||
if (track.id == null) {
|
||||
final secondMatch =
|
||||
track.artiste == '' ? track.album : track.artiste;
|
||||
|
@ -458,9 +528,27 @@ TableRow _buildTableRow(Track track, BuildContext context) {
|
|||
launchUrl(Uri.parse(dlLink));
|
||||
}
|
||||
}
|
||||
isDownloading = -1;
|
||||
downloadProvider.reload();
|
||||
},
|
||||
child: Text('TÉLÉCHARGER', style: textStyle),
|
||||
)),
|
||||
child: track.number == -1
|
||||
? Text('TÉLÉCHARGER', style: textStyle)
|
||||
: Consumer<DownloadProvider>(
|
||||
builder: (context, playerProvider, _) {
|
||||
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]),
|
||||
]);
|
||||
}))),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
@ -472,32 +560,38 @@ Future playTrack(BuildContext context, Track track) async {
|
|||
HomeProvider homeProvider = Provider.of<HomeProvider>(context, listen: false);
|
||||
|
||||
track = trackList[track.number - 1];
|
||||
currentTrack = track;
|
||||
|
||||
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;
|
||||
}
|
||||
final currentVolume = player?.volume ?? 1;
|
||||
player?.dispose();
|
||||
Future.delayed(const Duration(milliseconds: 5));
|
||||
player = Player.network(
|
||||
"https://invidious.fdn.fr/embed/${track.id}?raw=1&?listen=1");
|
||||
print(track.id);
|
||||
player!.volume = currentVolume;
|
||||
|
||||
try {
|
||||
player!.play();
|
||||
} catch (e) {
|
||||
print('Play error: ' + e.toString());
|
||||
}
|
||||
Future.delayed(const Duration(milliseconds: 50));
|
||||
Future.delayed(const Duration(milliseconds: 500));
|
||||
player!.callback = (PlayerEvent event) {
|
||||
if (event.name == 'position') {
|
||||
currentTrack!.duration = player!.duration;
|
||||
playerProvider.reload();
|
||||
}
|
||||
if (event.name == 'status') {
|
||||
var nextTrack =
|
||||
trackList.firstWhere((element) => element.number == track.number + 1);
|
||||
playTrack(context, nextTrack);
|
||||
}
|
||||
};
|
||||
currentTrack = track;
|
||||
playerProvider.reload();
|
||||
homeProvider.reload();
|
||||
}
|
||||
|
@ -528,3 +622,10 @@ List<DropdownMenuItem<String>> get radioList {
|
|||
];
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue