mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-15 16:45:17 +00:00
feat: show loading indicator on play track
This commit is contained in:
parent
1540999f50
commit
d12ea48b97
@ -131,7 +131,7 @@ final localTracksProvider = FutureProvider<List<LocalTrack>>((ref) async {
|
||||
class UserLocalTracks extends HookConsumerWidget {
|
||||
const UserLocalTracks({Key? key}) : super(key: key);
|
||||
|
||||
void playLocalTracks(
|
||||
Future<void> playLocalTracks(
|
||||
WidgetRef ref,
|
||||
List<LocalTrack> tracks, {
|
||||
LocalTrack? currentTrack,
|
||||
@ -203,10 +203,10 @@ class UserLocalTracks extends HookConsumerWidget {
|
||||
const SizedBox(width: 10),
|
||||
FilledButton(
|
||||
onPressed: trackSnapshot.value != null
|
||||
? () {
|
||||
? () async {
|
||||
if (trackSnapshot.value?.isNotEmpty == true) {
|
||||
if (!isPlaylistPlaying) {
|
||||
playLocalTracks(
|
||||
await playLocalTracks(
|
||||
ref,
|
||||
trackSnapshot.value!,
|
||||
);
|
||||
@ -295,8 +295,8 @@ class UserLocalTracks extends HookConsumerWidget {
|
||||
index: index,
|
||||
track: track,
|
||||
userPlaylist: false,
|
||||
onTap: () {
|
||||
playLocalTracks(
|
||||
onTap: () async {
|
||||
await playLocalTracks(
|
||||
ref,
|
||||
sortedTracks,
|
||||
currentTrack: track,
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fl_query/fl_query.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@ -27,7 +29,7 @@ class TrackCollectionView<T> extends HookConsumerWidget {
|
||||
final Query<List<TrackSimple>, T> tracksSnapshot;
|
||||
final String titleImage;
|
||||
final PlayButtonState playingState;
|
||||
final void Function([Track? currentTrack]) onPlay;
|
||||
final Future<void> Function([Track? currentTrack]) onPlay;
|
||||
final void Function([Track? currentTrack]) onShuffledPlay;
|
||||
final void Function() onAddToQueue;
|
||||
final void Function() onShare;
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@ -21,7 +23,7 @@ class TrackTile extends HookConsumerWidget {
|
||||
final Track track;
|
||||
final bool selected;
|
||||
final ValueChanged<bool?>? onChanged;
|
||||
final VoidCallback? onTap;
|
||||
final Future<void> Function()? onTap;
|
||||
final VoidCallback? onLongPress;
|
||||
final bool userPlaylist;
|
||||
final String? playlistId;
|
||||
@ -62,6 +64,10 @@ class TrackTile extends HookConsumerWidget {
|
||||
|
||||
final isPlaying = track.id == playlist.activeTrack?.id;
|
||||
|
||||
final isLoading = useState(false);
|
||||
|
||||
final isSelected = isPlaying || isLoading.value;
|
||||
|
||||
return LayoutBuilder(builder: (context, constrains) {
|
||||
return Listener(
|
||||
onPointerDown: (event) {
|
||||
@ -76,11 +82,18 @@ class TrackTile extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
child: HoverBuilder(
|
||||
permanentState: isPlaying || constrains.smAndDown ? true : null,
|
||||
permanentState: isSelected || constrains.smAndDown ? true : null,
|
||||
builder: (context, isHovering) {
|
||||
return ListTile(
|
||||
selected: isPlaying,
|
||||
onTap: onTap,
|
||||
selected: isSelected,
|
||||
onTap: () async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
await onTap?.call();
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
},
|
||||
onLongPress: onLongPress,
|
||||
enabled: !isBlackListed,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
@ -145,22 +158,23 @@ class TrackTile extends HookConsumerWidget {
|
||||
.copyWith(size: 26, color: Colors.white),
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: !isHovering
|
||||
? const SizedBox.shrink()
|
||||
: isPlaying && playlist.isFetching
|
||||
? const SizedBox(
|
||||
width: 26,
|
||||
height: 26,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 1.5,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: (isPlaying && playlist.isFetching) ||
|
||||
isLoading.value
|
||||
? const SizedBox(
|
||||
width: 26,
|
||||
height: 26,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 1.5,
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
: isPlaying
|
||||
? Icon(
|
||||
SpotubeIcons.pause,
|
||||
color: theme.colorScheme.primary,
|
||||
)
|
||||
: isPlaying
|
||||
? Icon(
|
||||
SpotubeIcons.pause,
|
||||
color: theme.colorScheme.primary,
|
||||
)
|
||||
: !isHovering
|
||||
? const SizedBox.shrink()
|
||||
: const Icon(SpotubeIcons.play),
|
||||
),
|
||||
),
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@ -27,7 +29,7 @@ final trackCollectionSortState =
|
||||
StateProvider.family<SortBy, String>((ref, _) => SortBy.none);
|
||||
|
||||
class TracksTableView extends HookConsumerWidget {
|
||||
final void Function(Track currentTrack)? onTrackPlayButtonPressed;
|
||||
final Future<void> Function(Track currentTrack)? onTrackPlayButtonPressed;
|
||||
final List<Track> tracks;
|
||||
final bool userPlaylist;
|
||||
final String? playlistId;
|
||||
@ -58,8 +60,7 @@ class TracksTableView extends HookConsumerWidget {
|
||||
final downloader = ref.watch(downloadManagerProvider.notifier);
|
||||
final apiType =
|
||||
ref.watch(userPreferencesProvider.select((s) => s.youtubeApiType));
|
||||
final tableHeadStyle =
|
||||
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||
const tableHeadStyle = TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||
|
||||
final selected = useState<List<String>>([]);
|
||||
final showCheck = useState<bool>(false);
|
||||
@ -297,7 +298,7 @@ class TracksTableView extends HookConsumerWidget {
|
||||
selected: selected.value.contains(track.id),
|
||||
userPlaylist: userPlaylist,
|
||||
playlistId: playlistId,
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
if (showCheck.value) {
|
||||
final alreadyChecked = selected.value.contains(track.id);
|
||||
if (alreadyChecked) {
|
||||
@ -314,9 +315,8 @@ class TracksTableView extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
);
|
||||
if (!isBlackListed) {
|
||||
onTrackPlayButtonPressed?.call(track);
|
||||
}
|
||||
if (isBlackListed) return;
|
||||
await onTrackPlayButtonPressed?.call(track);
|
||||
}
|
||||
},
|
||||
onLongPress: () {
|
||||
|
@ -85,10 +85,10 @@ class AlbumPage extends HookConsumerWidget {
|
||||
album: album,
|
||||
routePath: "/album/${album.id}",
|
||||
bottomSpace: mediaQuery.mdAndDown,
|
||||
onPlay: ([track]) {
|
||||
onPlay: ([track]) async {
|
||||
if (tracksSnapshot.hasData) {
|
||||
if (!isAlbumPlaying) {
|
||||
playPlaylist(
|
||||
await playPlaylist(
|
||||
tracksSnapshot.data!
|
||||
.map((track) =>
|
||||
TypeConversionUtils.simpleTrack_X_Track(track, album))
|
||||
@ -96,7 +96,7 @@ class AlbumPage extends HookConsumerWidget {
|
||||
ref,
|
||||
);
|
||||
} else if (isAlbumPlaying && track != null) {
|
||||
playPlaylist(
|
||||
await playPlaylist(
|
||||
tracksSnapshot.data!
|
||||
.map((track) =>
|
||||
TypeConversionUtils.simpleTrack_X_Track(track, album))
|
||||
@ -105,7 +105,7 @@ class AlbumPage extends HookConsumerWidget {
|
||||
ref,
|
||||
);
|
||||
} else {
|
||||
playback
|
||||
await playback
|
||||
.removeTracks(tracksSnapshot.data!.map((track) => track.id!));
|
||||
}
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ class ArtistPage extends HookConsumerWidget {
|
||||
return TrackTile(
|
||||
index: i,
|
||||
track: track,
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
playPlaylist(
|
||||
topTracks.toList(),
|
||||
currentTrack: track,
|
||||
|
@ -104,22 +104,16 @@ class PlaylistView extends HookConsumerWidget {
|
||||
tracksSnapshot: tracksSnapshot,
|
||||
description: playlist.description,
|
||||
isOwned: ownPlaylist,
|
||||
onPlay: ([track]) {
|
||||
onPlay: ([track]) async {
|
||||
if (tracksSnapshot.hasData) {
|
||||
if (!isPlaylistPlaying) {
|
||||
playPlaylist(
|
||||
tracksSnapshot.data!,
|
||||
ref,
|
||||
currentTrack: track,
|
||||
);
|
||||
} else if (isPlaylistPlaying && track != null) {
|
||||
playPlaylist(
|
||||
if (!isPlaylistPlaying || (isPlaylistPlaying && track != null)) {
|
||||
await playPlaylist(
|
||||
tracksSnapshot.data!,
|
||||
ref,
|
||||
currentTrack: track,
|
||||
);
|
||||
} else {
|
||||
playlistNotifier
|
||||
await playlistNotifier
|
||||
.removeTracks(tracksSnapshot.data!.map((e) => e.id!));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user