Slow Playback track play execution fixed

Sidebar abnormal ProgressBar size fix
Player volume slider stays at zero on fresh start fix
This commit is contained in:
Kingkor Roy Tirtho 2022-07-06 11:58:21 +06:00
parent acc939c581
commit 07f70af96d
3 changed files with 66 additions and 56 deletions

View File

@ -8,6 +8,7 @@ import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/hooks/useBreakpointValue.dart';
import 'package:spotube/hooks/useBreakpoints.dart';
import 'package:spotube/models/sideBarTiles.dart';
import 'package:spotube/provider/Auth.dart';
import 'package:spotube/provider/SpotifyRequests.dart';
class Sidebar extends HookConsumerWidget {
@ -38,6 +39,7 @@ class Sidebar extends HookConsumerWidget {
if (breakpoints.isSm) return Container();
final extended = useState(false);
final meSnapshot = ref.watch(currentUserQuery);
final auth = ref.watch(authProvider);
final int titleBarDragMaxWidth = useBreakpointValue(
md: 80,
@ -104,31 +106,38 @@ class Sidebar extends HookConsumerWidget {
),
SizedBox(
width: titleBarDragMaxWidth.toDouble(),
child: meSnapshot.when(
data: (data) {
final avatarImg = imageToUrlString(data.images,
index: (data.images?.length ?? 1) - 1);
child: Builder(
builder: (context) {
final data = meSnapshot.asData?.value;
final avatarImg = imageToUrlString(data?.images,
index: (data?.images?.length ?? 1) - 1);
if (extended.value) {
return Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
CircleAvatar(
backgroundImage:
CachedNetworkImageProvider(avatarImg),
),
const SizedBox(width: 10),
Text(
data.displayName ?? "Guest",
style: const TextStyle(
fontWeight: FontWeight.bold,
if (auth.isLoggedIn && data == null)
const Center(
child: CircularProgressIndicator(),
)
else if (data != null)
Row(
children: [
CircleAvatar(
backgroundImage:
CachedNetworkImageProvider(avatarImg),
),
),
],
),
const SizedBox(width: 10),
Text(
data.displayName ?? "Guest",
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
],
),
IconButton(
icon: const Icon(Icons.settings_outlined),
onPressed: () => goToSettings(context)),
@ -146,8 +155,6 @@ class Sidebar extends HookConsumerWidget {
);
}
},
error: (e, _) => Text("Error $e"),
loading: () => const CircularProgressIndicator(),
),
)
],

View File

@ -104,9 +104,14 @@ class Player extends HookConsumerWidget {
height: 20,
constraints: const BoxConstraints(maxWidth: 200),
child: HookBuilder(builder: (context) {
final volume = useState(
useMemoized(() => playback.volume, []),
);
final volume = useState(playback.volume);
useEffect(() {
if (volume.value != playback.volume) {
volume.value = playback.volume;
}
return null;
}, [playback.volume]);
return Slider.adaptive(
min: 0,
max: 1,

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:async/async.dart';
import 'package:audio_service/audio_service.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -123,19 +122,23 @@ class Playback extends PersistedChangeNotifier {
}
Future<void> playPlaylist(CurrentPlaylist playlist, [int index = 0]) async {
if (index < 0 || index > playlist.tracks.length - 1) return;
this.playlist = playlist;
final played = this.playlist!.tracks[index];
status = PlaybackStatus.loading;
notifyListeners();
await play(played).then((_) {
int i = this
.playlist!
.tracks
.indexWhere((element) => element.id == played.id);
if (index == -1) return;
this.playlist!.tracks[i] = track!;
});
try {
if (index < 0 || index > playlist.tracks.length - 1) return;
this.playlist = playlist;
final played = this.playlist!.tracks[index];
status = PlaybackStatus.loading;
notifyListeners();
await play(played).then((_) {
int i = this
.playlist!
.tracks
.indexWhere((element) => element.id == played.id);
if (index == -1) return;
this.playlist!.tracks[i] = track!;
});
} catch (e) {
_logger.e("[playPlaylist] $e");
}
}
// player methods
@ -228,25 +231,20 @@ class Playback extends PersistedChangeNotifier {
player.dispose();
}
Future<T> retryingOperation<T>(
Future<T> raceMultiple<T>(
Future<T> Function() inner, {
Duration? timeout,
Duration timeout = const Duration(milliseconds: 2500),
int retryCount = 4,
}) async {
T result;
try {
final operation = CancelableOperation.fromFuture(inner());
result = await operation.value;
await Future.delayed(timeout ?? const Duration(seconds: 5), () async {
if (!operation.isCompleted) {
operation.cancel();
result = await inner();
}
});
return result;
} catch (e) {
result = await inner();
return result;
}
return Future.any(
List.generate(retryCount, (i) {
if (i == 0) return inner();
return Future.delayed(
Duration(milliseconds: timeout.inMilliseconds * i),
inner,
);
}),
);
}
// playlist & track list methods
@ -283,7 +281,7 @@ class Playback extends PersistedChangeNotifier {
ytVideo = VideoFromCacheTrackExtension.fromCacheTrack(cachedTrack);
} else {
VideoSearchList videos =
await retryingOperation(() => youtube.search.search(queryString));
await raceMultiple(() => youtube.search.search(queryString));
if (matchAlgorithm != SpotubeTrackMatchAlgorithm.youtube) {
List<Map> ratedRankedVideos = videos
.map((video) {
@ -333,7 +331,7 @@ class Playback extends PersistedChangeNotifier {
}
}
StreamManifest trackManifest = await retryingOperation(
StreamManifest trackManifest = await raceMultiple(
() => youtube.videos.streams.getManifest(ytVideo.id),
);