From 0521e2b5c314df1d85e37a8f6121fb63211081ae Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Wed, 7 Feb 2024 01:08:28 +0800 Subject: [PATCH] Fix item count in HomeCollections does not consider the runtime count from item controller --- .../collection_items_controller.dart | 10 ++++++ app/lib/widget/home_collections.dart | 14 +++++--- app/lib/widget/home_collections.g.dart | 12 ++++++- app/lib/widget/home_collections/bloc.dart | 36 ++++++++++++++++--- .../widget/home_collections/state_event.dart | 14 ++++++++ app/lib/widget/home_collections/type.dart | 14 +++++--- app/lib/widget/home_collections/view.dart | 5 ++- 7 files changed, 89 insertions(+), 16 deletions(-) diff --git a/app/lib/controller/collection_items_controller.dart b/app/lib/controller/collection_items_controller.dart index 72b503e6..e8e20913 100644 --- a/app/lib/controller/collection_items_controller.dart +++ b/app/lib/controller/collection_items_controller.dart @@ -51,6 +51,13 @@ class CollectionItemsController { required this.collection, required this.onCollectionUpdated, }) { + _countStreamController = BehaviorSubject.seeded(collection.count); + _subscriptions.add(_dataStreamController.stream.listen((event) { + if (!event.hasNext) { + _countStreamController.add(event.items.length); + } + })); + _subscriptions.add(filesController.stream.listen(_onFilesEvent)); } @@ -82,6 +89,8 @@ class CollectionItemsController { /// Peek the stream and return the current value CollectionItemStreamData peekStream() => _dataStreamController.stream.value; + ValueStream get countStream => _countStreamController.stream; + /// Add list of [files] to [collection] Future addFiles(List files) async { final isInited = _isDataStreamInited; @@ -346,6 +355,7 @@ class CollectionItemsController { hasNext: true, ), ); + late final BehaviorSubject _countStreamController; final _mutex = Mutex(); final _subscriptions = []; diff --git a/app/lib/widget/home_collections.dart b/app/lib/widget/home_collections.dart index 8d65efb5..e817d9e1 100644 --- a/app/lib/widget/home_collections.dart +++ b/app/lib/widget/home_collections.dart @@ -191,9 +191,14 @@ class _WrappedHomeCollectionsState extends State<_WrappedHomeCollections> items: state.transformedItems, itemBuilder: (_, __, metadata) { final item = metadata as _Item; - return _ItemView( - account: _bloc.account, - item: item, + return _BlocSelector( + selector: (state) => + state.itemCounts[item.collection.id], + builder: (context, itemCount) => _ItemView( + account: _bloc.account, + item: item, + collectionItemCountOverride: itemCount, + ), ); }, staggeredTileBuilder: (_, __) => @@ -267,7 +272,8 @@ class _WrappedHomeCollectionsState extends State<_WrappedHomeCollections> typedef _BlocBuilder = BlocBuilder<_Bloc, _State>; typedef _BlocListener = BlocListener<_Bloc, _State>; -// typedef _BlocSelector = BlocSelector<_Bloc, _State, T>; +// typedef _BlocListenerT = BlocListenerT<_Bloc, _State, T>; +typedef _BlocSelector = BlocSelector<_Bloc, _State, T>; extension on BuildContext { _Bloc get bloc => read<_Bloc>(); diff --git a/app/lib/widget/home_collections.g.dart b/app/lib/widget/home_collections.g.dart index 95416794..c002b482 100644 --- a/app/lib/widget/home_collections.g.dart +++ b/app/lib/widget/home_collections.g.dart @@ -19,6 +19,7 @@ abstract class $_StateCopyWithWorker { bool? isLoading, List<_Item>? transformedItems, Set<_Item>? selectedItems, + Map? itemCounts, ExceptionEvent? error, ExceptionEvent? removeError}); } @@ -33,6 +34,7 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker { dynamic isLoading, dynamic transformedItems, dynamic selectedItems, + dynamic itemCounts, dynamic error = copyWithNull, dynamic removeError = copyWithNull}) { return _State( @@ -42,6 +44,7 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker { transformedItems: transformedItems as List<_Item>? ?? that.transformedItems, selectedItems: selectedItems as Set<_Item>? ?? that.selectedItems, + itemCounts: itemCounts as Map? ?? that.itemCounts, error: error == copyWithNull ? that.error : error as ExceptionEvent?, removeError: removeError == copyWithNull ? that.removeError @@ -96,7 +99,7 @@ extension _$_ItemNpLog on _Item { extension _$_StateToString on _State { String _$toString() { // ignore: unnecessary_string_interpolations - return "_State {collections: [length: ${collections.length}], sort: ${sort.name}, isLoading: $isLoading, transformedItems: [length: ${transformedItems.length}], selectedItems: {length: ${selectedItems.length}}, error: $error, removeError: $removeError}"; + return "_State {collections: [length: ${collections.length}], sort: ${sort.name}, isLoading: $isLoading, transformedItems: [length: ${transformedItems.length}], selectedItems: {length: ${selectedItems.length}}, itemCounts: $itemCounts, error: $error, removeError: $removeError}"; } } @@ -149,6 +152,13 @@ extension _$_SetCollectionSortToString on _SetCollectionSort { } } +extension _$_SetItemCountToString on _SetItemCount { + String _$toString() { + // ignore: unnecessary_string_interpolations + return "_SetItemCount {collection: $collection, value: $value}"; + } +} + extension _$_SetErrorToString on _SetError { String _$toString() { // ignore: unnecessary_string_interpolations diff --git a/app/lib/widget/home_collections/bloc.dart b/app/lib/widget/home_collections/bloc.dart index aba56295..a85e4e6f 100644 --- a/app/lib/widget/home_collections/bloc.dart +++ b/app/lib/widget/home_collections/bloc.dart @@ -16,18 +16,36 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger { on<_UpdateCollectionSort>(_onUpdateCollectionSort); on<_SetCollectionSort>(_onSetCollectionSort); + on<_SetItemCount>(_onSetItemCount); on<_SetError>(_onSetError); - _homeAlbumsSortSubscription = - prefController.homeAlbumsSort.distinct().listen((event) { + _subscriptions.add(prefController.homeAlbumsSort.distinct().listen((event) { add(_UpdateCollectionSort(collection_util.CollectionSort.values[event])); - }); + })); + _subscriptions.add(controller.stream.listen((event) { + for (final s in _itemSubscriptions) { + s.cancel(); + } + _itemSubscriptions.clear(); + for (final d in event.data) { + _itemSubscriptions.add(d.controller.countStream.listen((event) { + if (event != null) { + add(_SetItemCount(d.collection, event)); + } + })); + } + })); } @override Future close() { - _homeAlbumsSortSubscription?.cancel(); + for (final s in _itemSubscriptions) { + s.cancel(); + } + for (final s in _subscriptions) { + s.cancel(); + } return super.close(); } @@ -105,6 +123,13 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger { prefController.setHomeAlbumsSort(ev.sort.index); } + void _onSetItemCount(_SetItemCount ev, Emitter<_State> emit) { + _log.info(ev); + final next = Map.of(state.itemCounts); + next[ev.collection.id] = ev.value; + emit(state.copyWith(itemCounts: next)); + } + void _onSetError(_SetError ev, Emitter<_State> emit) { _log.info(ev); emit(state.copyWith(error: ExceptionEvent(ev.error, ev.stackTrace))); @@ -122,6 +147,7 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger { final CollectionsController controller; final PrefController prefController; - StreamSubscription? _homeAlbumsSortSubscription; + final _subscriptions = []; + final _itemSubscriptions = []; var _isHandlingError = false; } diff --git a/app/lib/widget/home_collections/state_event.dart b/app/lib/widget/home_collections/state_event.dart index 08f22632..612c8227 100644 --- a/app/lib/widget/home_collections/state_event.dart +++ b/app/lib/widget/home_collections/state_event.dart @@ -9,6 +9,7 @@ class _State { required this.isLoading, required this.transformedItems, required this.selectedItems, + required this.itemCounts, this.error, required this.removeError, }); @@ -20,6 +21,7 @@ class _State { isLoading: false, transformedItems: [], selectedItems: {}, + itemCounts: {}, removeError: null, ); } @@ -32,6 +34,7 @@ class _State { final bool isLoading; final List<_Item> transformedItems; final Set<_Item> selectedItems; + final Map itemCounts; final ExceptionEvent? error; final ExceptionEvent? removeError; @@ -112,6 +115,17 @@ class _SetCollectionSort implements _Event { final collection_util.CollectionSort sort; } +@toString +class _SetItemCount implements _Event { + const _SetItemCount(this.collection, this.value); + + @override + String toString() => _$toString(); + + final Collection collection; + final int value; +} + @toString class _SetError implements _Event { const _SetError(this.error, [this.stackTrace]); diff --git a/app/lib/widget/home_collections/type.dart b/app/lib/widget/home_collections/type.dart index 20737baa..cc5e91a4 100644 --- a/app/lib/widget/home_collections/type.dart +++ b/app/lib/widget/home_collections/type.dart @@ -11,9 +11,6 @@ enum _ItemType { class _Item implements SelectableItemMetadata { _Item(this.collection) : isShared = collection.shares.isNotEmpty || !collection.isOwned { - if (collection.count != null) { - _subtitle = L10n.global().albumSize(collection.count!); - } try { _coverUrl = collection.getCoverUrl(k.coverSize, k.coverSize); } catch (e, stackTrace) { @@ -35,7 +32,15 @@ class _Item implements SelectableItemMetadata { String get name => collection.name; - String? get subtitle => _subtitle; + String? getSubtitle({ + int? itemCountOverride, + }) { + if (collection.count != null) { + return L10n.global().albumSize(itemCountOverride ?? collection.count!); + } else { + return null; + } + } String? get coverUrl => _coverUrl; @@ -64,7 +69,6 @@ class _Item implements SelectableItemMetadata { final Collection collection; final bool isShared; - String? _subtitle; String? _coverUrl; late _ItemType _itemType; } diff --git a/app/lib/widget/home_collections/view.dart b/app/lib/widget/home_collections/view.dart index 13f9d362..bc4caf5d 100644 --- a/app/lib/widget/home_collections/view.dart +++ b/app/lib/widget/home_collections/view.dart @@ -129,6 +129,7 @@ class _ItemView extends StatelessWidget { const _ItemView({ required this.account, required this.item, + this.collectionItemCountOverride, }); @override @@ -152,7 +153,8 @@ class _ItemView extends StatelessWidget { if (item.isShared) { subtitle = "${L10n.global().albumSharedLabel} | "; } - subtitle += item.subtitle ?? ""; + subtitle += + item.getSubtitle(itemCountOverride: collectionItemCountOverride) ?? ""; return CollectionGridItem( cover: _CollectionCover( account: account, @@ -166,6 +168,7 @@ class _ItemView extends StatelessWidget { final Account account; final _Item item; + final int? collectionItemCountOverride; } class _CollectionCover extends StatelessWidget {