Skip to content

Commit

Permalink
memory leak fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
deckerst committed Nov 14, 2023
1 parent 5b73c86 commit 3909b92
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 47 deletions.
15 changes: 9 additions & 6 deletions lib/widgets/common/action_controls/togglers/mute.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/basic/popup/menu_row.dart';
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:aves_video/aves_video.dart';
import 'package:flutter/material.dart';

Expand All @@ -25,9 +26,10 @@ class MuteToggler extends StatelessWidget {

@override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
valueListenable: controller?.canMuteNotifier ?? ValueNotifier(false),
builder: (context, canDo, child) {
return NullableValueListenableBuilder<bool>(
valueListenable: controller?.canMuteNotifier,
builder: (context, value, child) {
final canDo = value ?? false;
return StreamBuilder<double>(
stream: controller?.volumeStream ?? Stream.value(1.0),
builder: (context, snapshot) {
Expand Down Expand Up @@ -66,9 +68,10 @@ class MuteTogglerCaption extends StatelessWidget {

@override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
valueListenable: controller?.canMuteNotifier ?? ValueNotifier(false),
builder: (context, canDo, child) {
return NullableValueListenableBuilder<bool>(
valueListenable: controller?.canMuteNotifier,
builder: (context, value, child) {
final canDo = value ?? false;
return StreamBuilder<double>(
stream: controller?.volumeStream ?? Stream.value(1.0),
builder: (context, snapshot) {
Expand Down
8 changes: 5 additions & 3 deletions lib/widgets/common/basic/insets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/extensions/media_query.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/common/tile_extent_controller.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

Expand Down Expand Up @@ -151,9 +152,10 @@ class SafeCutoutArea extends StatelessWidget {
return ValueListenableBuilder<EdgeInsets>(
valueListenable: AvesApp.cutoutInsetsNotifier,
builder: (context, cutoutInsets, child) {
return ValueListenableBuilder<double>(
valueListenable: animation ?? ValueNotifier(1),
builder: (context, factor, child) {
return NullableValueListenableBuilder<double>(
valueListenable: animation,
builder: (context, value, child) {
final double factor = value ?? 1.0;
final effectiveInsets = cutoutInsets * factor;
return Padding(
padding: effectiveInsets,
Expand Down
12 changes: 7 additions & 5 deletions lib/widgets/common/map/leaflet/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:aves/widgets/common/map/leaflet/latlng_tween.dart' as llt;
import 'package:aves/widgets/common/map/leaflet/scale_layer.dart';
import 'package:aves/widgets/common/map/leaflet/tile_layers.dart';
import 'package:aves_map/aves_map.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
Expand Down Expand Up @@ -172,8 +173,8 @@ class _EntryLeafletMapState<T> extends State<EntryLeafletMap<T>> with TickerProv
rotate: true,
alignment: Alignment.bottomCenter,
),
ValueListenableBuilder<LatLng?>(
valueListenable: widget.dotLocationNotifier ?? ValueNotifier(null),
NullableValueListenableBuilder<LatLng?>(
valueListenable: widget.dotLocationNotifier,
builder: (context, dotLocation, child) => MarkerLayer(
markers: [
if (dotLocation != null)
Expand Down Expand Up @@ -214,9 +215,10 @@ class _EntryLeafletMapState<T> extends State<EntryLeafletMap<T>> with TickerProv
final corner2 = overlayEntry.bottomRight;
if (corner1 == null || corner2 == null) return const SizedBox();

return ValueListenableBuilder<double>(
valueListenable: widget.overlayOpacityNotifier ?? ValueNotifier(1),
builder: (context, overlayOpacity, child) {
return NullableValueListenableBuilder<double>(
valueListenable: widget.overlayOpacityNotifier,
builder: (context, value, child) {
final double overlayOpacity = value ?? 1.0;
return OverlayImageLayer(
overlayImages: [
OverlayImage(
Expand Down
4 changes: 2 additions & 2 deletions lib/widgets/viewer/overlay/thumbnail_preview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ViewerThumbnailPreview extends StatefulWidget {
}

class _ViewerThumbnailPreviewState extends State<ViewerThumbnailPreview> {
final ValueNotifier<int> _entryIndexNotifier = ValueNotifier(0);
late final ValueNotifier<int> _entryIndexNotifier;
final Debouncer _debouncer = Debouncer(delay: ADurations.viewerThumbnailScrollDebounceDelay);

List<AvesEntry> get entries => widget.entries;
Expand All @@ -34,7 +34,7 @@ class _ViewerThumbnailPreviewState extends State<ViewerThumbnailPreview> {
@override
void initState() {
super.initState();
_entryIndexNotifier.value = widget.displayedIndex;
_entryIndexNotifier = ValueNotifier(widget.displayedIndex);
_entryIndexNotifier.addListener(_onScrollerIndexChanged);
}

Expand Down
22 changes: 13 additions & 9 deletions lib/widgets/viewer/overlay/viewer_buttons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import 'package:aves/widgets/viewer/action/entry_action_delegate.dart';
import 'package:aves/widgets/viewer/controls/notifications.dart';
import 'package:aves/widgets/viewer/video/conductor.dart';
import 'package:aves_model/aves_model.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:aves_video/aves_video.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
Expand Down Expand Up @@ -438,15 +439,18 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
Widget? child;
void onPressed() => actionDelegate.onActionSelected(context, action);

ValueListenableBuilder<bool> _buildFromListenable(ValueListenable<bool>? enabledNotifier) {
return ValueListenableBuilder<bool>(
valueListenable: enabledNotifier ?? ValueNotifier(false),
builder: (context, canDo, child) => IconButton(
icon: child!,
onPressed: canDo ? onPressed : null,
focusNode: focusNode,
tooltip: action.getText(context),
),
Widget _buildFromListenable(ValueListenable<bool>? enabledNotifier) {
return NullableValueListenableBuilder<bool>(
valueListenable: enabledNotifier,
builder: (context, value, child) {
final canDo = value ?? false;
return IconButton(
icon: child!,
onPressed: canDo ? onPressed : null,
focusNode: focusNode,
tooltip: action.getText(context),
);
},
child: action.getIcon(),
);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/widgets/viewer/page_entry_builder.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/multipage.dart';
import 'package:aves/widgets/viewer/multipage/controller.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:flutter/widgets.dart';

class PageEntryBuilder extends StatelessWidget {
Expand All @@ -20,8 +21,8 @@ class PageEntryBuilder extends StatelessWidget {
stream: controller != null ? controller.infoStream : Stream.value(null),
builder: (context, snapshot) {
final multiPageInfo = controller?.info;
return ValueListenableBuilder<int?>(
valueListenable: controller?.pageNotifier ?? ValueNotifier(null),
return NullableValueListenableBuilder<int?>(
valueListenable: controller?.pageNotifier,
builder: (context, page, child) {
final pageEntry = multiPageInfo?.getPageEntryByIndex(page);
return builder(pageEntry);
Expand Down
12 changes: 7 additions & 5 deletions plugins/aves_services_google/lib/src/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:typed_data';

import 'package:aves_map/aves_map.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:latlong2/latlong.dart' as ll;
Expand Down Expand Up @@ -172,12 +173,13 @@ class _EntryGoogleMapState<T> extends State<EntryGoogleMap<T>> with WidgetsBindi

final interactive = context.select<MapThemeData, bool>((v) => v.interactive);
final overlayEntry = widget.overlayEntry;
return ValueListenableBuilder<ll.LatLng?>(
valueListenable: widget.dotLocationNotifier ?? ValueNotifier(null),
return NullableValueListenableBuilder<ll.LatLng?>(
valueListenable: widget.dotLocationNotifier,
builder: (context, dotLocation, child) {
return ValueListenableBuilder<double>(
valueListenable: widget.overlayOpacityNotifier ?? ValueNotifier(1),
builder: (context, overlayOpacity, child) {
return NullableValueListenableBuilder<double>(
valueListenable: widget.overlayOpacityNotifier,
builder: (context, value, child) {
final double overlayOpacity = value ?? 1.0;
return LayoutBuilder(
builder: (context, constraints) {
_sizeNotifier.value = constraints.biggest;
Expand Down
7 changes: 7 additions & 0 deletions plugins/aves_services_google/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ packages:
relative: true
source: path
version: "0.0.1"
aves_utils:
dependency: "direct main"
description:
path: "../aves_utils"
relative: true
source: path
version: "0.0.1"
characters:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions plugins/aves_services_google/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ dependencies:
path: ../aves_map
aves_services:
path: ../aves_services
aves_utils:
path: ../aves_utils
device_info_plus:
google_api_availability:
google_maps_flutter:
Expand Down
12 changes: 7 additions & 5 deletions plugins/aves_services_huawei/lib/src/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:typed_data';

import 'package:aves_map/aves_map.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:flutter/material.dart';
import 'package:huawei_map/huawei_map.dart';
import 'package:latlong2/latlong.dart' as ll;
Expand Down Expand Up @@ -146,12 +147,13 @@ class _EntryHmsMapState<T> extends State<EntryHmsMap<T>> {

final interactive = context.select<MapThemeData, bool>((v) => v.interactive);
// final overlayEntry = widget.overlayEntry;
return ValueListenableBuilder<ll.LatLng?>(
valueListenable: widget.dotLocationNotifier ?? ValueNotifier(null),
return NullableValueListenableBuilder<ll.LatLng?>(
valueListenable: widget.dotLocationNotifier,
builder: (context, dotLocation, child) {
return ValueListenableBuilder<double>(
valueListenable: widget.overlayOpacityNotifier ?? ValueNotifier(1),
builder: (context, overlayOpacity, child) {
return NullableValueListenableBuilder<double>(
valueListenable: widget.overlayOpacityNotifier,
builder: (context, value, child) {
// final double overlayOpacity = value ?? 1.0;
return HuaweiMap(
initialCameraPosition: CameraPosition(
bearing: bounds.rotation,
Expand Down
7 changes: 7 additions & 0 deletions plugins/aves_services_huawei/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ packages:
relative: true
source: path
version: "0.0.1"
aves_utils:
dependency: "direct main"
description:
path: "../aves_utils"
relative: true
source: path
version: "0.0.1"
characters:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions plugins/aves_services_huawei/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ dependencies:
path: ../aves_platform_meta
aves_services:
path: ../aves_services
aves_utils:
path: ../aves_utils
# cf https://github.com/HMS-Core/hms-flutter-plugin/pull/296
huawei_hmsavailability:
git:
Expand Down
2 changes: 1 addition & 1 deletion plugins/aves_utils/lib/aves_utils.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
library aves_utils;

export 'src/change_notifier.dart';
export 'src/colors.dart';
export 'src/listenable.dart';
export 'src/optional_event_channel.dart';
export 'src/vector_utils.dart';
9 changes: 0 additions & 9 deletions plugins/aves_utils/lib/src/change_notifier.dart

This file was deleted.

55 changes: 55 additions & 0 deletions plugins/aves_utils/lib/src/listenable.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

// `ChangeNotifier` wrapper to call `notify` without constraint
class AChangeNotifier extends ChangeNotifier {
void notify() {
// why is this protected?
super.notifyListeners();
}
}

// contrary to standard `ValueListenableBuilder`, this widget allows providing a null listenable
class NullableValueListenableBuilder<T> extends StatefulWidget {
final ValueListenable<T?>? valueListenable;
final ValueWidgetBuilder<T?> builder;
final Widget? child;

const NullableValueListenableBuilder({
super.key,
required this.valueListenable,
required this.builder,
this.child,
});

@override
State<NullableValueListenableBuilder> createState() => _NullableValueListenableBuilderState<T>();
}

class _NullableValueListenableBuilderState<T> extends State<NullableValueListenableBuilder<T>> {
ValueNotifier<T?>? _internalValueListenable;

ValueListenable<T?> get _valueListenable {
var listenable = widget.valueListenable;
if (listenable == null) {
_internalValueListenable ??= ValueNotifier(null);
listenable = _internalValueListenable;
}
return listenable!;
}

@override
void dispose() {
_internalValueListenable?.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return ValueListenableBuilder<T?>(
valueListenable: _valueListenable,
builder: widget.builder,
child: widget.child,
);
}
}

0 comments on commit 3909b92

Please sign in to comment.