memory leak tracking & fixes
This commit is contained in:
parent
c5fde95c73
commit
506190f882
34 changed files with 146 additions and 38 deletions
|
@ -123,7 +123,6 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
_unregisterWidget(widget);
|
_unregisterWidget(widget);
|
||||||
_queryBarFocusNode.dispose();
|
_queryBarFocusNode.dispose();
|
||||||
_queryFocusRequestNotifier.removeListener(_onQueryFocusRequest);
|
_queryFocusRequestNotifier.removeListener(_onQueryFocusRequest);
|
||||||
_isSelectingNotifier.removeListener(_onActivityChanged);
|
|
||||||
_isSelectingNotifier.dispose();
|
_isSelectingNotifier.dispose();
|
||||||
_browseToSelectAnimation.dispose();
|
_browseToSelectAnimation.dispose();
|
||||||
_subscriptions
|
_subscriptions
|
||||||
|
|
|
@ -302,7 +302,7 @@ class _CollectionSectionedContentState extends State<_CollectionSectionedContent
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_appBarHeightNotifier.removeListener(_onAppBarHeightChanged);
|
_appBarHeightNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class FavouriteToggler extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FavouriteTogglerState extends State<FavouriteToggler> {
|
class _FavouriteTogglerState extends State<FavouriteToggler> {
|
||||||
final ValueNotifier<bool> isFavouriteNotifier = ValueNotifier(false);
|
final ValueNotifier<bool> _isFavouriteNotifier = ValueNotifier(false);
|
||||||
|
|
||||||
Set<AvesEntry> get entries => widget.entries;
|
Set<AvesEntry> get entries => widget.entries;
|
||||||
|
|
||||||
|
@ -53,14 +53,14 @@ class _FavouriteTogglerState extends State<FavouriteToggler> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
favourites.removeListener(_onChanged);
|
favourites.removeListener(_onChanged);
|
||||||
isFavouriteNotifier.dispose();
|
_isFavouriteNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ValueListenableBuilder<bool>(
|
return ValueListenableBuilder<bool>(
|
||||||
valueListenable: isFavouriteNotifier,
|
valueListenable: _isFavouriteNotifier,
|
||||||
builder: (context, isFavourite, child) {
|
builder: (context, isFavourite, child) {
|
||||||
if (widget.isMenuItem) {
|
if (widget.isMenuItem) {
|
||||||
return isFavourite
|
return isFavourite
|
||||||
|
@ -88,7 +88,7 @@ class _FavouriteTogglerState extends State<FavouriteToggler> {
|
||||||
favouriteSweeperIcon,
|
favouriteSweeperIcon,
|
||||||
color: context.select<AvesColorsData, Color>((v) => v.favourite),
|
color: context.select<AvesColorsData, Color>((v) => v.favourite),
|
||||||
),
|
),
|
||||||
toggledNotifier: isFavouriteNotifier,
|
toggledNotifier: _isFavouriteNotifier,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -97,7 +97,7 @@ class _FavouriteTogglerState extends State<FavouriteToggler> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onChanged() {
|
void _onChanged() {
|
||||||
isFavouriteNotifier.value = entries.isNotEmpty && entries.every((entry) => entry.isFavourite);
|
_isFavouriteNotifier.value = entries.isNotEmpty && entries.every((entry) => entry.isFavourite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class FavouriteTogglerCaption extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FavouriteTogglerCaptionState extends State<FavouriteTogglerCaption> {
|
class _FavouriteTogglerCaptionState extends State<FavouriteTogglerCaption> {
|
||||||
final ValueNotifier<bool> isFavouriteNotifier = ValueNotifier(false);
|
final ValueNotifier<bool> _isFavouriteNotifier = ValueNotifier(false);
|
||||||
|
|
||||||
Set<AvesEntry> get entries => widget.entries;
|
Set<AvesEntry> get entries => widget.entries;
|
||||||
|
|
||||||
|
@ -136,14 +136,14 @@ class _FavouriteTogglerCaptionState extends State<FavouriteTogglerCaption> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
favourites.removeListener(_onChanged);
|
favourites.removeListener(_onChanged);
|
||||||
isFavouriteNotifier.dispose();
|
_isFavouriteNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ValueListenableBuilder<bool>(
|
return ValueListenableBuilder<bool>(
|
||||||
valueListenable: isFavouriteNotifier,
|
valueListenable: _isFavouriteNotifier,
|
||||||
builder: (context, isFavourite, child) {
|
builder: (context, isFavourite, child) {
|
||||||
return CaptionedButtonText(
|
return CaptionedButtonText(
|
||||||
text: isFavourite ? context.l10n.entryActionRemoveFavourite : context.l10n.entryActionAddFavourite,
|
text: isFavourite ? context.l10n.entryActionRemoveFavourite : context.l10n.entryActionAddFavourite,
|
||||||
|
@ -154,6 +154,6 @@ class _FavouriteTogglerCaptionState extends State<FavouriteTogglerCaption> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onChanged() {
|
void _onChanged() {
|
||||||
isFavouriteNotifier.value = entries.isNotEmpty && entries.every((entry) => entry.isFavourite);
|
_isFavouriteNotifier.value = entries.isNotEmpty && entries.every((entry) => entry.isFavourite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,12 +391,15 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin {
|
||||||
return dateMillis == null || dateMillis == 0;
|
return dateMillis == null || dateMillis == 0;
|
||||||
}).toSet();
|
}).toSet();
|
||||||
if (undatedItems.isNotEmpty) {
|
if (undatedItems.isNotEmpty) {
|
||||||
if (!await showSkippableConfirmationDialog(
|
final confirmationDialogDelegate = MoveUndatedConfirmationDialogDelegate();
|
||||||
|
final confirmed = await showSkippableConfirmationDialog(
|
||||||
context: context,
|
context: context,
|
||||||
type: ConfirmationDialog.moveUndatedItems,
|
type: ConfirmationDialog.moveUndatedItems,
|
||||||
delegate: MoveUndatedConfirmationDialogDelegate(),
|
delegate: confirmationDialogDelegate,
|
||||||
confirmationButtonLabel: context.l10n.continueButtonLabel,
|
confirmationButtonLabel: context.l10n.continueButtonLabel,
|
||||||
)) return false;
|
);
|
||||||
|
confirmationDialogDelegate.dispose();
|
||||||
|
if (!confirmed) return false;
|
||||||
|
|
||||||
if (settings.setMetadataDateBeforeFileOp) {
|
if (settings.setMetadataDateBeforeFileOp) {
|
||||||
final entriesToDate = undatedItems.where((entry) => entry.canEditDate).toSet();
|
final entriesToDate = undatedItems.where((entry) => entry.canEditDate).toSet();
|
||||||
|
@ -461,6 +464,10 @@ class MoveUndatedConfirmationDialogDelegate extends ConfirmationDialogDelegate {
|
||||||
_setMetadataDate.value = settings.setMetadataDateBeforeFileOp;
|
_setMetadataDate.value = settings.setMetadataDateBeforeFileOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
_setMetadataDate.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Widget> build(BuildContext context) => [
|
List<Widget> build(BuildContext context) => [
|
||||||
Padding(
|
Padding(
|
||||||
|
|
|
@ -190,6 +190,7 @@ class _AvesFloatingBarState extends State<AvesFloatingBar> with RouteAware {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
AvesApp.pageRouteObserver.unsubscribe(this);
|
AvesApp.pageRouteObserver.unsubscribe(this);
|
||||||
|
_isBlurAllowedNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,12 @@ class _ThumbnailHighlightOverlayState extends State<ThumbnailHighlightOverlay> {
|
||||||
|
|
||||||
static const startAngle = pi * -3 / 4;
|
static const startAngle = pi * -3 / 4;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_highlightedNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final highlightInfo = context.watch<HighlightInfo>();
|
final highlightInfo = context.watch<HighlightInfo>();
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ThumbnailScroller extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ThumbnailScrollerState extends State<ThumbnailScroller> {
|
class _ThumbnailScrollerState extends State<ThumbnailScroller> {
|
||||||
final _cancellableNotifier = ValueNotifier(true);
|
final ValueNotifier<bool> _cancellableNotifier = ValueNotifier(true);
|
||||||
late ScrollController _scrollController;
|
late ScrollController _scrollController;
|
||||||
bool _isAnimating = false, _isScrolling = false;
|
bool _isAnimating = false, _isScrolling = false;
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ class _ThumbnailScrollerState extends State<ThumbnailScroller> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_unregisterWidget(widget);
|
_unregisterWidget(widget);
|
||||||
|
_cancellableNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_nameController.dispose();
|
_nameController.dispose();
|
||||||
|
_isValidNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,13 @@ class _SkippableConfirmationDialog extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SkippableConfirmationDialogState extends State<_SkippableConfirmationDialog> {
|
class _SkippableConfirmationDialogState extends State<_SkippableConfirmationDialog> {
|
||||||
final ValueNotifier<bool> _skip = ValueNotifier(false);
|
final ValueNotifier<bool> _skipNotifier = ValueNotifier(false);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_skipNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -127,10 +133,10 @@ class _SkippableConfirmationDialogState extends State<_SkippableConfirmationDial
|
||||||
scrollableContent: [
|
scrollableContent: [
|
||||||
...widget.delegate.build(context),
|
...widget.delegate.build(context),
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _skip,
|
valueListenable: _skipNotifier,
|
||||||
builder: (context, flag, child) => SwitchListTile(
|
builder: (context, flag, child) => SwitchListTile(
|
||||||
value: flag,
|
value: flag,
|
||||||
onChanged: (v) => _skip.value = v,
|
onChanged: (v) => _skipNotifier.value = v,
|
||||||
title: Text(context.l10n.doNotAskAgain),
|
title: Text(context.l10n.doNotAskAgain),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -139,7 +145,7 @@ class _SkippableConfirmationDialogState extends State<_SkippableConfirmationDial
|
||||||
const CancelButton(),
|
const CancelButton(),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_skip.value) {
|
if (_skipNotifier.value) {
|
||||||
_skipConfirmation(widget.type);
|
_skipConfirmation(widget.type);
|
||||||
}
|
}
|
||||||
Navigator.maybeOf(context)?.pop(true);
|
Navigator.maybeOf(context)?.pop(true);
|
||||||
|
|
|
@ -88,6 +88,8 @@ class _ConvertEntryDialogState extends State<ConvertEntryDialog> {
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_widthController.dispose();
|
_widthController.dispose();
|
||||||
_heightController.dispose();
|
_heightController.dispose();
|
||||||
|
_isValidNotifier.dispose();
|
||||||
|
_mimeTypeNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,13 @@ class _DurationDialogState extends State<DurationDialog> {
|
||||||
_seconds = ValueNotifier(seconds % secondsInMinute);
|
_seconds = ValueNotifier(seconds % secondsInMinute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_minutes.dispose();
|
||||||
|
_seconds.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MediaQueryDataProvider(
|
return MediaQueryDataProvider(
|
||||||
|
|
|
@ -60,6 +60,9 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_isValidNotifier.dispose();
|
_isValidNotifier.dispose();
|
||||||
|
_shiftHour.dispose();
|
||||||
|
_shiftMinute.dispose();
|
||||||
|
_shiftSign.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_latitudeController.dispose();
|
_latitudeController.dispose();
|
||||||
_longitudeController.dispose();
|
_longitudeController.dispose();
|
||||||
|
_isValidNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,12 @@ class _RemoveEntryMetadataDialogState extends State<RemoveEntryMetadataDialog> {
|
||||||
_validate();
|
_validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_isValidNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
|
|
|
@ -37,6 +37,7 @@ class _RenameEntryDialogState extends State<RenameEntryDialog> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_nameController.dispose();
|
_nameController.dispose();
|
||||||
|
_isValidNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,12 @@ class _AlbumPickPageState extends State<_AlbumPickPage> {
|
||||||
ChipSetAction.createVault,
|
ChipSetAction.createVault,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_appBarHeightNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
return ListenableProvider<ValueNotifier<AppMode>>.value(
|
||||||
|
|
|
@ -96,8 +96,10 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
||||||
_subscriptions
|
_subscriptions
|
||||||
..forEach((sub) => sub.cancel())
|
..forEach((sub) => sub.cancel())
|
||||||
..clear();
|
..clear();
|
||||||
_dotLocationNotifier.removeListener(_updateLocationInfo);
|
|
||||||
_mapController.dispose();
|
_mapController.dispose();
|
||||||
|
_isPageAnimatingNotifier.dispose();
|
||||||
|
_dotLocationNotifier.dispose();
|
||||||
|
_infoLocationNotifier.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,12 @@ class _TileViewDialogState<S, G, L> extends State<TileViewDialog<S, G, L>> with
|
||||||
_columnMax = columnRange.$2;
|
_columnMax = columnRange.$2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_columnCountNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
|
|
|
@ -111,7 +111,6 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_queryBarFocusNode.dispose();
|
_queryBarFocusNode.dispose();
|
||||||
_queryFocusRequestNotifier.removeListener(_onQueryFocusRequest);
|
_queryFocusRequestNotifier.removeListener(_onQueryFocusRequest);
|
||||||
_isSelectingNotifier.removeListener(_onActivityChanged);
|
|
||||||
_isSelectingNotifier.dispose();
|
_isSelectingNotifier.dispose();
|
||||||
_browseToSelectAnimation.dispose();
|
_browseToSelectAnimation.dispose();
|
||||||
_subscriptions
|
_subscriptions
|
||||||
|
|
|
@ -99,6 +99,12 @@ class FilterNavigationPage<T extends CollectionFilter, CSAD extends ChipSetActio
|
||||||
class _FilterNavigationPageState<T extends CollectionFilter, CSAD extends ChipSetActionDelegate<T>> extends State<FilterNavigationPage<T, CSAD>> {
|
class _FilterNavigationPageState<T extends CollectionFilter, CSAD extends ChipSetActionDelegate<T>> extends State<FilterNavigationPage<T, CSAD>> {
|
||||||
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
final ValueNotifier<double> _appBarHeightNotifier = ValueNotifier(0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_appBarHeightNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SelectionProvider<FilterGridItem<T>>(
|
return SelectionProvider<FilterGridItem<T>>(
|
||||||
|
|
|
@ -27,6 +27,12 @@ class _ChipHighlightOverlayState extends State<ChipHighlightOverlay> {
|
||||||
|
|
||||||
CollectionFilter get filter => widget.filter;
|
CollectionFilter get filter => widget.filter;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_highlightedNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final highlightInfo = context.watch<HighlightInfo>();
|
final highlightInfo = context.watch<HighlightInfo>();
|
||||||
|
|
|
@ -159,12 +159,18 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
||||||
_subscriptions
|
_subscriptions
|
||||||
..forEach((sub) => sub.cancel())
|
..forEach((sub) => sub.cancel())
|
||||||
..clear();
|
..clear();
|
||||||
_dotEntryNotifier.value?.metadataChangeNotifier.removeListener(_onMarkerEntryMetadataChanged);
|
|
||||||
_overlayAnimationController.dispose();
|
|
||||||
_overlayVisible.removeListener(_onOverlayVisibleChanged);
|
|
||||||
_mapController.dispose();
|
_mapController.dispose();
|
||||||
|
_isPageAnimatingNotifier.dispose();
|
||||||
_selectedIndexNotifier.dispose();
|
_selectedIndexNotifier.dispose();
|
||||||
regionCollection?.dispose();
|
_regionCollectionNotifier.value?.dispose();
|
||||||
|
_regionCollectionNotifier.dispose();
|
||||||
|
_dotLocationNotifier.dispose();
|
||||||
|
_dotEntryNotifier.value?.metadataChangeNotifier.removeListener(_onMarkerEntryMetadataChanged);
|
||||||
|
_dotEntryNotifier.dispose();
|
||||||
|
_overlayOpacityNotifier.dispose();
|
||||||
|
_overlayVisible.dispose();
|
||||||
|
_overlayAnimationController.dispose();
|
||||||
|
|
||||||
// provided collection should be a new instance specifically created
|
// provided collection should be a new instance specifically created
|
||||||
// for the `MapPage` widget, so it can be safely disposed here
|
// for the `MapPage` widget, so it can be safely disposed here
|
||||||
widget.collection.dispose();
|
widget.collection.dispose();
|
||||||
|
|
|
@ -104,7 +104,13 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_draggedQuickAction.dispose();
|
||||||
|
_draggedAvailableAction.dispose();
|
||||||
|
_quickActionHighlight.dispose();
|
||||||
|
_availableActionHighlight.dispose();
|
||||||
_quickActionsChangeNotifier.dispose();
|
_quickActionsChangeNotifier.dispose();
|
||||||
|
_availableActionPageController.dispose();
|
||||||
|
|
||||||
_stopLeavingTimer();
|
_stopLeavingTimer();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,12 @@ class _StatsPageState extends State<StatsPage> with FeedbackMixin, VaultAwareMix
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_isPageAnimatingNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final useTvLayout = settings.useTvLayout;
|
final useTvLayout = settings.useTvLayout;
|
||||||
|
|
|
@ -65,7 +65,7 @@ class ViewerController {
|
||||||
if (kFlutterMemoryAllocationsEnabled) {
|
if (kFlutterMemoryAllocationsEnabled) {
|
||||||
MemoryAllocations.instance.dispatchObjectDisposed(object: this);
|
MemoryAllocations.instance.dispatchObjectDisposed(object: this);
|
||||||
}
|
}
|
||||||
_autopilotNotifier.removeListener(_onAutopilotChanged);
|
_autopilotNotifier.dispose();
|
||||||
_clearAutopilotAnimations();
|
_clearAutopilotAnimations();
|
||||||
_stopPlayTimer();
|
_stopPlayTimer();
|
||||||
_streamController.close();
|
_streamController.close();
|
||||||
|
|
|
@ -61,6 +61,12 @@ class _XmpCardState extends State<XmpCard> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_indexNotifier.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final _isIndexed = isIndexed;
|
final _isIndexed = isIndexed;
|
||||||
|
|
|
@ -50,7 +50,8 @@ class _PanoramaPageState extends State<PanoramaPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_overlayVisible.removeListener(_onOverlayVisibleChanged);
|
_overlayVisible.dispose();
|
||||||
|
_sensorControl.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ class _RasterImageViewState extends State<RasterImageView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_fullImageLoaded.dispose();
|
||||||
_unregisterFullImage();
|
_unregisterFullImage();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ class _VectorImageViewState extends State<VectorImageView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_fullImageLoaded.dispose();
|
||||||
_unregisterFullImage();
|
_unregisterFullImage();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,10 +119,10 @@ class _EntryEditorState extends State<EntryEditor> with EntryViewControllerMixin
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
cleanEntryControllers(entry);
|
cleanEntryControllers(entry);
|
||||||
_viewerController.dispose();
|
_overlayVisible.dispose();
|
||||||
_videoActionDelegate.dispose();
|
|
||||||
_overlayAnimationController.dispose();
|
_overlayAnimationController.dispose();
|
||||||
_overlayVisible.removeListener(_onOverlayVisibleChanged);
|
_videoActionDelegate.dispose();
|
||||||
|
_viewerController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,17 @@ abstract class AvesVideoControllerFactory {
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
AvesVideoController buildController(
|
AvesVideoController buildController(
|
||||||
AvesEntryBase entry, {
|
AvesEntryBase entry, {
|
||||||
required PlaybackStateHandler playbackStateHandler,
|
required PlaybackStateHandler playbackStateHandler,
|
||||||
required VideoSettings settings,
|
required VideoSettings settings,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AvesVideoController {
|
abstract class AvesVideoController {
|
||||||
final AvesEntryBase _entry;
|
final AvesEntryBase _entry;
|
||||||
final PlaybackStateHandler playbackStateHandler;
|
final PlaybackStateHandler playbackStateHandler;
|
||||||
final VideoSettings settings;
|
final VideoSettings settings;
|
||||||
|
bool _disposed = false;
|
||||||
|
|
||||||
AvesEntryBase get entry => _entry;
|
AvesEntryBase get entry => _entry;
|
||||||
|
|
||||||
|
@ -41,6 +42,8 @@ abstract class AvesVideoController {
|
||||||
|
|
||||||
@mustCallSuper
|
@mustCallSuper
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
|
assert(!_disposed);
|
||||||
|
_disposed = true;
|
||||||
if (kFlutterMemoryAllocationsEnabled) {
|
if (kFlutterMemoryAllocationsEnabled) {
|
||||||
MemoryAllocations.instance.dispatchObjectDisposed(object: this);
|
MemoryAllocations.instance.dispatchObjectDisposed(object: this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,12 +80,19 @@ class IjkVideoController extends AvesVideoController {
|
||||||
@override
|
@override
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
await super.dispose();
|
await super.dispose();
|
||||||
|
|
||||||
_initialPlayTimer?.cancel();
|
_initialPlayTimer?.cancel();
|
||||||
_stopListening();
|
_stopListening();
|
||||||
await _valueStreamController.close();
|
await _valueStreamController.close();
|
||||||
await _timedTextStreamController.close();
|
await _timedTextStreamController.close();
|
||||||
await _instance.release();
|
await _instance.release();
|
||||||
|
|
||||||
_completedNotifier.dispose();
|
_completedNotifier.dispose();
|
||||||
|
canCaptureFrameNotifier.dispose();
|
||||||
|
canMuteNotifier.dispose();
|
||||||
|
canSetSpeedNotifier.dispose();
|
||||||
|
canSelectStreamNotifier.dispose();
|
||||||
|
sarNotifier.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startListening() {
|
void _startListening() {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import 'package:media_kit_video/media_kit_video.dart';
|
||||||
class MpvVideoController extends AvesVideoController {
|
class MpvVideoController extends AvesVideoController {
|
||||||
late Player _instance;
|
late Player _instance;
|
||||||
late VideoStatus _status;
|
late VideoStatus _status;
|
||||||
bool _disposed = false, _firstFrameRendered = false;
|
bool _firstFrameRendered = false;
|
||||||
final ValueNotifier<VideoController?> _controllerNotifier = ValueNotifier(null);
|
final ValueNotifier<VideoController?> _controllerNotifier = ValueNotifier(null);
|
||||||
final List<StreamSubscription> _subscriptions = [];
|
final List<StreamSubscription> _subscriptions = [];
|
||||||
final StreamController<VideoStatus> _statusStreamController = StreamController.broadcast();
|
final StreamController<VideoStatus> _statusStreamController = StreamController.broadcast();
|
||||||
|
@ -63,16 +63,21 @@ class MpvVideoController extends AvesVideoController {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
assert(!_disposed);
|
|
||||||
_disposed = true;
|
|
||||||
await super.dispose();
|
await super.dispose();
|
||||||
|
|
||||||
_stopListening();
|
_stopListening();
|
||||||
_stopStreamFetchTimer();
|
_stopStreamFetchTimer();
|
||||||
await _statusStreamController.close();
|
await _statusStreamController.close();
|
||||||
await _timedTextStreamController.close();
|
await _timedTextStreamController.close();
|
||||||
await _instance.dispose();
|
await _instance.dispose();
|
||||||
_controllerNotifier.dispose();
|
_controllerNotifier.dispose();
|
||||||
|
|
||||||
_completedNotifier.dispose();
|
_completedNotifier.dispose();
|
||||||
|
canCaptureFrameNotifier.dispose();
|
||||||
|
canMuteNotifier.dispose();
|
||||||
|
canSetSpeedNotifier.dispose();
|
||||||
|
canSelectStreamNotifier.dispose();
|
||||||
|
sarNotifier.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startListening() {
|
void _startListening() {
|
||||||
|
|
Loading…
Reference in a new issue