leaks: imageinfo, notifiers
This commit is contained in:
parent
4116a55f8d
commit
4e811cc37c
8 changed files with 27 additions and 7 deletions
|
@ -113,11 +113,13 @@ class _CollectionGridContent extends StatefulWidget {
|
||||||
class _CollectionGridContentState extends State<_CollectionGridContent> {
|
class _CollectionGridContentState extends State<_CollectionGridContent> {
|
||||||
final ValueNotifier<AvesEntry?> _focusedItemNotifier = ValueNotifier(null);
|
final ValueNotifier<AvesEntry?> _focusedItemNotifier = ValueNotifier(null);
|
||||||
final ValueNotifier<bool> _isScrollingNotifier = ValueNotifier(false);
|
final ValueNotifier<bool> _isScrollingNotifier = ValueNotifier(false);
|
||||||
|
final ValueNotifier<AppMode> _selectingAppModeNotifier = ValueNotifier(AppMode.pickFilteredMediaInternal);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_focusedItemNotifier.dispose();
|
_focusedItemNotifier.dispose();
|
||||||
_isScrollingNotifier.dispose();
|
_isScrollingNotifier.dispose();
|
||||||
|
_selectingAppModeNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +254,7 @@ class _CollectionGridContentState extends State<_CollectionGridContent> {
|
||||||
if (selection.isSelecting) {
|
if (selection.isSelecting) {
|
||||||
child = MultiProvider(
|
child = MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
ListenableProvider<ValueNotifier<AppMode>>.value(value: ValueNotifier(AppMode.pickFilteredMediaInternal)),
|
ListenableProvider<ValueNotifier<AppMode>>.value(value: _selectingAppModeNotifier),
|
||||||
ChangeNotifierProvider<Selection<AvesEntry>>.value(value: selection),
|
ChangeNotifierProvider<Selection<AvesEntry>>.value(value: selection),
|
||||||
],
|
],
|
||||||
child: child,
|
child: child,
|
||||||
|
|
|
@ -64,6 +64,7 @@ class _AlbumPickPage extends StatefulWidget {
|
||||||
|
|
||||||
class _AlbumPickPageState extends State<_AlbumPickPage> {
|
class _AlbumPickPageState extends State<_AlbumPickPage> {
|
||||||
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
||||||
|
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.pickFilterInternal);
|
||||||
|
|
||||||
CollectionSource get source => widget.source;
|
CollectionSource get source => widget.source;
|
||||||
|
|
||||||
|
@ -93,13 +94,14 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_appBarHeightNotifier.dispose();
|
_appBarHeightNotifier.dispose();
|
||||||
|
_appModeNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
||||||
value: ValueNotifier(AppMode.pickFilterInternal),
|
value: _appModeNotifier,
|
||||||
child: Selector<Settings, (AlbumChipGroupFactor, ChipSortFactor)>(
|
child: Selector<Settings, (AlbumChipGroupFactor, ChipSortFactor)>(
|
||||||
selector: (context, s) => (s.albumGroupFactor, s.albumSortFactor),
|
selector: (context, s) => (s.albumGroupFactor, s.albumSortFactor),
|
||||||
builder: (context, s, child) {
|
builder: (context, s, child) {
|
||||||
|
|
|
@ -29,20 +29,23 @@ class ItemPickPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ItemPickPageState extends State<ItemPickPage> {
|
class _ItemPickPageState extends State<ItemPickPage> {
|
||||||
|
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.initialization);
|
||||||
|
|
||||||
CollectionLens get collection => widget.collection;
|
CollectionLens get collection => widget.collection;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
collection.dispose();
|
collection.dispose();
|
||||||
|
_appModeNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final liveFilter = collection.filters.firstWhereOrNull((v) => v is QueryFilter && v.live) as QueryFilter?;
|
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(
|
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
||||||
value: ValueNotifier(mode),
|
value: _appModeNotifier,
|
||||||
child: AvesScaffold(
|
child: AvesScaffold(
|
||||||
body: SelectionProvider<AvesEntry>(
|
body: SelectionProvider<AvesEntry>(
|
||||||
child: QueryProvider(
|
child: QueryProvider(
|
||||||
|
|
|
@ -53,8 +53,10 @@ class _ImageHistogramState extends State<ImageHistogram> {
|
||||||
|
|
||||||
void _registerWidget(ImageHistogram widget) {
|
void _registerWidget(ImageHistogram widget) {
|
||||||
_imageStream = imageProvider.resolve(ImageConfiguration.empty);
|
_imageStream = imageProvider.resolve(ImageConfiguration.empty);
|
||||||
_imageListener = ImageStreamListener((image, synchronousCall) {
|
_imageListener = ImageStreamListener((image, synchronousCall) async {
|
||||||
_updateLevels(image);
|
// implementer is responsible for disposing the provided `ImageInfo`
|
||||||
|
await _updateLevels(image);
|
||||||
|
image.dispose();
|
||||||
});
|
});
|
||||||
_imageStream?.addListener(_imageListener);
|
_imageStream?.addListener(_imageListener);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ class SlideshowPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SlideshowPageState extends State<SlideshowPage> {
|
class _SlideshowPageState extends State<SlideshowPage> {
|
||||||
|
final ValueNotifier<AppMode> _appModeNotifier = ValueNotifier(AppMode.slideshow);
|
||||||
late ViewerController _viewerController;
|
late ViewerController _viewerController;
|
||||||
late CollectionLens _slideshowCollection;
|
late CollectionLens _slideshowCollection;
|
||||||
AvesEntry? _initialEntry;
|
AvesEntry? _initialEntry;
|
||||||
|
@ -51,6 +52,7 @@ class _SlideshowPageState extends State<SlideshowPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_appModeNotifier.dispose();
|
||||||
_disposeViewerController();
|
_disposeViewerController();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
@ -59,7 +61,7 @@ class _SlideshowPageState extends State<SlideshowPage> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final initialEntry = _initialEntry;
|
final initialEntry = _initialEntry;
|
||||||
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
||||||
value: ValueNotifier(AppMode.slideshow),
|
value: _appModeNotifier,
|
||||||
child: AvesScaffold(
|
child: AvesScaffold(
|
||||||
body: initialEntry == null
|
body: initialEntry == null
|
||||||
? EmptyContent(
|
? EmptyContent(
|
||||||
|
|
|
@ -41,6 +41,7 @@ class _RasterImageViewState extends State<RasterImageView> {
|
||||||
ImageStream? _fullImageStream;
|
ImageStream? _fullImageStream;
|
||||||
late ImageStreamListener _fullImageListener;
|
late ImageStreamListener _fullImageListener;
|
||||||
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
|
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
|
||||||
|
ImageInfo? _fullImageInfo;
|
||||||
|
|
||||||
AvesEntry get entry => widget.entry;
|
AvesEntry get entry => widget.entry;
|
||||||
|
|
||||||
|
@ -101,10 +102,13 @@ class _RasterImageViewState extends State<RasterImageView> {
|
||||||
void _unregisterFullImage() {
|
void _unregisterFullImage() {
|
||||||
_fullImageStream?.removeListener(_fullImageListener);
|
_fullImageStream?.removeListener(_fullImageListener);
|
||||||
_fullImageStream = null;
|
_fullImageStream = null;
|
||||||
|
_fullImageInfo?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
|
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
|
||||||
|
// implementer is responsible for disposing the provided `ImageInfo`
|
||||||
_unregisterFullImage();
|
_unregisterFullImage();
|
||||||
|
_fullImageInfo = image;
|
||||||
_fullImageLoaded.value = true;
|
_fullImageLoaded.value = true;
|
||||||
FullImageLoadedNotification(entry, fullImageProvider).dispatch(context);
|
FullImageLoadedNotification(entry, fullImageProvider).dispatch(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ class _VectorImageViewState extends State<VectorImageView> {
|
||||||
ImageStream? _fullImageStream;
|
ImageStream? _fullImageStream;
|
||||||
late ImageStreamListener _fullImageListener;
|
late ImageStreamListener _fullImageListener;
|
||||||
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
|
final ValueNotifier<bool> _fullImageLoaded = ValueNotifier(false);
|
||||||
|
ImageInfo? _fullImageInfo;
|
||||||
|
|
||||||
AvesEntry get entry => widget.entry;
|
AvesEntry get entry => widget.entry;
|
||||||
|
|
||||||
|
@ -91,10 +92,13 @@ class _VectorImageViewState extends State<VectorImageView> {
|
||||||
void _unregisterFullImage() {
|
void _unregisterFullImage() {
|
||||||
_fullImageStream?.removeListener(_fullImageListener);
|
_fullImageStream?.removeListener(_fullImageListener);
|
||||||
_fullImageStream = null;
|
_fullImageStream = null;
|
||||||
|
_fullImageInfo?.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
|
void _onFullImageCompleted(ImageInfo image, bool synchronousCall) {
|
||||||
|
// implementer is responsible for disposing the provided `ImageInfo`
|
||||||
_unregisterFullImage();
|
_unregisterFullImage();
|
||||||
|
_fullImageInfo = image;
|
||||||
_fullImageLoaded.value = true;
|
_fullImageLoaded.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ abstract class AvesVideoController with ABRepeatMixin {
|
||||||
if (kFlutterMemoryAllocationsEnabled) {
|
if (kFlutterMemoryAllocationsEnabled) {
|
||||||
FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this);
|
FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this);
|
||||||
}
|
}
|
||||||
|
abRepeatNotifier.dispose();
|
||||||
_entry.visualChangeNotifier.removeListener(onVisualChanged);
|
_entry.visualChangeNotifier.removeListener(onVisualChanged);
|
||||||
await _savePlaybackState();
|
await _savePlaybackState();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue