nkbmusic/lib/data/user_library.dart
metatroncubeswdev 178d2d00ab Nanga Kathai: Flutter app, self-hosted backend and song tools
- Flutter app (Android/iOS): home, explore, albums, search, player with
  equalizer, mini player, sign up/sign in with email codes, profile,
  encrypted offline downloads, About page
- server/: one-command deploy of self-hosted Supabase behind HestiaCP/nginx
  (or Caddy), migrations, backups, email templates
- supabase/migrations: schema, row-level security, profiles
- tools/: song scanner and importer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:39:26 -04:00

49 lines
1.6 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../audio/player_providers.dart';
/// Overridden in main() once SharedPreferences has loaded.
final sharedPrefsProvider = Provider<SharedPreferences>(
(ref) => throw UnimplementedError('sharedPrefsProvider must be overridden in main()'),
);
/// Liked song ids, stored on the device. Synced to Supabase once sign-in is wired up.
class LikedSongs extends Notifier<Set<String>> {
static const _key = 'liked_track_ids';
@override
Set<String> build() => {...?ref.watch(sharedPrefsProvider).getStringList(_key)};
bool isLiked(String id) => state.contains(id);
void toggle(String id) {
state = state.contains(id) ? ({...state}..remove(id)) : {...state, id};
ref.read(sharedPrefsProvider).setStringList(_key, state.toList());
}
}
final likedSongsProvider = NotifierProvider<LikedSongs, Set<String>>(LikedSongs.new);
/// Most recent first, capped at 30.
class RecentlyPlayed extends Notifier<List<String>> {
static const _key = 'recent_track_ids';
static const _max = 30;
@override
List<String> build() {
ref.listen(mediaItemProvider, (_, next) {
final id = next.value?.id;
if (id != null && (state.isEmpty || state.first != id)) _push(id);
});
return ref.watch(sharedPrefsProvider).getStringList(_key) ?? const [];
}
void _push(String id) {
state = [id, ...state.where((e) => e != id)].take(_max).toList();
ref.read(sharedPrefsProvider).setStringList(_key, state);
}
}
final recentlyPlayedProvider = NotifierProvider<RecentlyPlayed, List<String>>(RecentlyPlayed.new);