mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
120 lines
4.5 KiB
Dart
120 lines
4.5 KiB
Dart
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
|
import 'package:skeletonizer/skeletonizer.dart';
|
|
import 'package:spotube/collections/fake.dart';
|
|
import 'package:spotube/components/dialogs/prompt_dialog.dart';
|
|
import 'package:spotube/components/dialogs/select_device_dialog.dart';
|
|
import 'package:spotube/components/track_tile/track_tile.dart';
|
|
import 'package:spotube/extensions/context.dart';
|
|
import 'package:spotube/models/connect/connect.dart';
|
|
import 'package:spotube/modules/search/loading.dart';
|
|
import 'package:spotube/pages/search/search.dart';
|
|
import 'package:spotube/provider/audio_player/audio_player.dart';
|
|
import 'package:spotube/provider/connect/connect.dart';
|
|
import 'package:spotube/provider/metadata_plugin/search/tracks.dart';
|
|
import 'package:spotube/provider/metadata_plugin/utils/common.dart';
|
|
import 'package:very_good_infinite_list/very_good_infinite_list.dart';
|
|
|
|
class SearchPageTracksTab extends HookConsumerWidget {
|
|
const SearchPageTracksTab({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, ref) {
|
|
final searchTerm = ref.watch(searchTermStateProvider);
|
|
final searchTracksSnapshot =
|
|
ref.watch(metadataPluginSearchTracksProvider(searchTerm));
|
|
final searchTracksNotifier =
|
|
ref.read(metadataPluginSearchTracksProvider(searchTerm).notifier);
|
|
final searchTracks =
|
|
searchTracksSnapshot.asData?.value.items ?? [FakeData.track];
|
|
|
|
final playlist = ref.watch(audioPlayerProvider);
|
|
final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
|
|
|
|
return SearchPlaceholder(
|
|
snapshot: searchTracksSnapshot,
|
|
child: InfiniteList(
|
|
itemCount: searchTracksSnapshot.asData?.value.items.length ?? 0,
|
|
hasReachedMax: searchTracksSnapshot.asData?.value.hasMore != true,
|
|
isLoading: searchTracksSnapshot.isLoading &&
|
|
!searchTracksSnapshot.isLoadingNextPage,
|
|
loadingBuilder: (context) {
|
|
return Skeletonizer(
|
|
enabled: true,
|
|
child: TrackTile(track: FakeData.track, playlist: playlist),
|
|
);
|
|
},
|
|
onFetchData: () {
|
|
searchTracksNotifier.fetchMore();
|
|
},
|
|
itemBuilder: (context, index) {
|
|
final track = searchTracks[index];
|
|
|
|
return TrackTile(
|
|
track: track,
|
|
playlist: playlist,
|
|
index: index,
|
|
onTap: () async {
|
|
final isRemoteDevice = await showSelectDeviceDialog(context, ref);
|
|
|
|
if (isRemoteDevice == null) return;
|
|
|
|
if (isRemoteDevice) {
|
|
final remotePlayback = ref.read(connectProvider.notifier);
|
|
final remotePlaylist = ref.read(queueProvider);
|
|
|
|
final isTrackPlaying =
|
|
remotePlaylist.activeTrack?.id == track.id;
|
|
|
|
if (!isTrackPlaying && context.mounted) {
|
|
final shouldPlay = (playlist.tracks.length) > 20
|
|
? await showPromptDialog(
|
|
context: context,
|
|
title: context.l10n.playing_track(
|
|
track.name,
|
|
),
|
|
message: context.l10n.queue_clear_alert(
|
|
playlist.tracks.length,
|
|
),
|
|
)
|
|
: true;
|
|
|
|
if (shouldPlay) {
|
|
await remotePlayback.load(
|
|
WebSocketLoadEventData.playlist(
|
|
tracks: [track],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
final isTrackPlaying = playlist.activeTrack?.id == track.id;
|
|
if (!isTrackPlaying && context.mounted) {
|
|
final shouldPlay = (playlist.tracks.length) > 20
|
|
? await showPromptDialog(
|
|
context: context,
|
|
title: context.l10n.playing_track(
|
|
track.name,
|
|
),
|
|
message: context.l10n.queue_clear_alert(
|
|
playlist.tracks.length,
|
|
),
|
|
)
|
|
: true;
|
|
|
|
if (shouldPlay) {
|
|
await playlistNotifier.load(
|
|
[track],
|
|
autoPlay: true,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|