Custom radius for location tags but with state refresh issues

This commit is contained in:
ashilkn 2023-04-26 18:31:33 +05:30
parent 36c5052a6d
commit 2b0d851c81
9 changed files with 68 additions and 12 deletions

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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>);

View file

@ -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;
}

View file

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

View file

@ -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(),

View file

@ -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) {

View file

@ -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,
);

View file

@ -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)