Workaround memory leak in bloc

This commit is contained in:
Ming Ming 2024-06-18 00:04:53 +08:00
parent 8d75ab7967
commit 68b4273bfa
19 changed files with 133 additions and 46 deletions

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/single_child_widget.dart'; import 'package:provider/single_child_widget.dart';
@ -58,3 +60,42 @@ extension BlocExtension<E, S> on Bloc<E, S> {
} }
} }
} }
class _BlocForEachObj {
const _BlocForEachObj(this.subscription, this.completer);
final StreamSubscription subscription;
final Completer completer;
}
mixin BlocForEachMixin<E, S> implements Bloc<E, S> {
@override
Future<void> close() async {
for (final e in _forEaches) {
unawaited(e.subscription.cancel());
e.completer.complete();
}
}
// The original emit.forEach is causing the internal eventController in Bloc
// to deadlock when closing, use this instead
Future<void> forEach<T>(
Emitter<S> emit,
Stream<T> stream, {
required S Function(T data) onData,
S Function(Object error, StackTrace stackTrace)? onError,
}) async {
final completer = Completer();
final subscription = stream.listen((event) {
emit(onData(event));
}, onError: (e, stackTrace) {
if (onError != null) {
emit(onError(e, stackTrace));
}
});
_forEaches.add(_BlocForEachObj(subscription, completer));
return completer.future;
}
final _forEaches = <_BlocForEachObj>[];
}

View file

