leaks: imageinfo, notifiers

This commit is contained in:
Thibault Deckers 2024-06-17 21:03:55 +02:00
parent 4116a55f8d
commit 4e811cc37c
8 changed files with 27 additions and 7 deletions

View file

@ -113,11 +113,13 @@ class _CollectionGridContent extends StatefulWidget {
class _CollectionGridContentState extends State<_CollectionGridContent> {
final ValueNotifier<AvesEntry?> _focusedItemNotifier = ValueNotifier(null);
final ValueNotifier<bool> _isScrollingNotifier = ValueNotifier(false);
final ValueNotifier<AppMode> _selectingAppModeNotifier = ValueNotifier(AppMode.pickFilteredMediaInternal);
@override
void dispose() {
_focusedItemNotifier.dispose();
_isScrollingNotifier.dispose();
_selectingAppModeNotifier.dispose();
super.dispose();
}
@ -252,7 +254,7 @@ class _CollectionGridContentState extends State<_CollectionGridContent> {
if (selection.isSelecting) {
child = MultiProvider(
providers: [
ListenableProvider<ValueNotifier<AppMode>>.value(value: ValueNotifier(AppMode.pickFilteredMediaInternal)),
ListenableProvider<ValueNotifier<AppMode>>.value(value: _selectingAppModeNotifier),
ChangeNotifierProvider<Selection<AvesEntry>>.value(value: selection),
],
child: child,

View file

@ -64,6 +64,7 @@ class _AlbumPickPage extends StatefulWidget {
class _AlbumPickPageState extends State<_AlbumPickPage> {
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.pickFilterInternal);
CollectionSource get source => widget.source;
@ -93,13 +94,14 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
@override
void dispose() {
_appBarHeightNotifier.dispose();
_appModeNotifier.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListenableProvider<ValueNotifier<AppMode>>.value(
value: ValueNotifier(AppMode.pickFilterInternal),
value: _appModeNotifier,
child: Selector<Settings, (AlbumChipGroupFactor, ChipSortFactor)>(
selector: (context, s) => (s.albumGroupFactor, s.albumSortFactor),
builder: (context, s, child) {

View file

@ -29,20 +29,23 @@ class ItemPickPage extends StatefulWidget {
}
class _ItemPickPageState extends State<ItemPickPage> {
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.initialization);
CollectionLens get collection => widget.collection;
@override
void dispose() {
collection.dispose();
_appModeNotifier.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final liveFilter = collection.filters.firstWhereOrNull((v) => v is QueryFilter && v.live) as QueryFilter?;
final mode = widget.canRemoveFilters ? AppMode.pickUnfilteredMediaInternal : AppMode.pickFilteredMediaInternal;
_appModeNotifier.value = widget.canRemoveFilters ? AppMode.pickUnfilteredMediaInternal : AppMode.pickFilteredMediaInternal;
return ListenableProvider<ValueNotifier<AppMode>>.value(
value: ValueNotifier(mode),
value: _appModeNotifier,
child: AvesScaffold(
body: SelectionProvider<AvesEntry>(
child: QueryProvider(

View file

@ -53,8 +53,10 @@ class _ImageHistogramState extends State<ImageHistogram> {
void _registerWidget(ImageHistogram widget) {
_imageStream = imageProvider.resolve(ImageConfiguration.empty);
_imageListener = ImageStreamListener((image, synchronousCall) {
_updateLevels(image);
_imageListener = ImageStreamListener((image, synchronousCall) async {
// implementer is responsible for disposing the provided `ImageInfo`
await _updateLevels(image);
image.dispose();
});
_imageStream?.addListener(_imageListener);
}

View file

@ -35,6 +35,7 @@ class SlideshowPage extends StatefulWidget {
}
class _SlideshowPageState extends State<SlideshowPage> {
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.slideshow);
late ViewerController _viewerController;
late CollectionLens _slideshowCollection;
AvesEntry? _initialEntry;
@ -51,6 +52,7 @@ class _SlideshowPageState extends State<SlideshowPage> {
@override
void dispose() {
_appModeNotifier.dispose();
_disposeViewerController();
super.dispose();
}
@ -59,7 +61,7 @@ class _SlideshowPageState extends State<SlideshowPage> {
Widget build(BuildContext context) {
final initialEntry = _initialEntry;
return ListenableProvider<ValueNotifier<AppMode>>.value(
value: ValueNotifier(AppMode.slideshow),
value: _appModeNotifier,
child: AvesScaffold(
body: initialEntry == null
? EmptyContent(

View file

@ -41,6 +41,7 @@ class _RasterImageViewState extends State<RasterImageView> {
ImageStream? _fullImageStream;
late ImageStreamListener _fullImageListener;
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
ImageInfo? _fullImageInfo;
AvesEntry get entry => widget.entry;
@ -101,10 +102,13 @@ class _RasterImageViewState extends State<RasterImageView> {
void _unregisterFullImage() {
_fullImageStream?.removeListener(_fullImageListener);
_fullImageStream = null;
_fullImageInfo?.dispose();
}
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
// implementer is responsible for disposing the provided `ImageInfo`
_unregisterFullImage();
_fullImageInfo = image;
_fullImageLoaded.value = true;
FullImageLoadedNotification(entry, fullImageProvider).dispatch(context);
}

View file

@ -37,6 +37,7 @@ class _VectorImageViewState extends State<VectorImageView> {
ImageStream? _fullImageStream;
late ImageStreamListener _fullImageListener;
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
ImageInfo? _fullImageInfo;
AvesEntry get entry => widget.entry;
@ -91,10 +92,13 @@ class _VectorImageViewState extends State<VectorImageView> {
void _unregisterFullImage() {
_fullImageStream?.removeListener(_fullImageListener);
_fullImageStream = null;
_fullImageInfo?.dispose();
}
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
// implementer is responsible for disposing the provided `ImageInfo`
_unregisterFullImage();
_fullImageInfo = image;
_fullImageLoaded.value = true;
}

View file

@ -47,6 +47,7 @@ abstract class AvesVideoController with ABRepeatMixin {
if (kFlutterMemoryAllocationsEnabled) {
FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this);
}
abRepeatNotifier.dispose();
_entry.visualChangeNotifier.removeListener(onVisualChanged);
await _savePlaybackState();
}