mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 15:02:42 +01:00
v2
This commit is contained in:
143
lib/state/audio.dart
Normal file
143
lib/state/audio.dart
Normal file
@@ -0,0 +1,143 @@
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:drift/drift.dart' show Value;
|
||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../database/database.dart';
|
||||
import '../models/music.dart';
|
||||
import '../models/support.dart';
|
||||
import '../services/audio_service.dart';
|
||||
import 'settings.dart';
|
||||
|
||||
part 'audio.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<MediaItem?> mediaItem(MediaItemRef ref) async* {
|
||||
final audio = ref.watch(audioControlProvider);
|
||||
await for (var item in audio.mediaItem) {
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
MediaItemData? mediaItemData(MediaItemDataRef ref) {
|
||||
return ref.watch(mediaItemProvider.select(
|
||||
(value) => value.valueOrNull?.data,
|
||||
));
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<Song?> mediaItemSong(MediaItemSongRef ref) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
final id = ref.watch(mediaItemProvider.select(
|
||||
(value) => value.valueOrNull?.id,
|
||||
));
|
||||
|
||||
return db.songById(sourceId, id ?? '').watchSingleOrNull();
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<PlaybackState> playbackState(PlaybackStateRef ref) async* {
|
||||
final audio = ref.watch(audioControlProvider);
|
||||
await for (var state in audio.playbackState) {
|
||||
yield state;
|
||||
}
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<QueueMode> queueMode(QueueModeRef ref) async* {
|
||||
final audio = ref.watch(audioControlProvider);
|
||||
await for (var state in audio.queueMode) {
|
||||
yield state;
|
||||
}
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<List<MediaItem>> queue(QueueRef ref) async* {
|
||||
final audio = ref.watch(audioControlProvider);
|
||||
await for (var queue in audio.queue) {
|
||||
yield queue;
|
||||
}
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<List<int>?> shuffleIndicies(ShuffleIndiciesRef ref) async* {
|
||||
final audio = ref.watch(audioControlProvider);
|
||||
await for (var indicies in audio.shuffleIndicies) {
|
||||
yield indicies;
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<Duration> positionStream(PositionStreamRef ref) async* {
|
||||
final audio = ref.watch(audioControlProvider);
|
||||
await for (var state in audio.position) {
|
||||
yield state;
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
bool playing(PlayingRef ref) {
|
||||
return ref.watch(playbackStateProvider.select(
|
||||
(value) => value.valueOrNull?.playing ?? false,
|
||||
));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
AudioProcessingState? processingState(ProcessingStateRef ref) {
|
||||
return ref.watch(playbackStateProvider.select(
|
||||
(value) => value.valueOrNull?.processingState,
|
||||
));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
int position(PositionRef ref) {
|
||||
return ref.watch(positionStreamProvider.select(
|
||||
(value) => value.valueOrNull?.inSeconds ?? 0,
|
||||
));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
int duration(DurationRef ref) {
|
||||
return ref.watch(mediaItemProvider.select(
|
||||
(value) => value.valueOrNull?.duration?.inSeconds ?? 0,
|
||||
));
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
AudioServiceShuffleMode? shuffleMode(ShuffleModeRef ref) {
|
||||
return ref.watch(playbackStateProvider.select(
|
||||
(value) => value.valueOrNull?.shuffleMode,
|
||||
));
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
AudioServiceRepeatMode repeatMode(RepeatModeRef ref) {
|
||||
return ref.watch(playbackStateProvider.select(
|
||||
(value) => value.valueOrNull?.repeatMode ?? AudioServiceRepeatMode.none,
|
||||
));
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class LastAudioStateService extends _$LastAudioStateService {
|
||||
@override
|
||||
Future<void> build() async {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final queueMode = ref.watch(queueModeProvider).valueOrNull;
|
||||
final shuffleIndicies = ref.watch(shuffleIndiciesProvider).valueOrNull;
|
||||
final repeat = ref.watch(repeatModeProvider);
|
||||
|
||||
await db.saveLastAudioState(LastAudioStateCompanion.insert(
|
||||
id: const Value(1),
|
||||
queueMode: queueMode ?? QueueMode.user,
|
||||
shuffleIndicies: Value(shuffleIndicies?.lock),
|
||||
repeat: {
|
||||
AudioServiceRepeatMode.none: RepeatMode.none,
|
||||
AudioServiceRepeatMode.all: RepeatMode.all,
|
||||
AudioServiceRepeatMode.group: RepeatMode.all,
|
||||
AudioServiceRepeatMode.one: RepeatMode.one,
|
||||
}[repeat]!,
|
||||
));
|
||||
}
|
||||
}
|
||||
229
lib/state/audio.g.dart
Normal file
229
lib/state/audio.g.dart
Normal file
@@ -0,0 +1,229 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'audio.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$mediaItemHash() => r'ca8b6768872f17355f756c95cf85278127b59444';
|
||||
|
||||
/// See also [mediaItem].
|
||||
@ProviderFor(mediaItem)
|
||||
final mediaItemProvider = StreamProvider<MediaItem?>.internal(
|
||||
mediaItem,
|
||||
name: r'mediaItemProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$mediaItemHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MediaItemRef = StreamProviderRef<MediaItem?>;
|
||||
String _$mediaItemDataHash() => r'8539c02682f0d33b584ea0437dd3774d9f321a2e';
|
||||
|
||||
/// See also [mediaItemData].
|
||||
@ProviderFor(mediaItemData)
|
||||
final mediaItemDataProvider = Provider<MediaItemData?>.internal(
|
||||
mediaItemData,
|
||||
name: r'mediaItemDataProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$mediaItemDataHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MediaItemDataRef = ProviderRef<MediaItemData?>;
|
||||
String _$mediaItemSongHash() => r'274f43470cd993f0a2bed3d3da22d7bd41b562f1';
|
||||
|
||||
/// See also [mediaItemSong].
|
||||
@ProviderFor(mediaItemSong)
|
||||
final mediaItemSongProvider = StreamProvider<Song?>.internal(
|
||||
mediaItemSong,
|
||||
name: r'mediaItemSongProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$mediaItemSongHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MediaItemSongRef = StreamProviderRef<Song?>;
|
||||
String _$playbackStateHash() => r'b4a9eb7f802fc8c92666c1318f789865140d6025';
|
||||
|
||||
/// See also [playbackState].
|
||||
@ProviderFor(playbackState)
|
||||
final playbackStateProvider = StreamProvider<PlaybackState>.internal(
|
||||
playbackState,
|
||||
name: r'playbackStateProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$playbackStateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PlaybackStateRef = StreamProviderRef<PlaybackState>;
|
||||
String _$queueModeHash() => r'be0b1ff436c367e9be54c6d15fd8bac4f904fdec';
|
||||
|
||||
/// See also [queueMode].
|
||||
@ProviderFor(queueMode)
|
||||
final queueModeProvider = StreamProvider<QueueMode>.internal(
|
||||
queueMode,
|
||||
name: r'queueModeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$queueModeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef QueueModeRef = StreamProviderRef<QueueMode>;
|
||||
String _$queueHash() => r'94d86c99382f56193a11baf3f13354eab6a39fa8';
|
||||
|
||||
/// See also [queue].
|
||||
@ProviderFor(queue)
|
||||
final queueProvider = StreamProvider<List<MediaItem>>.internal(
|
||||
queue,
|
||||
name: r'queueProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$queueHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef QueueRef = StreamProviderRef<List<MediaItem>>;
|
||||
String _$shuffleIndiciesHash() => r'e5dc6879b2a7b7a501b58aace717ff36eff59995';
|
||||
|
||||
/// See also [shuffleIndicies].
|
||||
@ProviderFor(shuffleIndicies)
|
||||
final shuffleIndiciesProvider = StreamProvider<List<int>?>.internal(
|
||||
shuffleIndicies,
|
||||
name: r'shuffleIndiciesProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$shuffleIndiciesHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef ShuffleIndiciesRef = StreamProviderRef<List<int>?>;
|
||||
String _$positionStreamHash() => r'5f1dc9d11e1bcce649ddb764525cc0dc79bfb6d8';
|
||||
|
||||
/// See also [positionStream].
|
||||
@ProviderFor(positionStream)
|
||||
final positionStreamProvider = AutoDisposeStreamProvider<Duration>.internal(
|
||||
positionStream,
|
||||
name: r'positionStreamProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$positionStreamHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PositionStreamRef = AutoDisposeStreamProviderRef<Duration>;
|
||||
String _$playingHash() => r'2a40fa275358918b243c8734bbe49bc9d7373f10';
|
||||
|
||||
/// See also [playing].
|
||||
@ProviderFor(playing)
|
||||
final playingProvider = AutoDisposeProvider<bool>.internal(
|
||||
playing,
|
||||
name: r'playingProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$playingHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PlayingRef = AutoDisposeProviderRef<bool>;
|
||||
String _$processingStateHash() => r'b9e59927b905384a0f1221b2adb9b681091c27d1';
|
||||
|
||||
/// See also [processingState].
|
||||
@ProviderFor(processingState)
|
||||
final processingStateProvider =
|
||||
AutoDisposeProvider<AudioProcessingState?>.internal(
|
||||
processingState,
|
||||
name: r'processingStateProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$processingStateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef ProcessingStateRef = AutoDisposeProviderRef<AudioProcessingState?>;
|
||||
String _$positionHash() => r'bfc853fe9e46bf79522fa41374763a7e1c12e739';
|
||||
|
||||
/// See also [position].
|
||||
@ProviderFor(position)
|
||||
final positionProvider = AutoDisposeProvider<int>.internal(
|
||||
position,
|
||||
name: r'positionProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$positionHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PositionRef = AutoDisposeProviderRef<int>;
|
||||
String _$durationHash() => r'bf9eb316b8401401e5862384deb1a4c1134e6dd2';
|
||||
|
||||
/// See also [duration].
|
||||
@ProviderFor(duration)
|
||||
final durationProvider = AutoDisposeProvider<int>.internal(
|
||||
duration,
|
||||
name: r'durationProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$durationHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef DurationRef = AutoDisposeProviderRef<int>;
|
||||
String _$shuffleModeHash() => r'fd26d81cb9bd5e0e1a7e9ccf1589c104d9a4eb3a';
|
||||
|
||||
/// See also [shuffleMode].
|
||||
@ProviderFor(shuffleMode)
|
||||
final shuffleModeProvider = Provider<AudioServiceShuffleMode?>.internal(
|
||||
shuffleMode,
|
||||
name: r'shuffleModeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$shuffleModeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef ShuffleModeRef = ProviderRef<AudioServiceShuffleMode?>;
|
||||
String _$repeatModeHash() => r'346248bf08df65f1f69e4cb4b6ef192190d2910c';
|
||||
|
||||
/// See also [repeatMode].
|
||||
@ProviderFor(repeatMode)
|
||||
final repeatModeProvider = Provider<AudioServiceRepeatMode>.internal(
|
||||
repeatMode,
|
||||
name: r'repeatModeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$repeatModeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef RepeatModeRef = ProviderRef<AudioServiceRepeatMode>;
|
||||
String _$lastAudioStateServiceHash() =>
|
||||
r'4291b8d4a399f1b192277a3e8a93fbe7096fea32';
|
||||
|
||||
/// See also [LastAudioStateService].
|
||||
@ProviderFor(LastAudioStateService)
|
||||
final lastAudioStateServiceProvider =
|
||||
AsyncNotifierProvider<LastAudioStateService, void>.internal(
|
||||
LastAudioStateService.new,
|
||||
name: r'lastAudioStateServiceProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$lastAudioStateServiceHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$LastAudioStateService = AsyncNotifier<void>;
|
||||
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
||||
82
lib/state/init.dart
Normal file
82
lib/state/init.dart
Normal file
@@ -0,0 +1,82 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../app/app.dart';
|
||||
import '../app/app_router.dart';
|
||||
import '../app/pages/bottom_nav_page.dart';
|
||||
import '../app/pages/library_page.dart';
|
||||
import '../services/audio_service.dart';
|
||||
import '../services/download_service.dart';
|
||||
import '../services/settings_service.dart';
|
||||
import 'audio.dart';
|
||||
import 'settings.dart';
|
||||
|
||||
part 'init.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
FutureOr<Map<String, String>> env(EnvRef ref) async {
|
||||
await dotenv.load();
|
||||
return dotenv.env;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
AppRouter router(RouterRef ref) {
|
||||
return AppRouter();
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
FutureOr<Uri> placeholderImageUri(PlaceholderImageUriRef ref) async {
|
||||
final byteData = await rootBundle.load('assets/placeholder.png');
|
||||
final docsDir = await getApplicationDocumentsDirectory();
|
||||
|
||||
return (await File('${docsDir.path}/placeholder.png').writeAsBytes(byteData
|
||||
.buffer
|
||||
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes)))
|
||||
.uri;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
FutureOr<Uri> placeholderThumbImageUri(PlaceholderThumbImageUriRef ref) async {
|
||||
final byteData = await rootBundle.load('assets/placeholder_thumb.png');
|
||||
final docsDir = await getApplicationDocumentsDirectory();
|
||||
|
||||
return (await File('${docsDir.path}/placeholder_thumb.png').writeAsBytes(
|
||||
byteData.buffer
|
||||
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes)))
|
||||
.uri;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
FutureOr<PackageInfo> packageInfo(PackageInfoRef ref) async {
|
||||
return await PackageInfo.fromPlatform();
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
FutureOr<void> init(InitRef ref) async {
|
||||
ref.watch(routerProvider);
|
||||
await ref.watch(envProvider.future);
|
||||
await ref.read(packageInfoProvider.future);
|
||||
await ref.watch(placeholderImageUriProvider.future);
|
||||
await ref.watch(placeholderThumbImageUriProvider.future);
|
||||
|
||||
await ref.read(networkModeProvider.future);
|
||||
await ref.read(maxBitrateProvider.future);
|
||||
await ref.watch(settingsServiceProvider.notifier).init();
|
||||
|
||||
final audio = await ref.watch(audioControlInitProvider.future);
|
||||
await audio.init();
|
||||
ref.watch(lastAudioStateServiceProvider.notifier);
|
||||
|
||||
await ref.watch(downloadServiceProvider.notifier).init();
|
||||
|
||||
await ref.watch(lastPathProvider.notifier).init();
|
||||
ref.watch(lastBottomNavStateServiceProvider.notifier);
|
||||
ref.watch(lastLibraryStateServiceProvider.notifier);
|
||||
|
||||
await ref.watch(libraryListsProvider.notifier).init();
|
||||
}
|
||||
97
lib/state/init.g.dart
Normal file
97
lib/state/init.g.dart
Normal file
@@ -0,0 +1,97 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'init.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$envHash() => r'183e2c6c10c5a9d3dfcaffca0f1723cd85d67a5c';
|
||||
|
||||
/// See also [env].
|
||||
@ProviderFor(env)
|
||||
final envProvider = FutureProvider<Map<String, String>>.internal(
|
||||
env,
|
||||
name: r'envProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$envHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef EnvRef = FutureProviderRef<Map<String, String>>;
|
||||
String _$routerHash() => r'3f52af31948ac5942fe4167f84785572458eeacc';
|
||||
|
||||
/// See also [router].
|
||||
@ProviderFor(router)
|
||||
final routerProvider = Provider<AppRouter>.internal(
|
||||
router,
|
||||
name: r'routerProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$routerHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef RouterRef = ProviderRef<AppRouter>;
|
||||
String _$placeholderImageUriHash() =>
|
||||
r'129f37af640421ec12038d161a8b15a67536e570';
|
||||
|
||||
/// See also [placeholderImageUri].
|
||||
@ProviderFor(placeholderImageUri)
|
||||
final placeholderImageUriProvider = FutureProvider<Uri>.internal(
|
||||
placeholderImageUri,
|
||||
name: r'placeholderImageUriProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$placeholderImageUriHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PlaceholderImageUriRef = FutureProviderRef<Uri>;
|
||||
String _$placeholderThumbImageUriHash() =>
|
||||
r'8136dd4bbb3dc57fb1e6aa8db556e58620c61c85';
|
||||
|
||||
/// See also [placeholderThumbImageUri].
|
||||
@ProviderFor(placeholderThumbImageUri)
|
||||
final placeholderThumbImageUriProvider = FutureProvider<Uri>.internal(
|
||||
placeholderThumbImageUri,
|
||||
name: r'placeholderThumbImageUriProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$placeholderThumbImageUriHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PlaceholderThumbImageUriRef = FutureProviderRef<Uri>;
|
||||
String _$packageInfoHash() => r'9a2956f08c2e98b92dd8cce49cb331a127c78670';
|
||||
|
||||
/// See also [packageInfo].
|
||||
@ProviderFor(packageInfo)
|
||||
final packageInfoProvider = FutureProvider<PackageInfo>.internal(
|
||||
packageInfo,
|
||||
name: r'packageInfoProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$packageInfoHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef PackageInfoRef = FutureProviderRef<PackageInfo>;
|
||||
String _$initHash() => r'10e2945eb65f51e6a904a3811fa88e63771e5b19';
|
||||
|
||||
/// See also [init].
|
||||
@ProviderFor(init)
|
||||
final initProvider = FutureProvider<void>.internal(
|
||||
init,
|
||||
name: r'initProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$initHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef InitRef = FutureProviderRef<void>;
|
||||
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
||||
152
lib/state/music.dart
Normal file
152
lib/state/music.dart
Normal file
@@ -0,0 +1,152 @@
|
||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../database/database.dart';
|
||||
import '../models/music.dart';
|
||||
import '../models/query.dart';
|
||||
import '../models/support.dart';
|
||||
import 'settings.dart';
|
||||
|
||||
part 'music.g.dart';
|
||||
|
||||
@riverpod
|
||||
Stream<Artist> artist(ArtistRef ref, String id) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.artistById(sourceId, id).watchSingle();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<Album> album(AlbumRef ref, String id) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.albumById(sourceId, id).watchSingle();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<ListDownloadStatus> albumDownloadStatus(
|
||||
AlbumDownloadStatusRef ref,
|
||||
String id,
|
||||
) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.albumDownloadStatus(sourceId, id).watchSingle();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<ListDownloadStatus> playlistDownloadStatus(
|
||||
PlaylistDownloadStatusRef ref,
|
||||
String id,
|
||||
) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.playlistDownloadStatus(sourceId, id).watchSingle();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<Song> song(SongRef ref, String id) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.songById(sourceId, id).watchSingle();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<List<Song>> albumSongsList(
|
||||
AlbumSongsListRef ref,
|
||||
String id,
|
||||
ListQuery opt,
|
||||
) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.albumSongsList(SourceId(sourceId: sourceId, id: id), opt).get();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<List<Song>> songsByAlbumList(
|
||||
SongsByAlbumListRef ref,
|
||||
ListQuery opt,
|
||||
) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.songsByAlbumList(sourceId, opt).get();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<Playlist> playlist(PlaylistRef ref, String id) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.playlistById(sourceId, id).watchSingle();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<List<Song>> playlistSongsList(
|
||||
PlaylistSongsListRef ref,
|
||||
String id,
|
||||
ListQuery opt,
|
||||
) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.playlistSongsList(SourceId(sourceId: sourceId, id: id), opt).get();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<List<Album>> albumsInIds(AlbumsInIdsRef ref, IList<String> ids) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.albumsInIds(sourceId, ids.toList()).get();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<IList<Album>> albumsByArtistId(AlbumsByArtistIdRef ref, String id) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db
|
||||
.albumsByArtistId(sourceId, id)
|
||||
.watch()
|
||||
.map((event) => event.toIList());
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<IList<String>> albumGenres(AlbumGenresRef ref, Pagination page) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db
|
||||
.albumGenres(sourceId, page.limit, page.offset)
|
||||
.watch()
|
||||
.map((event) => event.withNullsRemoved().toIList());
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<IList<Album>> albumsByGenre(
|
||||
AlbumsByGenreRef ref,
|
||||
String genre,
|
||||
Pagination page,
|
||||
) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db
|
||||
.albumsByGenre(sourceId, genre, page.limit, page.offset)
|
||||
.watch()
|
||||
.map((event) => event.toIList());
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Stream<int> songsByGenreCount(SongsByGenreCountRef ref, String genre) {
|
||||
final db = ref.watch(databaseProvider);
|
||||
final sourceId = ref.watch(sourceIdProvider);
|
||||
|
||||
return db.songsByGenreCount(sourceId, genre).watchSingle();
|
||||
}
|
||||
1206
lib/state/music.g.dart
Normal file
1206
lib/state/music.g.dart
Normal file
File diff suppressed because it is too large
Load Diff
88
lib/state/settings.dart
Normal file
88
lib/state/settings.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../http/client.dart';
|
||||
import '../models/settings.dart';
|
||||
import '../services/settings_service.dart';
|
||||
import '../sources/music_source.dart';
|
||||
import '../sources/subsonic/source.dart';
|
||||
|
||||
part 'settings.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
MusicSource musicSource(MusicSourceRef ref) {
|
||||
final settings = ref.watch(settingsServiceProvider.select(
|
||||
(value) => value.activeSource,
|
||||
)) as SubsonicSettings;
|
||||
final streamFormat = ref.watch(settingsServiceProvider.select(
|
||||
(value) => value.app.streamFormat,
|
||||
));
|
||||
final maxBitrate = ref.watch(maxBitrateProvider).requireValue;
|
||||
final http = ref.watch(httpClientProvider);
|
||||
|
||||
return MusicSource(
|
||||
SubsonicSource(
|
||||
opt: settings,
|
||||
http: http,
|
||||
maxBitrate: maxBitrate,
|
||||
streamFormat: streamFormat,
|
||||
),
|
||||
ref,
|
||||
);
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<NetworkMode> networkMode(NetworkModeRef ref) async* {
|
||||
await for (var state in Connectivity().onConnectivityChanged) {
|
||||
switch (state) {
|
||||
case ConnectivityResult.wifi:
|
||||
case ConnectivityResult.ethernet:
|
||||
yield NetworkMode.wifi;
|
||||
break;
|
||||
default:
|
||||
yield NetworkMode.mobile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
Future<int> maxBitrate(MaxBitrateRef ref) async {
|
||||
final settings = ref.watch(settingsServiceProvider.select(
|
||||
(value) => value.app,
|
||||
));
|
||||
final networkMode = ref.watch(networkModeProvider).requireValue;
|
||||
|
||||
return networkMode == NetworkMode.wifi
|
||||
? settings.maxBitrateWifi
|
||||
: settings.maxBitrateMobile;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
int sourceId(SourceIdRef ref) {
|
||||
return ref.watch(musicSourceProvider.select((value) => value.id));
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class OfflineMode extends _$OfflineMode {
|
||||
@override
|
||||
bool build() {
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<void> setMode(bool value) async {
|
||||
final hasSource = ref.read(settingsServiceProvider.select(
|
||||
(value) => value.activeSource != null,
|
||||
));
|
||||
if (!hasSource) return;
|
||||
|
||||
if (value == false && state == true) {
|
||||
try {
|
||||
await ref.read(musicSourceProvider).ping();
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
state = value;
|
||||
}
|
||||
}
|
||||
79
lib/state/settings.g.dart
Normal file
79
lib/state/settings.g.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'settings.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$musicSourceHash() => r'466e2654eab8518c9e40c8c2c08a2ecb331b0a7f';
|
||||
|
||||
/// See also [musicSource].
|
||||
@ProviderFor(musicSource)
|
||||
final musicSourceProvider = Provider<MusicSource>.internal(
|
||||
musicSource,
|
||||
name: r'musicSourceProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$musicSourceHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MusicSourceRef = ProviderRef<MusicSource>;
|
||||
String _$networkModeHash() => r'813a60a454c6acaefbe3b56bf0152497ab18dcce';
|
||||
|
||||
/// See also [networkMode].
|
||||
@ProviderFor(networkMode)
|
||||
final networkModeProvider = StreamProvider<NetworkMode>.internal(
|
||||
networkMode,
|
||||
name: r'networkModeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$networkModeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef NetworkModeRef = StreamProviderRef<NetworkMode>;
|
||||
String _$maxBitrateHash() => r'ec02d3ccbc9f3429acfc1b3f191cab791b1191e0';
|
||||
|
||||
/// See also [maxBitrate].
|
||||
@ProviderFor(maxBitrate)
|
||||
final maxBitrateProvider = FutureProvider<int>.internal(
|
||||
maxBitrate,
|
||||
name: r'maxBitrateProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$maxBitrateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MaxBitrateRef = FutureProviderRef<int>;
|
||||
String _$sourceIdHash() => r'66ed4717b4a07548f5e25a42aeac2027aeab9b9c';
|
||||
|
||||
/// See also [sourceId].
|
||||
@ProviderFor(sourceId)
|
||||
final sourceIdProvider = Provider<int>.internal(
|
||||
sourceId,
|
||||
name: r'sourceIdProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$sourceIdHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef SourceIdRef = ProviderRef<int>;
|
||||
String _$offlineModeHash() => r'b84cdece48d97c69e995fbaea97febb128cfc20a';
|
||||
|
||||
/// See also [OfflineMode].
|
||||
@ProviderFor(OfflineMode)
|
||||
final offlineModeProvider = NotifierProvider<OfflineMode, bool>.internal(
|
||||
OfflineMode.new,
|
||||
name: r'offlineModeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$offlineModeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$OfflineMode = Notifier<bool>;
|
||||
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
||||
258
lib/state/theme.dart
Normal file
258
lib/state/theme.dart
Normal file
@@ -0,0 +1,258 @@
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker_manager/worker_manager.dart';
|
||||
|
||||
import '../cache/image_cache.dart';
|
||||
import '../models/support.dart';
|
||||
import '../services/cache_service.dart';
|
||||
import 'audio.dart';
|
||||
import 'music.dart';
|
||||
|
||||
part 'theme.g.dart';
|
||||
|
||||
const kDarkBackgroundValue = 0.28;
|
||||
const kDarkerBackgroundLightness = 0.13;
|
||||
const kOnDarkerBackgroundLightness = 0.6;
|
||||
|
||||
PaletteColor? _rankedByLuminance(
|
||||
List<PaletteColor?> colors, [
|
||||
double minLuminance = 0.0,
|
||||
double maxLuminance = 1.0,
|
||||
]) {
|
||||
for (var color in colors) {
|
||||
if (color == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final luminance = color.color.computeLuminance();
|
||||
if (luminance >= minLuminance && luminance <= maxLuminance) {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
PaletteColor? _rankedWithValue(double value, List<PaletteColor?> colors) {
|
||||
for (var color in colors) {
|
||||
if (color == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final hsv = HSVColor.fromColor(color.color);
|
||||
if (hsv.value > value) {
|
||||
return PaletteColor(hsv.withValue(value).toColor(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@riverpod
|
||||
ColorTheme _colorTheme(_ColorThemeRef ref, Palette palette) {
|
||||
final base = ref.watch(baseThemeProvider);
|
||||
|
||||
final primary = _rankedByLuminance([
|
||||
palette.dominantColor,
|
||||
palette.vibrantColor,
|
||||
palette.mutedColor,
|
||||
palette.darkVibrantColor,
|
||||
], 0.2);
|
||||
final vibrant = _rankedByLuminance([
|
||||
palette.vibrantColor,
|
||||
palette.darkVibrantColor,
|
||||
palette.dominantColor,
|
||||
], 0.05);
|
||||
final secondary = _rankedByLuminance([
|
||||
palette.lightMutedColor,
|
||||
palette.mutedColor,
|
||||
palette.darkMutedColor,
|
||||
]);
|
||||
|
||||
final background = _rankedWithValue(0.5, [
|
||||
palette.vibrantColor,
|
||||
palette.darkVibrantColor,
|
||||
palette.darkMutedColor,
|
||||
palette.dominantColor,
|
||||
palette.mutedColor,
|
||||
palette.lightVibrantColor,
|
||||
palette.lightMutedColor,
|
||||
]);
|
||||
|
||||
final colorScheme = ColorScheme.fromSeed(
|
||||
brightness: Brightness.dark,
|
||||
seedColor: background?.color ?? Colors.purple[800]!,
|
||||
background: background?.color,
|
||||
primaryContainer: primary?.color,
|
||||
onPrimaryContainer: primary?.bodyTextColor,
|
||||
secondaryContainer: secondary?.color,
|
||||
onSecondaryContainer: secondary?.bodyTextColor,
|
||||
surface: background?.color,
|
||||
surfaceTint: vibrant?.color,
|
||||
);
|
||||
|
||||
final hsv = HSVColor.fromColor(colorScheme.background);
|
||||
final hsl = HSLColor.fromColor(colorScheme.background);
|
||||
|
||||
return base.copyWith(
|
||||
theme: ThemeData(
|
||||
colorScheme: colorScheme,
|
||||
useMaterial3: base.theme.useMaterial3,
|
||||
brightness: base.theme.brightness,
|
||||
cardTheme: base.theme.cardTheme,
|
||||
),
|
||||
gradientHigh: colorScheme.background,
|
||||
darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(),
|
||||
darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(),
|
||||
onDarkerBackground:
|
||||
hsl.withLightness(kOnDarkerBackgroundLightness).toColor(),
|
||||
);
|
||||
}
|
||||
|
||||
@riverpod
|
||||
ColorTheme baseTheme(BaseThemeRef ref) {
|
||||
final theme = ThemeData(
|
||||
useMaterial3: true,
|
||||
colorSchemeSeed: Colors.purple[800],
|
||||
brightness: Brightness.dark,
|
||||
cardTheme: CardTheme(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final hsv = HSVColor.fromColor(theme.colorScheme.background);
|
||||
final hsl = HSLColor.fromColor(theme.colorScheme.background);
|
||||
|
||||
return ColorTheme(
|
||||
theme: theme,
|
||||
gradientHigh: theme.colorScheme.background,
|
||||
gradientLow: HSLColor.fromColor(theme.colorScheme.background)
|
||||
.withLightness(0.06)
|
||||
.toColor(),
|
||||
darkBackground: hsv.withValue(kDarkBackgroundValue).toColor(),
|
||||
darkerBackground: hsl.withLightness(kDarkerBackgroundLightness).toColor(),
|
||||
onDarkerBackground:
|
||||
hsl.withLightness(kOnDarkerBackgroundLightness).toColor(),
|
||||
);
|
||||
}
|
||||
|
||||
@riverpod
|
||||
FutureOr<Palette> albumArtPalette(
|
||||
AlbumArtPaletteRef ref,
|
||||
String id,
|
||||
) async {
|
||||
final album = await ref.watch(albumProvider(id).future);
|
||||
final cache = ref.watch(cacheServiceProvider);
|
||||
final info = cache.albumArt(album, thumbnail: true);
|
||||
|
||||
return Palette.fromPaletteGenerator(await _generateFromCache(info));
|
||||
}
|
||||
|
||||
Future<PaletteGenerator> _generateFromCache(
|
||||
UriCacheInfo cacheInfo,
|
||||
) async {
|
||||
var file = await cacheInfo.cacheManager.getSingleFile(
|
||||
cacheInfo.uri.toString(),
|
||||
key: cacheInfo.cacheKey,
|
||||
);
|
||||
|
||||
final memoryImage = ResizeImage(
|
||||
MemoryImage(await file.readAsBytes()),
|
||||
height: 32,
|
||||
width: 32,
|
||||
);
|
||||
final stream = memoryImage.resolve(const ImageConfiguration(
|
||||
devicePixelRatio: 1.0,
|
||||
));
|
||||
|
||||
Completer<ui.Image> imageCompleter = Completer<ui.Image>();
|
||||
late ImageStreamListener listener;
|
||||
listener = ImageStreamListener((ImageInfo info, bool synchronousCall) {
|
||||
stream.removeListener(listener);
|
||||
imageCompleter.complete(info.image);
|
||||
});
|
||||
|
||||
stream.addListener(listener);
|
||||
final image = await imageCompleter.future;
|
||||
final byteData = (await image.toByteData())!;
|
||||
final height = image.height;
|
||||
final width = image.width;
|
||||
|
||||
return await Executor().execute(
|
||||
arg1: byteData,
|
||||
arg2: height,
|
||||
arg3: width,
|
||||
fun3: _computePalette,
|
||||
);
|
||||
}
|
||||
|
||||
Future<PaletteGenerator> _computePalette(
|
||||
ByteData byteData,
|
||||
int height,
|
||||
int width,
|
||||
TypeSendPort port,
|
||||
) async {
|
||||
return await PaletteGenerator.fromByteData(
|
||||
EncodedImage(byteData, height: height, width: width),
|
||||
);
|
||||
}
|
||||
|
||||
@riverpod
|
||||
FutureOr<Palette> playlistArtPalette(
|
||||
PlaylistArtPaletteRef ref,
|
||||
String id,
|
||||
) async {
|
||||
final playlist = await ref.watch(playlistProvider(id).future);
|
||||
final cache = ref.watch(cacheServiceProvider);
|
||||
final info = cache.playlistArt(playlist, thumbnail: true);
|
||||
|
||||
return Palette.fromPaletteGenerator(await _generateFromCache(info));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
FutureOr<Palette> mediaItemPalette(MediaItemPaletteRef ref) async {
|
||||
final item = ref.watch(mediaItemProvider).valueOrNull;
|
||||
final itemData = ref.watch(mediaItemDataProvider);
|
||||
final imageCache = ref.watch(imageCacheProvider);
|
||||
|
||||
if (item == null || item.artUri == null || itemData == null) {
|
||||
return const Palette();
|
||||
}
|
||||
|
||||
return Palette.fromPaletteGenerator(await _generateFromCache(
|
||||
UriCacheInfo(
|
||||
uri: item.artUri!,
|
||||
cacheKey: itemData.artCache!.thumbnailArtCacheKey,
|
||||
cacheManager: imageCache,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
FutureOr<ColorTheme> mediaItemTheme(MediaItemThemeRef ref) async {
|
||||
final palette = await ref.watch(mediaItemPaletteProvider.future);
|
||||
return ref.watch(_colorThemeProvider(palette));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
FutureOr<ColorTheme> albumArtTheme(AlbumArtThemeRef ref, String id) async {
|
||||
final palette = await ref.watch(albumArtPaletteProvider(id).future);
|
||||
return ref.watch(_colorThemeProvider(palette));
|
||||
}
|
||||
|
||||
@riverpod
|
||||
FutureOr<ColorTheme> playlistArtTheme(
|
||||
PlaylistArtThemeRef ref,
|
||||
String id,
|
||||
) async {
|
||||
final palette = await ref.watch(playlistArtPaletteProvider(id).future);
|
||||
return ref.watch(_colorThemeProvider(palette));
|
||||
}
|
||||
485
lib/state/theme.g.dart
Normal file
485
lib/state/theme.g.dart
Normal file
@@ -0,0 +1,485 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'theme.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$colorThemeHash() => r'f5cc23cb5e2af379c02ae4b9756df72f9f6da5e6';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
_SystemHash._();
|
||||
|
||||
static int combine(int hash, int value) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + value);
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||
return hash ^ (hash >> 6);
|
||||
}
|
||||
|
||||
static int finish(int hash) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||
// ignore: parameter_assignments
|
||||
hash = hash ^ (hash >> 11);
|
||||
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||
}
|
||||
}
|
||||
|
||||
typedef _ColorThemeRef = AutoDisposeProviderRef<ColorTheme>;
|
||||
|
||||
/// See also [_colorTheme].
|
||||
@ProviderFor(_colorTheme)
|
||||
const _colorThemeProvider = _ColorThemeFamily();
|
||||
|
||||
/// See also [_colorTheme].
|
||||
class _ColorThemeFamily extends Family<ColorTheme> {
|
||||
/// See also [_colorTheme].
|
||||
const _ColorThemeFamily();
|
||||
|
||||
/// See also [_colorTheme].
|
||||
_ColorThemeProvider call(
|
||||
Palette palette,
|
||||
) {
|
||||
return _ColorThemeProvider(
|
||||
palette,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
_ColorThemeProvider getProviderOverride(
|
||||
covariant _ColorThemeProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.palette,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'_colorThemeProvider';
|
||||
}
|
||||
|
||||
/// See also [_colorTheme].
|
||||
class _ColorThemeProvider extends AutoDisposeProvider<ColorTheme> {
|
||||
/// See also [_colorTheme].
|
||||
_ColorThemeProvider(
|
||||
this.palette,
|
||||
) : super.internal(
|
||||
(ref) => _colorTheme(
|
||||
ref,
|
||||
palette,
|
||||
),
|
||||
from: _colorThemeProvider,
|
||||
name: r'_colorThemeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$colorThemeHash,
|
||||
dependencies: _ColorThemeFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
_ColorThemeFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final Palette palette;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is _ColorThemeProvider && other.palette == palette;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, palette.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
String _$baseThemeHash() => r'317a5ef77def208357a54b7938ef3d91666fce70';
|
||||
|
||||
/// See also [baseTheme].
|
||||
@ProviderFor(baseTheme)
|
||||
final baseThemeProvider = AutoDisposeProvider<ColorTheme>.internal(
|
||||
baseTheme,
|
||||
name: r'baseThemeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$baseThemeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef BaseThemeRef = AutoDisposeProviderRef<ColorTheme>;
|
||||
String _$albumArtPaletteHash() => r'8130b954ee3c67f53207593d4ed3dfbffb00c95d';
|
||||
typedef AlbumArtPaletteRef = AutoDisposeFutureProviderRef<Palette>;
|
||||
|
||||
/// See also [albumArtPalette].
|
||||
@ProviderFor(albumArtPalette)
|
||||
const albumArtPaletteProvider = AlbumArtPaletteFamily();
|
||||
|
||||
/// See also [albumArtPalette].
|
||||
class AlbumArtPaletteFamily extends Family<AsyncValue<Palette>> {
|
||||
/// See also [albumArtPalette].
|
||||
const AlbumArtPaletteFamily();
|
||||
|
||||
/// See also [albumArtPalette].
|
||||
AlbumArtPaletteProvider call(
|
||||
String id,
|
||||
) {
|
||||
return AlbumArtPaletteProvider(
|
||||
id,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AlbumArtPaletteProvider getProviderOverride(
|
||||
covariant AlbumArtPaletteProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.id,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'albumArtPaletteProvider';
|
||||
}
|
||||
|
||||
/// See also [albumArtPalette].
|
||||
class AlbumArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
|
||||
/// See also [albumArtPalette].
|
||||
AlbumArtPaletteProvider(
|
||||
this.id,
|
||||
) : super.internal(
|
||||
(ref) => albumArtPalette(
|
||||
ref,
|
||||
id,
|
||||
),
|
||||
from: albumArtPaletteProvider,
|
||||
name: r'albumArtPaletteProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$albumArtPaletteHash,
|
||||
dependencies: AlbumArtPaletteFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
AlbumArtPaletteFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final String id;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is AlbumArtPaletteProvider && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, id.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
String _$playlistArtPaletteHash() =>
|
||||
r'6bc015688f354ea8d91dde86e2a7191ef1ef6496';
|
||||
typedef PlaylistArtPaletteRef = AutoDisposeFutureProviderRef<Palette>;
|
||||
|
||||
/// See also [playlistArtPalette].
|
||||
@ProviderFor(playlistArtPalette)
|
||||
const playlistArtPaletteProvider = PlaylistArtPaletteFamily();
|
||||
|
||||
/// See also [playlistArtPalette].
|
||||
class PlaylistArtPaletteFamily extends Family<AsyncValue<Palette>> {
|
||||
/// See also [playlistArtPalette].
|
||||
const PlaylistArtPaletteFamily();
|
||||
|
||||
/// See also [playlistArtPalette].
|
||||
PlaylistArtPaletteProvider call(
|
||||
String id,
|
||||
) {
|
||||
return PlaylistArtPaletteProvider(
|
||||
id,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
PlaylistArtPaletteProvider getProviderOverride(
|
||||
covariant PlaylistArtPaletteProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.id,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'playlistArtPaletteProvider';
|
||||
}
|
||||
|
||||
/// See also [playlistArtPalette].
|
||||
class PlaylistArtPaletteProvider extends AutoDisposeFutureProvider<Palette> {
|
||||
/// See also [playlistArtPalette].
|
||||
PlaylistArtPaletteProvider(
|
||||
this.id,
|
||||
) : super.internal(
|
||||
(ref) => playlistArtPalette(
|
||||
ref,
|
||||
id,
|
||||
),
|
||||
from: playlistArtPaletteProvider,
|
||||
name: r'playlistArtPaletteProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$playlistArtPaletteHash,
|
||||
dependencies: PlaylistArtPaletteFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
PlaylistArtPaletteFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final String id;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is PlaylistArtPaletteProvider && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, id.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
String _$mediaItemPaletteHash() => r'2f2744aa735c6056919197c283a367714d7e04e4';
|
||||
|
||||
/// See also [mediaItemPalette].
|
||||
@ProviderFor(mediaItemPalette)
|
||||
final mediaItemPaletteProvider = AutoDisposeFutureProvider<Palette>.internal(
|
||||
mediaItemPalette,
|
||||
name: r'mediaItemPaletteProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$mediaItemPaletteHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MediaItemPaletteRef = AutoDisposeFutureProviderRef<Palette>;
|
||||
String _$mediaItemThemeHash() => r'f43e6f86eeed7aef33fa8bd2695454a760f41afa';
|
||||
|
||||
/// See also [mediaItemTheme].
|
||||
@ProviderFor(mediaItemTheme)
|
||||
final mediaItemThemeProvider = AutoDisposeFutureProvider<ColorTheme>.internal(
|
||||
mediaItemTheme,
|
||||
name: r'mediaItemThemeProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$mediaItemThemeHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef MediaItemThemeRef = AutoDisposeFutureProviderRef<ColorTheme>;
|
||||
String _$albumArtThemeHash() => r'd3ee71b2df856f1763ec925e158ae2e0f613b9e0';
|
||||
typedef AlbumArtThemeRef = AutoDisposeFutureProviderRef<ColorTheme>;
|
||||
|
||||
/// See also [albumArtTheme].
|
||||
@ProviderFor(albumArtTheme)
|
||||
const albumArtThemeProvider = AlbumArtThemeFamily();
|
||||
|
||||
/// See also [albumArtTheme].
|
||||
class AlbumArtThemeFamily extends Family<AsyncValue<ColorTheme>> {
|
||||
/// See also [albumArtTheme].
|
||||
const AlbumArtThemeFamily();
|
||||
|
||||
/// See also [albumArtTheme].
|
||||
AlbumArtThemeProvider call(
|
||||
String id,
|
||||
) {
|
||||
return AlbumArtThemeProvider(
|
||||
id,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AlbumArtThemeProvider getProviderOverride(
|
||||
covariant AlbumArtThemeProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.id,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'albumArtThemeProvider';
|
||||
}
|
||||
|
||||
/// See also [albumArtTheme].
|
||||
class AlbumArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
|
||||
/// See also [albumArtTheme].
|
||||
AlbumArtThemeProvider(
|
||||
this.id,
|
||||
) : super.internal(
|
||||
(ref) => albumArtTheme(
|
||||
ref,
|
||||
id,
|
||||
),
|
||||
from: albumArtThemeProvider,
|
||||
name: r'albumArtThemeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$albumArtThemeHash,
|
||||
dependencies: AlbumArtThemeFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
AlbumArtThemeFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final String id;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is AlbumArtThemeProvider && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, id.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
String _$playlistArtThemeHash() => r'1629552e1f3aa2a1e7d223ac1e078893042e5e3b';
|
||||
typedef PlaylistArtThemeRef = AutoDisposeFutureProviderRef<ColorTheme>;
|
||||
|
||||
/// See also [playlistArtTheme].
|
||||
@ProviderFor(playlistArtTheme)
|
||||
const playlistArtThemeProvider = PlaylistArtThemeFamily();
|
||||
|
||||
/// See also [playlistArtTheme].
|
||||
class PlaylistArtThemeFamily extends Family<AsyncValue<ColorTheme>> {
|
||||
/// See also [playlistArtTheme].
|
||||
const PlaylistArtThemeFamily();
|
||||
|
||||
/// See also [playlistArtTheme].
|
||||
PlaylistArtThemeProvider call(
|
||||
String id,
|
||||
) {
|
||||
return PlaylistArtThemeProvider(
|
||||
id,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
PlaylistArtThemeProvider getProviderOverride(
|
||||
covariant PlaylistArtThemeProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.id,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'playlistArtThemeProvider';
|
||||
}
|
||||
|
||||
/// See also [playlistArtTheme].
|
||||
class PlaylistArtThemeProvider extends AutoDisposeFutureProvider<ColorTheme> {
|
||||
/// See also [playlistArtTheme].
|
||||
PlaylistArtThemeProvider(
|
||||
this.id,
|
||||
) : super.internal(
|
||||
(ref) => playlistArtTheme(
|
||||
ref,
|
||||
id,
|
||||
),
|
||||
from: playlistArtThemeProvider,
|
||||
name: r'playlistArtThemeProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$playlistArtThemeHash,
|
||||
dependencies: PlaylistArtThemeFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
PlaylistArtThemeFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final String id;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is PlaylistArtThemeProvider && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, id.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
||||
Reference in New Issue
Block a user