Skip to content

Commit

Permalink
feat: user local tracks searchbar
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Jan 6, 2023
1 parent d0aaa97 commit e7f3f4e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
52 changes: 49 additions & 3 deletions lib/components/library/user_local_tracks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:collection/collection.dart';
import 'package:fuzzywuzzy/fuzzywuzzy.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:metadata_god/metadata_god.dart';
import 'package:mime/mime.dart';
Expand All @@ -15,6 +17,7 @@ import 'package:spotube/components/shared/shimmers/shimmer_track_tile.dart';
import 'package:spotube/components/shared/sort_tracks_dropdown.dart';
import 'package:spotube/components/shared/track_table/track_tile.dart';
import 'package:spotube/hooks/use_async_effect.dart';
import 'package:spotube/hooks/use_breakpoints.dart';
import 'package:spotube/models/current_playlist.dart';
import 'package:spotube/models/logger.dart';
import 'package:spotube/provider/playback_provider.dart';
Expand All @@ -24,6 +27,7 @@ import 'package:spotube/utils/primitive_utils.dart';
import 'package:spotube/utils/service_utils.dart';
import 'package:spotube/utils/type_conversion_utils.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart' show FfiException;
import 'package:tuple/tuple.dart';

const supportedAudioTypes = [
"audio/webm",
Expand Down Expand Up @@ -157,22 +161,37 @@ class UserLocalTracks extends HookConsumerWidget {
final playback = ref.watch(playbackProvider);
final isPlaylistPlaying = playback.playlist?.id == "local";
final trackSnapshot = ref.watch(localTracksProvider);
final isMounted = useIsMounted();
final breakpoint = useBreakpoints();

final searchText = useState<String>("");

useAsyncEffect(
() async {
if (!kIsMobile) return;
if (!await Permission.storage.isGranted &&
!await Permission.storage.isLimited) {
await Permission.storage.request();
ref.refresh(localTracksProvider);
if (isMounted()) ref.refresh(localTracksProvider);
}
},
null,
[],
);

var searchbar = PlatformTextField(
onChanged: (value) => searchText.value = value,
placeholder: "Search local tracks...",
prefixIcon: Icons.search_rounded,
);

return Column(
children: [
if (breakpoint <= Breakpoints.md)
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16),
child: searchbar,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
Expand Down Expand Up @@ -201,6 +220,12 @@ class UserLocalTracks extends HookConsumerWidget {
],
),
),
const SizedBox(width: 10),
if (breakpoint > Breakpoints.md)
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 300),
child: searchbar,
),
const Spacer(),
SortTracksDropdown(
value: sortBy.value,
Expand All @@ -224,11 +249,32 @@ class UserLocalTracks extends HookConsumerWidget {
return ServiceUtils.sortTracks(tracks, sortBy.value);
}, [sortBy.value, tracks]);

final filteredTracks = useMemoized(() {
return sortedTracks
.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(
"${e.name} - ${TypeConversionUtils.artists_X_String<Artist>(e.artists ?? [])}",
searchText.value,
),
e,
))
.toList()
.sorted(
(a, b) => b.item1.compareTo(a.item1),
)
.where((e) => e.item1 > 50)
.map((e) => e.item2)
.toList()
.toList();
}, [searchText.value, sortedTracks]);

return Expanded(
child: ListView.builder(
itemCount: sortedTracks.length,
itemCount: filteredTracks.length,
itemBuilder: (context, index) {
final track = sortedTracks[index];
final track = filteredTracks[index];
return TrackTile(
playback,
duration:
Expand Down
4 changes: 2 additions & 2 deletions lib/components/shared/track_table/track_collection_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ class TrackCollectionView<T> extends HookConsumerWidget {

final filteredTracks = useMemoized(() {
return tracksSnapshot.data
?.mapIndexed((i, e) => Tuple2(
?.map((e) => Tuple2(
searchText.value.isEmpty
? 100
: weightedRatio(
"${e.name} - ${TypeConversionUtils.artists_X_String<Artist>(e.artists ?? [])}",
searchText.value,
),
e..discNumber = i,
e,
))
.toList()
.sorted(
Expand Down

0 comments on commit e7f3f4e

Please sign in to comment.