mirror of
https://github.com/Dr-Blank/Vaani.git
synced 2025-12-21 02:19:30 +00:00
refactor: update cover image handling to use item IDs and simplify library item actions
This commit is contained in:
parent
d25d23a0b7
commit
405d625cdc
15 changed files with 305 additions and 362 deletions
|
|
@ -4,6 +4,7 @@ import 'package:logging/logging.dart';
|
|||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:shelfsdk/audiobookshelf_api.dart';
|
||||
import 'package:vaani/api/api_provider.dart';
|
||||
import 'package:vaani/api/library_item_provider.dart';
|
||||
import 'package:vaani/db/cache_manager.dart';
|
||||
|
||||
/// provides cover images for the audiobooks
|
||||
|
|
@ -19,52 +20,53 @@ final _logger = Logger('cover_image_provider');
|
|||
@Riverpod(keepAlive: true)
|
||||
class CoverImage extends _$CoverImage {
|
||||
@override
|
||||
Stream<Uint8List> build(LibraryItem libraryItem) async* {
|
||||
Stream<Uint8List> build(String itemId) async* {
|
||||
final api = ref.watch(authenticatedApiProvider);
|
||||
|
||||
// ! artifical delay for testing
|
||||
// await Future.delayed(const Duration(seconds: 2));
|
||||
|
||||
// try to get the image from the cache
|
||||
final file = await imageCacheManager.getFileFromMemory(libraryItem.id) ??
|
||||
await imageCacheManager.getFileFromCache(libraryItem.id);
|
||||
final file = await imageCacheManager.getFileFromMemory(itemId) ??
|
||||
await imageCacheManager.getFileFromCache(itemId);
|
||||
|
||||
if (file != null) {
|
||||
// if the image is in the cache, yield it
|
||||
_logger.fine(
|
||||
'cover image found in cache for ${libraryItem.id} at ${file.file.path}',
|
||||
'cover image found in cache for $itemId at ${file.file.path}',
|
||||
);
|
||||
yield await file.file.readAsBytes();
|
||||
final libraryItem = await ref.watch(libraryItemProvider(itemId).future);
|
||||
// return if no need to fetch from the server
|
||||
if (libraryItem.updatedAt.isBefore(await file.file.lastModified())) {
|
||||
_logger.fine(
|
||||
'cover image is up to date for ${libraryItem.id}, no need to fetch from the server',
|
||||
'cover image is up to date for $itemId, no need to fetch from the server',
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
_logger.fine(
|
||||
'cover image stale for ${libraryItem.id}, fetching from the server',
|
||||
'cover image stale for $itemId, fetching from the server',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
_logger.fine('cover image not found in cache for ${libraryItem.id}');
|
||||
_logger.fine('cover image not found in cache for $itemId');
|
||||
}
|
||||
|
||||
// check if the image is in the cache
|
||||
final coverImage = await api.items.getCover(
|
||||
libraryItemId: libraryItem.id,
|
||||
libraryItemId: itemId,
|
||||
parameters: const GetImageReqParams(width: 1200),
|
||||
);
|
||||
// save the image to the cache
|
||||
if (coverImage != null) {
|
||||
final newFile = await imageCacheManager.putFile(
|
||||
libraryItem.id,
|
||||
itemId,
|
||||
coverImage,
|
||||
key: libraryItem.id,
|
||||
key: itemId,
|
||||
fileExtension: 'jpg',
|
||||
);
|
||||
_logger.fine(
|
||||
'cover image fetched for for ${libraryItem.id}, file time: ${await newFile.lastModified()}',
|
||||
'cover image fetched for for $itemId, file time: ${await newFile.lastModified()}',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'image_provider.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$coverImageHash() => r'702afafa217dfcbb290837caf21cc1ef54defd55';
|
||||
String _$coverImageHash() => r'89cc4783cbc76bb41beae34384d92fb277135c75';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -30,10 +30,10 @@ class _SystemHash {
|
|||
}
|
||||
|
||||
abstract class _$CoverImage extends BuildlessStreamNotifier<Uint8List> {
|
||||
late final LibraryItem libraryItem;
|
||||
late final String itemId;
|
||||
|
||||
Stream<Uint8List> build(
|
||||
LibraryItem libraryItem,
|
||||
String itemId,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -48,10 +48,10 @@ class CoverImageFamily extends Family<AsyncValue<Uint8List>> {
|
|||
|
||||
/// See also [CoverImage].
|
||||
CoverImageProvider call(
|
||||
LibraryItem libraryItem,
|
||||
String itemId,
|
||||
) {
|
||||
return CoverImageProvider(
|
||||
libraryItem,
|
||||
itemId,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ class CoverImageFamily extends Family<AsyncValue<Uint8List>> {
|
|||
covariant CoverImageProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.libraryItem,
|
||||
provider.itemId,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -84,9 +84,9 @@ class CoverImageProvider
|
|||
extends StreamNotifierProviderImpl<CoverImage, Uint8List> {
|
||||
/// See also [CoverImage].
|
||||
CoverImageProvider(
|
||||
LibraryItem libraryItem,
|
||||
String itemId,
|
||||
) : this._internal(
|
||||
() => CoverImage()..libraryItem = libraryItem,
|
||||
() => CoverImage()..itemId = itemId,
|
||||
from: coverImageProvider,
|
||||
name: r'coverImageProvider',
|
||||
debugGetCreateSourceHash:
|
||||
|
|
@ -96,7 +96,7 @@ class CoverImageProvider
|
|||
dependencies: CoverImageFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
CoverImageFamily._allTransitiveDependencies,
|
||||
libraryItem: libraryItem,
|
||||
itemId: itemId,
|
||||
);
|
||||
|
||||
CoverImageProvider._internal(
|
||||
|
|
@ -106,17 +106,17 @@ class CoverImageProvider
|
|||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.libraryItem,
|
||||
required this.itemId,
|
||||
}) : super.internal();
|
||||
|
||||
final LibraryItem libraryItem;
|
||||
final String itemId;
|
||||
|
||||
@override
|
||||
Stream<Uint8List> runNotifierBuild(
|
||||
covariant CoverImage notifier,
|
||||
) {
|
||||
return notifier.build(
|
||||
libraryItem,
|
||||
itemId,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -125,13 +125,13 @@ class CoverImageProvider
|
|||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: CoverImageProvider._internal(
|
||||
() => create()..libraryItem = libraryItem,
|
||||
() => create()..itemId = itemId,
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
libraryItem: libraryItem,
|
||||
itemId: itemId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -143,21 +143,21 @@ class CoverImageProvider
|
|||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CoverImageProvider && other.libraryItem == libraryItem;
|
||||
return other is CoverImageProvider && other.itemId == itemId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, libraryItem.hashCode);
|
||||
hash = _SystemHash.combine(hash, itemId.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
mixin CoverImageRef on StreamNotifierProviderRef<Uint8List> {
|
||||
/// The parameter `libraryItem` of this provider.
|
||||
LibraryItem get libraryItem;
|
||||
/// The parameter `itemId` of this provider.
|
||||
String get itemId;
|
||||
}
|
||||
|
||||
class _CoverImageProviderElement
|
||||
|
|
@ -166,7 +166,7 @@ class _CoverImageProviderElement
|
|||
_CoverImageProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
LibraryItem get libraryItem => (origin as CoverImageProvider).libraryItem;
|
||||
String get itemId => (origin as CoverImageProvider).itemId;
|
||||
}
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ part 'library_item_provider.g.dart';
|
|||
final _logger = Logger('LibraryItemProvider');
|
||||
|
||||
/// provides the library item for the given id
|
||||
@riverpod
|
||||
@Riverpod(keepAlive: true)
|
||||
class LibraryItem extends _$LibraryItem {
|
||||
@override
|
||||
Stream<shelfsdk.LibraryItemExpanded> build(String id) async* {
|
||||
|
|
@ -22,7 +22,7 @@ class LibraryItem extends _$LibraryItem {
|
|||
_logger.fine('LibraryItemProvider fetching library item: $id');
|
||||
|
||||
// ! this is a mock delay
|
||||
// await Future.delayed(const Duration(seconds: 10));
|
||||
// await Future.delayed(const Duration(seconds: 150));
|
||||
|
||||
// look for the item in the cache
|
||||
final key = CacheKey.libraryItem(id);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'library_item_provider.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$libraryItemHash() => r'fa3f8309349c5b1b777f1bc919616e51c3f5b520';
|
||||
String _$libraryItemHash() => r'a3cfa7f912e9498a70b5782899018b6964d6445c';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -30,7 +30,7 @@ class _SystemHash {
|
|||
}
|
||||
|
||||
abstract class _$LibraryItem
|
||||
extends BuildlessAutoDisposeStreamNotifier<shelfsdk.LibraryItemExpanded> {
|
||||
extends BuildlessStreamNotifier<shelfsdk.LibraryItemExpanded> {
|
||||
late final String id;
|
||||
|
||||
Stream<shelfsdk.LibraryItemExpanded> build(
|
||||
|
|
@ -92,8 +92,8 @@ class LibraryItemFamily
|
|||
/// provides the library item for the given id
|
||||
///
|
||||
/// Copied from [LibraryItem].
|
||||
class LibraryItemProvider extends AutoDisposeStreamNotifierProviderImpl<
|
||||
LibraryItem, shelfsdk.LibraryItemExpanded> {
|
||||
class LibraryItemProvider extends StreamNotifierProviderImpl<LibraryItem,
|
||||
shelfsdk.LibraryItemExpanded> {
|
||||
/// provides the library item for the given id
|
||||
///
|
||||
/// Copied from [LibraryItem].
|
||||
|
|
@ -151,8 +151,8 @@ class LibraryItemProvider extends AutoDisposeStreamNotifierProviderImpl<
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeStreamNotifierProviderElement<LibraryItem,
|
||||
shelfsdk.LibraryItemExpanded> createElement() {
|
||||
StreamNotifierProviderElement<LibraryItem, shelfsdk.LibraryItemExpanded>
|
||||
createElement() {
|
||||
return _LibraryItemProviderElement(this);
|
||||
}
|
||||
|
||||
|
|
@ -171,14 +171,13 @@ class LibraryItemProvider extends AutoDisposeStreamNotifierProviderImpl<
|
|||
}
|
||||
|
||||
mixin LibraryItemRef
|
||||
on AutoDisposeStreamNotifierProviderRef<shelfsdk.LibraryItemExpanded> {
|
||||
on StreamNotifierProviderRef<shelfsdk.LibraryItemExpanded> {
|
||||
/// The parameter `id` of this provider.
|
||||
String get id;
|
||||
}
|
||||
|
||||
class _LibraryItemProviderElement
|
||||
extends AutoDisposeStreamNotifierProviderElement<LibraryItem,
|
||||
shelfsdk.LibraryItemExpanded> with LibraryItemRef {
|
||||
class _LibraryItemProviderElement extends StreamNotifierProviderElement<
|
||||
LibraryItem, shelfsdk.LibraryItemExpanded> with LibraryItemRef {
|
||||
_LibraryItemProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue