Преглед изворни кода

Custom radius for location tags but with state refresh issues

ashilkn пре 2 година
родитељ
комит
2b0d851c81

+ 1 - 1
lib/core/constants.dart

@@ -60,7 +60,7 @@ const publicLinkDeviceLimits = [50, 25, 10, 5, 2, 1];
 
 const kilometersPerDegree = 111.16;
 
-const radiusValues = <double>[1, 2, 10, 20, 40, 80, 200, 400, 1200];
+const defaultRadiusValues = <double>[1, 2, 10, 20, 40, 80, 200, 400, 1200];
 
 const defaultRadiusValueIndex = 4;
 

+ 1 - 2
lib/models/location_tag/location_tag.dart

@@ -1,5 +1,4 @@
 import 'package:freezed_annotation/freezed_annotation.dart';
-import "package:photos/core/constants.dart";
 import 'package:photos/models/location/location.dart';
 
 part 'location_tag.freezed.dart';
@@ -19,7 +18,7 @@ class LocationTag with _$LocationTag {
   factory LocationTag.fromJson(Map<String, Object?> json) =>
       _$LocationTagFromJson(json);
 
-  int get radiusIndex {
+  int radiusIndex(List<double> radiusValues) {
     return radiusValues.indexOf(radius);
   }
 }

+ 1 - 0
lib/models/typedefs.dart

@@ -9,3 +9,4 @@ typedef VoidCallbackParamStr = void Function(String);
 typedef FutureOrVoidCallback = FutureOr<void> Function();
 typedef VoidCallbackParamInt = void Function(int);
 typedef VoidCallbackParamLocation = void Function(Location);
+typedef VoidCallbackParamListDouble = void Function(List<double>);

+ 46 - 3
lib/states/location_state.dart

@@ -1,5 +1,6 @@
 import "dart:async";
 
+import "package:collection/collection.dart";
 import "package:flutter/material.dart";
 import "package:photos/core/constants.dart";
 import "package:photos/core/event_bus.dart";
@@ -33,14 +34,22 @@ class _LocationTagStateProviderState extends State<LocationTagStateProvider> {
   final Debouncer _selectedRadiusDebouncer =
       Debouncer(const Duration(milliseconds: 300));
   late final StreamSubscription _locTagEntityListener;
+  late final List<double> _radiusValues;
+
   @override
   void initState() {
     _locationTagEntity = widget.locationTagEntity;
     _centerPoint = widget.centerPoint;
     assert(_centerPoint != null || _locationTagEntity != null);
     _centerPoint = _locationTagEntity?.item.centerPoint ?? _centerPoint!;
+
+    ///If the location tag has a custom radius value, we add the custom radius
+    ///value to the list of default radius values only for this location tag and
+    ///keep it in the state of this widget.
+    _radiusValues = _getRadiusValuesOfLocTag(_locationTagEntity?.item.radius);
     _selectedRaduisIndex =
-        _locationTagEntity?.item.radiusIndex ?? defaultRadiusValueIndex;
+        _locationTagEntity?.item.radiusIndex(_radiusValues) ??
+            defaultRadiusValueIndex;
     _locTagEntityListener =
         Bus.instance.on<LocationTagUpdatedEvent>().listen((event) {
       _locationTagUpdateListener(event);
@@ -60,7 +69,8 @@ class _LocationTagStateProviderState extends State<LocationTagStateProvider> {
         //Update state when locationTag is updated.
         setState(() {
           final updatedLocTagEntity = event.updatedLocTagEntities!.first;
-          _selectedRaduisIndex = updatedLocTagEntity.item.radiusIndex;
+          _selectedRaduisIndex =
+              updatedLocTagEntity.item.radiusIndex(_radiusValues);
           _centerPoint = updatedLocTagEntity.item.centerPoint;
           _locationTagEntity = updatedLocTagEntity;
         });
@@ -87,6 +97,32 @@ class _LocationTagStateProviderState extends State<LocationTagStateProvider> {
     }
   }
 
+  void _updateRadiusValues(List<double> radiusValues) {
+    if (mounted) {
+      setState(() {
+        for (double radiusValue in radiusValues) {
+          if (!_radiusValues.contains(radiusValue)) {
+            _radiusValues.add(radiusValue);
+          }
+        }
+        _radiusValues.sort();
+      });
+    }
+  }
+
+  ///Returns the list of radius values for the location tag entity. If radius of
+  ///the location tag is not present in the default list, it returns the list
+  ///with the custom radius value.
+  List<double> _getRadiusValuesOfLocTag(double? radiusOfLocTag) {
+    final radiusValues = <double>[...defaultRadiusValues];
+    if (radiusOfLocTag != null &&
+        !defaultRadiusValues.contains(radiusOfLocTag)) {
+      radiusValues.add(radiusOfLocTag);
+      radiusValues.sort();
+    }
+    return radiusValues;
+  }
+
   @override
   Widget build(BuildContext context) {
     return InheritedLocationTagData(
@@ -95,6 +131,8 @@ class _LocationTagStateProviderState extends State<LocationTagStateProvider> {
       _updateSelectedIndex,
       _locationTagEntity,
       _updateCenterPoint,
+      _updateRadiusValues,
+      _radiusValues,
       child: widget.child,
     );
   }
@@ -108,12 +146,16 @@ class InheritedLocationTagData extends InheritedWidget {
   final LocalEntity<LocationTag>? locationTagEntity;
   final VoidCallbackParamInt updateSelectedIndex;
   final VoidCallbackParamLocation updateCenterPoint;
+  final VoidCallbackParamListDouble updateRadiusValues;
+  final List<double> radiusValues;
   const InheritedLocationTagData(
     this.selectedRadiusIndex,
     this.centerPoint,
     this.updateSelectedIndex,
     this.locationTagEntity,
-    this.updateCenterPoint, {
+    this.updateCenterPoint,
+    this.updateRadiusValues,
+    this.radiusValues, {
     required super.child,
     super.key,
   });
@@ -126,6 +168,7 @@ class InheritedLocationTagData extends InheritedWidget {
   @override
   bool updateShouldNotify(InheritedLocationTagData oldWidget) {
     return oldWidget.selectedRadiusIndex != selectedRadiusIndex ||
+        !oldWidget.radiusValues.equals(radiusValues) ||
         oldWidget.centerPoint != centerPoint ||
         oldWidget.locationTagEntity != locationTagEntity;
   }

+ 0 - 1
lib/ui/components/dialog_widget.dart

@@ -229,7 +229,6 @@ class _TextInputDialogState extends State<TextInputDialog> {
   @override
   void dispose() {
     _submitNotifier.dispose();
-    _textEditingController.dispose();
     _inputIsEmptyNotifier.dispose();
     super.dispose();
   }

+ 1 - 0
lib/ui/viewer/location/add_location_sheet.dart

@@ -230,6 +230,7 @@ class _AddLocationSheetState extends State<AddLocationSheet> {
   Future<void> _addLocationTag() async {
     final locationData = InheritedLocationTagData.of(context);
     final coordinates = locationData.centerPoint;
+    final radiusValues = locationData.radiusValues;
     final radius = radiusValues[locationData.selectedRadiusIndex];
     await LocationService.instance.addLocation(
       _textEditingController.text.trim(),

+ 2 - 2
lib/ui/viewer/location/dynamic_location_gallery_widget.dart

@@ -122,8 +122,8 @@ class _DynamicLocationGalleryWidgetState
   }
 
   double _selectedRadius() {
-    return radiusValues[
-        InheritedLocationTagData.of(context).selectedRadiusIndex];
+    final locationTagState = InheritedLocationTagData.of(context);
+    return locationTagState.radiusValues[locationTagState.selectedRadiusIndex];
   }
 
   double _galleryHeight(int fileCount) {

+ 2 - 1
lib/ui/viewer/location/edit_location_sheet.dart

@@ -240,7 +240,8 @@ class _EditLocationSheetState extends State<EditLocationSheet> {
     final locationTagState = InheritedLocationTagData.of(context);
     await LocationService.instance.updateLocationTag(
       locationTagEntity: locationTagState.locationTagEntity!,
-      newRadius: radiusValues[locationTagState.selectedRadiusIndex],
+      newRadius:
+          locationTagState.radiusValues[locationTagState.selectedRadiusIndex],
       newName: _textEditingController.text.trim(),
       newCenterPoint: InheritedLocationTagData.of(context).centerPoint,
     );

+ 14 - 2
lib/ui/viewer/location/radius_picker_widget.dart

@@ -1,6 +1,5 @@
 import "package:flutter/material.dart";
 import "package:flutter/services.dart";
-import "package:photos/core/constants.dart";
 import "package:photos/generated/l10n.dart";
 import "package:photos/states/location_state.dart";
 import "package:photos/theme/colors.dart";
@@ -50,6 +49,7 @@ class _RadiusPickerWidgetState extends State<RadiusPickerWidget> {
 
   @override
   Widget build(BuildContext context) {
+    final radiusValues = InheritedLocationTagData.of(context).radiusValues;
     final selectedRadiusIndex = widget.selectedRadiusIndexNotifier.value;
     final radiusValue = radiusValues[selectedRadiusIndex];
     final textTheme = getEnteTextTheme(context);
@@ -63,7 +63,19 @@ class _RadiusPickerWidgetState extends State<RadiusPickerWidget> {
             showTextInputDialog(
               context,
               title: "Custom radius",
-              onSubmit: (customRadius) async {},
+              onSubmit: (customRadius) async {
+                final radius = double.tryParse(customRadius);
+                if (radius != null) {
+                  InheritedLocationTagData.of(context)
+                      .updateRadiusValues([radius]);
+                } else {
+                  showErrorDialog(
+                    context,
+                    "Invalid radius",
+                    "Please enter a valid radius",
+                  );
+                }
+              },
               submitButtonLabel: "Done",
               textInputFormatter: [
                 NumberWithDecimalInputFormatter(maxValue: 10000)