@ -1,7 +1,8 @@
part of '../archive_browser.dart'; part of '../archive_browser.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.filesController, required this.filesController,
@ -58,7 +59,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadItems ev, Emitter<_State> emit) { Future<void> _onLoad(_LoadItems ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
unawaited(filesController.queryByArchived()); unawaited(filesController.queryByArchived());
return emit.forEach<FilesStreamEvent>( return forEach(
emit,
filesController.stream, filesController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
files: data.data, files: data.data,

View file

@ -1,7 +1,8 @@
part of '../collection_browser.dart'; part of '../collection_browser.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required DiContainer container, required DiContainer container,
required this.account, required this.account,
@ -121,7 +122,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadItems ev, Emitter<_State> emit) async { Future<void> _onLoad(_LoadItems ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<CollectionItemStreamData>( forEach(
emit,
itemsController.stream, itemsController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
items: _filterItems(data.items, state.itemsWhitelist), items: _filterItems(data.items, state.itemsWhitelist),
@ -136,7 +138,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
); );
}, },
), ),
emit.forEach<FilesStreamEvent>( forEach(
emit,
filesController.stream, filesController.stream,
onData: (data) { onData: (data) {
final whitelist = HashSet.of(data.dataMap.keys); final whitelist = HashSet.of(data.dataMap.keys);

View file

@ -1,7 +1,8 @@
part of '../collection_picker.dart'; part of '../collection_picker.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.controller, required this.controller,
@ -31,7 +32,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadCollections ev, Emitter<_State> emit) async { Future<void> _onLoad(_LoadCollections ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
return emit.forEach<CollectionStreamEvent>( return forEach(
emit,
controller.stream, controller.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
collections: data.data.map((e) => e.collection).toList(), collections: data.data.map((e) => e.collection).toList(),

View file

@ -1,7 +1,8 @@
part of '../home_collections.dart'; part of '../home_collections.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.controller, required this.controller,
@ -69,7 +70,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadCollections ev, Emitter<_State> emit) async { Future<void> _onLoad(_LoadCollections ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
return emit.forEach<CollectionStreamEvent>( return forEach(
emit,
controller.stream, controller.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
collections: data.data.map((d) => d.collection).toList(), collections: data.data.map((d) => d.collection).toList(),

View file

@ -1,7 +1,8 @@
part of '../home_photos2.dart'; part of '../home_photos2.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc( _Bloc(
this._c, { this._c, {
required this.account, required this.account,
@ -138,7 +139,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadItems ev, Emitter<_State> emit) async { Future<void> _onLoad(_LoadItems ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<FilesSummaryStreamEvent>( forEach(
emit,
filesController.summaryStream, filesController.summaryStream,
onData: (data) { onData: (data) {
if (data.summary.items.isEmpty && _isInitialLoad) { if (data.summary.items.isEmpty && _isInitialLoad) {
@ -157,7 +159,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
); );
}, },
), ),
emit.forEach<TimelineStreamEvent>( forEach(
emit,
filesController.timelineStream, filesController.timelineStream,
onData: (data) { onData: (data) {
if (!data.isDummy && _isInitialLoad) { if (!data.isDummy && _isInitialLoad) {

View file

@ -1,7 +1,8 @@
part of '../people_browser.dart'; part of '../people_browser.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.personsController, required this.personsController,
@ -16,7 +17,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadPersons ev, Emitter<_State> emit) { Future<void> _onLoad(_LoadPersons ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
return emit.forEach<PersonStreamEvent>( return forEach(
emit,
personsController.stream, personsController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
persons: data.data, persons: data.data,

View file

@ -1,7 +1,8 @@
part of '../places_browser.dart'; part of '../places_browser.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.placesController, required this.placesController,
@ -16,7 +17,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoad(_LoadPlaces ev, Emitter<_State> emit) { Future<void> _onLoad(_LoadPlaces ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
return emit.forEach<PlaceStreamEvent>( return forEach(
emit,
placesController.stream, placesController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
places: data.data, places: data.data,

View file

@ -1,7 +1,8 @@
part of '../search_landing.dart'; part of '../search_landing.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.personsController, required this.personsController,
@ -18,7 +19,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoadPersons(_LoadPersons ev, Emitter<_State> emit) { Future<void> _onLoadPersons(_LoadPersons ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
return emit.forEach<PersonStreamEvent>( return forEach(
emit,
personsController.stream, personsController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
persons: data.data, persons: data.data,
@ -54,7 +56,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onLoadPlaces(_LoadPlaces ev, Emitter<_State> emit) { Future<void> _onLoadPlaces(_LoadPlaces ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
return emit.forEach<PlaceStreamEvent>( return forEach(
emit,
placesController.stream, placesController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
places: data.data, places: data.data,

View file

@ -1,7 +1,8 @@
part of '../collection_settings.dart'; part of '../collection_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
@ -16,7 +17,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
return emit.forEach<bool>( return forEach(
emit,
prefController.isAlbumBrowserShowDateChange, prefController.isAlbumBrowserShowDateChange,
onData: (data) => state.copyWith(isBrowserShowDate: data), onData: (data) => state.copyWith(isBrowserShowDate: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../enhancement_settings.dart'; part of '../enhancement_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
@ -20,7 +21,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( forEach(
emit,
prefController.isSaveEditResultToServerChange, prefController.isSaveEditResultToServerChange,
onData: (data) => state.copyWith(isSaveEditResultToServer: data), onData: (data) => state.copyWith(isSaveEditResultToServer: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -28,7 +30,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<SizeInt>( forEach(
emit,
prefController.enhanceMaxSizeChange, prefController.enhanceMaxSizeChange,
onData: (data) => state.copyWith(maxSize: data), onData: (data) => state.copyWith(maxSize: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../language_settings.dart'; part of '../language_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State.init( }) : super(_State.init(
@ -30,7 +31,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) { Future<void> _onInit(_Init ev, Emitter<_State> emit) {
_log.info(ev); _log.info(ev);
return emit.forEach<language_util.AppLanguage>( return forEach(
emit,
prefController.languageChange, prefController.languageChange,
onData: (data) => state.copyWith(selected: data), onData: (data) => state.copyWith(selected: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../metadata_settings.dart'; part of '../metadata_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
@ -19,7 +20,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( forEach(
emit,
prefController.isEnableExifChange, prefController.isEnableExifChange,
onData: (data) => state.copyWith(isEnable: data), onData: (data) => state.copyWith(isEnable: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -27,7 +29,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<bool>( forEach(
emit,
prefController.shouldProcessExifWifiOnlyChange, prefController.shouldProcessExifWifiOnlyChange,
onData: (data) => state.copyWith(isWifiOnly: data), onData: (data) => state.copyWith(isWifiOnly: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../misc_settings.dart'; part of '../misc_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
required this.securePrefController, required this.securePrefController,
@ -19,7 +20,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( forEach(
emit,
prefController.isDoubleTapExitChange, prefController.isDoubleTapExitChange,
onData: (data) => state.copyWith(isDoubleTapExit: data), onData: (data) => state.copyWith(isDoubleTapExit: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -27,7 +29,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<ProtectedPageAuthType?>( forEach(
emit,
securePrefController.protectedPageAuthTypeChange, securePrefController.protectedPageAuthTypeChange,
onData: (data) => state.copyWith(appLockType: data), onData: (data) => state.copyWith(appLockType: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../photos_settings.dart'; part of '../photos_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
required this.accountPrefController, required this.accountPrefController,
@ -20,7 +21,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( forEach(
emit,
accountPrefController.isEnableMemoryAlbumChange, accountPrefController.isEnableMemoryAlbumChange,
onData: (data) => state.copyWith(isEnableMemories: data), onData: (data) => state.copyWith(isEnableMemories: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -28,7 +30,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<int>( forEach(
emit,
prefController.memoriesRangeChange, prefController.memoriesRangeChange,
onData: (data) => state.copyWith(memoriesRange: data), onData: (data) => state.copyWith(memoriesRange: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../theme_settings.dart'; part of '../theme_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
@ -22,7 +23,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<bool>( forEach(
emit,
prefController.isFollowSystemThemeChange, prefController.isFollowSystemThemeChange,
onData: (data) => state.copyWith(isFollowSystemTheme: data), onData: (data) => state.copyWith(isFollowSystemTheme: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -30,7 +32,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<bool>( forEach(
emit,
prefController.isUseBlackInDarkThemeChange, prefController.isUseBlackInDarkThemeChange,
onData: (data) => state.copyWith(isUseBlackInDarkTheme: data), onData: (data) => state.copyWith(isUseBlackInDarkTheme: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -38,7 +41,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<Color?>( forEach(
emit,
prefController.seedColorChange, prefController.seedColorChange,
onData: (data) => state.copyWith(seedColor: data?.value), onData: (data) => state.copyWith(seedColor: data?.value),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -46,7 +50,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<Color?>( forEach(
emit,
prefController.secondarySeedColorChange, prefController.secondarySeedColorChange,
onData: (data) => state.copyWith(secondarySeedColor: data?.value), onData: (data) => state.copyWith(secondarySeedColor: data?.value),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -1,7 +1,8 @@
part of '../viewer_settings.dart'; part of '../viewer_settings.dart';
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> with BlocLogger { class _Bloc extends Bloc<_Event, _State>
with BlocLogger, BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.prefController, required this.prefController,
}) : super(_State( }) : super(_State(
@ -21,7 +22,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
Future<void> _onInit(_Init ev, Emitter<_State> emit) async { Future<void> _onInit(_Init ev, Emitter<_State> emit) async {
_log.info(ev); _log.info(ev);
await Future.wait([ await Future.wait([
emit.forEach<int>( forEach(
emit,
prefController.viewerScreenBrightnessChange, prefController.viewerScreenBrightnessChange,
onData: (data) => state.copyWith(screenBrightness: data), onData: (data) => state.copyWith(screenBrightness: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -29,7 +31,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<bool>( forEach(
emit,
prefController.isViewerForceRotationChange, prefController.isViewerForceRotationChange,
onData: (data) => state.copyWith(isForceRotation: data), onData: (data) => state.copyWith(isForceRotation: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {
@ -37,7 +40,8 @@ class _Bloc extends Bloc<_Event, _State> with BlocLogger {
return state.copyWith(error: ExceptionEvent(e, stackTrace)); return state.copyWith(error: ExceptionEvent(e, stackTrace));
}, },
), ),
emit.forEach<GpsMapProvider>( forEach(
emit,
prefController.gpsMapProviderChange, prefController.gpsMapProviderChange,
onData: (data) => state.copyWith(gpsMapProvider: data), onData: (data) => state.copyWith(gpsMapProvider: data),
onError: (e, stackTrace) { onError: (e, stackTrace) {

View file

@ -9,6 +9,7 @@ import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/bloc_util.dart';
import 'package:nc_photos/controller/account_controller.dart'; import 'package:nc_photos/controller/account_controller.dart';
import 'package:nc_photos/controller/account_pref_controller.dart'; import 'package:nc_photos/controller/account_pref_controller.dart';
import 'package:nc_photos/controller/sharings_controller.dart'; import 'package:nc_photos/controller/sharings_controller.dart';

View file

@ -2,7 +2,7 @@ part of '../sharing_browser.dart';
/// List shares to be shown in [SharingBrowser] /// List shares to be shown in [SharingBrowser]
@npLog @npLog
class _Bloc extends Bloc<_Event, _State> { class _Bloc extends Bloc<_Event, _State> with BlocForEachMixin<_Event, _State> {
_Bloc({ _Bloc({
required this.account, required this.account,
required this.accountPrefController, required this.accountPrefController,
@ -21,7 +21,8 @@ class _Bloc extends Bloc<_Event, _State> {
"[_onInit] Failed while _importPotentialSharedAlbum", e, stackTrace); "[_onInit] Failed while _importPotentialSharedAlbum", e, stackTrace);
} }
unawaited(sharingsController.reload()); unawaited(sharingsController.reload());
return emit.forEach<SharingStreamEvent>( return forEach(
emit,
sharingsController.stream, sharingsController.stream,
onData: (data) => state.copyWith( onData: (data) => state.copyWith(
items: data.data, items: data.data,