From b04d90a3ad7ece06dc39f3804be63ffc09888625 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Thu, 18 Apr 2024 17:25:39 +0200 Subject: [PATCH] Added image principal geopoint + set centrage localisation mapdto --- lib/Components/geoloc_input_container.dart | 181 ++++++++++++++++++ .../Section/SubSection/Map/map_config.dart | 15 ++ .../Map/showNewOrUpdateGeoPoint.dart | 15 ++ lib/api/swagger.yaml | 12 ++ manager_api_new/doc/GeoPointDTO.md | 2 + manager_api_new/doc/MapDTO.md | 2 + manager_api_new/lib/model/geo_point_dto.dart | 24 ++- manager_api_new/lib/model/map_dto.dart | 58 ++++-- pubspec.yaml | 2 +- 9 files changed, 291 insertions(+), 20 deletions(-) create mode 100644 lib/Components/geoloc_input_container.dart diff --git a/lib/Components/geoloc_input_container.dart b/lib/Components/geoloc_input_container.dart new file mode 100644 index 0000000..b998939 --- /dev/null +++ b/lib/Components/geoloc_input_container.dart @@ -0,0 +1,181 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:location_picker_flutter_map/location_picker_flutter_map.dart'; +import 'package:manager_app/Components/loading_common.dart'; +import 'package:manager_app/Components/message_notification.dart'; +import 'package:manager_app/Components/rounded_button.dart'; +import 'package:manager_app/Components/rounded_input_field.dart'; +import 'package:manager_app/constants.dart'; + +class GeolocInputContainer extends StatefulWidget { + final Color color; + final String label; + final LatLong? initialValue; + final ValueChanged onChanged; + final bool isSmall; + final double fontSize; + final double fontSizeText; + const GeolocInputContainer({ + Key? key, + this.color = kSecond, + required this.label, + required this.initialValue, + required this.onChanged, + this.isSmall = false, + this.fontSize = 25, + this.fontSizeText = 20, + }) : super(key: key); + + @override + State createState() => _GeolocInputContainerState(); +} + +class _GeolocInputContainerState extends State { + LatLong? localisation; + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.of(context).size; + localisation = widget.initialValue; + + return Container( + child: Row( + children: [ + Align( + alignment: AlignmentDirectional.centerStart, + child: AutoSizeText( + widget.label, + style: TextStyle(fontSize: widget.fontSize, fontWeight: FontWeight.w300), + maxLines: 2, + maxFontSize: widget.fontSize, + textAlign: TextAlign.center, + ), + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + width: size.width *0.15, + child: InkWell( + onTap: () { + showDialog( + builder: (BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20.0)) + ), + title: Center(child: Text(widget.label)), + content: SingleChildScrollView( + child: Container( + width: size.width *0.75, + height: 350, + child: FlutterLocationPicker( + initZoom: 14, + initPosition: localisation == null ? LatLong(50.429333, 4.891434) : LatLong(localisation!.latitude, localisation!.longitude), + minZoomLevel: 0, + maxZoomLevel: 17, + markerIcon: const Icon( + Icons.location_pin, + color: kPrimaryColor, + size: 50, + ), + loadingWidget: LoadingCommon(iconSize: 40.0), + searchBarHintColor: kPrimaryColor, + mapLoadingBackgroundColor: kSecond, + zoomButtonsBackgroundColor: kPrimaryColor, + zoomButtonsColor: Colors.white, + locationButtonBackgroundColor: kPrimaryColor, + locationButtonsColor: Colors.white, + countryFilter: "be, fr", + trackMyPosition: false, + searchBarHintText: "Chercher une localisation", + searchBarTextColor: Colors.black, + searchBarBackgroundColor: Colors.white, + showSelectLocationButton : true, + selectLocationButtonText: "Choisir cette localisation", + selectedLocationButtonTextstyle: const TextStyle(fontSize: 18, color: kPrimaryColor), + mapLanguage: 'fr', + onError: (e) => print(e), + selectLocationButtonLeadingIcon: const Icon(Icons.check, color: kPrimaryColor), + onPicked: (pickedData) { + print("onPicked"); + localisation = pickedData.latLong; + print(localisation); + }, + onChanged: (pickedData) { + print("onChanged"); + print(pickedData.latLong.latitude); + print(pickedData.latLong.longitude); + print(pickedData.address); + print(pickedData.addressData); + }, + showContributorBadgeForOSM: false, + ), + ), + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + width: 180, + height: 70, + child: RoundedButton( + text: "Annuler", + icon: Icons.undo, + color: kSecond, + press: () { + Navigator.of(context).pop(); + }, + fontSize: 20, + ), + ), + Container( + width: 180, + height: 70, + child: RoundedButton( + text: "Valider", + icon: Icons.check, + color: kPrimaryColor, + textColor: kWhite, + press: () { + if(localisation != null) { + widget.onChanged(localisation!); + Navigator.of(context).pop(); + } else { + showNotification(kPrimaryColor, kWhite, "Aucune localisation choisie", context, null); + } + }, + fontSize: 20, + ), + ), + ], + ), + ], + ); + }, context: context + ); + }, + child: Container( + decoration: BoxDecoration( + color: widget.color, + borderRadius: BorderRadius.circular(50), + ), + child: Padding( + padding: const EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 15), + child: Center( + child: AutoSizeText( + "Changer la localisation", + style: TextStyle(color: kWhite), + maxLines: 2, + ) + ), + ) + ), + ), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/Screens/Configurations/Section/SubSection/Map/map_config.dart b/lib/Screens/Configurations/Section/SubSection/Map/map_config.dart index 410d71a..2161629 100644 --- a/lib/Screens/Configurations/Section/SubSection/Map/map_config.dart +++ b/lib/Screens/Configurations/Section/SubSection/Map/map_config.dart @@ -1,6 +1,8 @@ import 'package:diacritic/diacritic.dart'; import 'package:flutter/material.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; +import 'package:location_picker_flutter_map/location_picker_flutter_map.dart'; +import 'package:manager_app/Components/geoloc_input_container.dart'; import 'package:manager_app/Components/multi_select_dropdown_language_container.dart'; import 'package:manager_app/Screens/Configurations/Section/SubSection/Map/category_input_container.dart'; import 'package:manager_app/Components/dropDown_input_container.dart'; @@ -174,6 +176,19 @@ class _MapConfigState extends State { widget.onChanged(jsonEncode(mapDTO).toString()); } ), + GeolocInputContainer( + label: "Point de centrage:", + initialValue: mapDTO.latitude != null && mapDTO.longitude != null ? LatLong(double.parse(mapDTO.latitude!), double.parse(mapDTO.longitude!)) : null, + color: kPrimaryColor, + onChanged: (LatLong? localisation) { + if(localisation != null) { + mapDTO.longitude = localisation.longitude.toString(); + mapDTO.latitude = localisation.latitude.toString(); + } + widget.onChanged(jsonEncode(mapDTO).toString()); + }, + isSmall: true + ), // Icon ResourceInputContainer( label: "IcĂ´ne:", diff --git a/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart b/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart index 7cd5fdb..4813ab9 100644 --- a/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart +++ b/lib/Screens/Configurations/Section/SubSection/Map/showNewOrUpdateGeoPoint.dart @@ -3,6 +3,7 @@ import 'package:location_picker_flutter_map/location_picker_flutter_map.dart'; import 'package:manager_app/Components/dropDown_input_container_categories.dart'; import 'package:manager_app/Components/loading_common.dart'; import 'package:manager_app/Components/multi_string_input_container.dart'; +import 'package:manager_app/Components/resource_input_container.dart'; import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/string_input_container.dart'; import 'package:manager_app/Models/managerContext.dart'; @@ -256,6 +257,20 @@ void showNewOrUpdateGeoPoint(MapDTO mapDTO, GeoPointDTO? inputGeoPointDTO, Funct child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ + ResourceInputContainer( + label: "Image principal:", + initialValue: geoPointDTO.imageResourceId != null ? geoPointDTO.imageResourceId : null, + color: kPrimaryColor, + onChanged: (ResourceDTO resource) { + if(resource.id == null) { + geoPointDTO.imageResourceId = null; + geoPointDTO.imageUrl = null; + } else { + geoPointDTO.imageResourceId = resource.id; + geoPointDTO.imageUrl = resource.url; + } + }, + ), if(mapDTO.categories != null && mapDTO.categories!.isNotEmpty) Container( constraints: BoxConstraints(minHeight: 50, maxHeight: 80), diff --git a/lib/api/swagger.yaml b/lib/api/swagger.yaml index bb092f9..7a074e5 100644 --- a/lib/api/swagger.yaml +++ b/lib/api/swagger.yaml @@ -2153,6 +2153,12 @@ components: nullable: true items: $ref: '#/components/schemas/CategorieDTO' + latitude: + type: string + nullable: true + longitude: + type: string + nullable: true MapTypeApp: type: integer description: |- @@ -2247,6 +2253,12 @@ components: longitude: type: string nullable: true + imageResourceId: + type: string + nullable: true + imageUrl: + type: string + nullable: true schedules: type: array nullable: true diff --git a/manager_api_new/doc/GeoPointDTO.md b/manager_api_new/doc/GeoPointDTO.md index b03a337..10b1688 100644 --- a/manager_api_new/doc/GeoPointDTO.md +++ b/manager_api_new/doc/GeoPointDTO.md @@ -16,6 +16,8 @@ Name | Type | Description | Notes **categorieId** | **int** | | [optional] **latitude** | **String** | | [optional] **longitude** | **String** | | [optional] +**imageResourceId** | **String** | | [optional] +**imageUrl** | **String** | | [optional] **schedules** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **prices** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **phone** | [**List**](TranslationDTO.md) | | [optional] [default to const []] diff --git a/manager_api_new/doc/MapDTO.md b/manager_api_new/doc/MapDTO.md index e636119..9658b62 100644 --- a/manager_api_new/doc/MapDTO.md +++ b/manager_api_new/doc/MapDTO.md @@ -16,6 +16,8 @@ Name | Type | Description | Notes **iconResourceId** | **String** | | [optional] **iconSource** | **String** | | [optional] **categories** | [**List**](CategorieDTO.md) | | [optional] [default to const []] +**latitude** | **String** | | [optional] +**longitude** | **String** | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/manager_api_new/lib/model/geo_point_dto.dart b/manager_api_new/lib/model/geo_point_dto.dart index 100c7fb..16c16bd 100644 --- a/manager_api_new/lib/model/geo_point_dto.dart +++ b/manager_api_new/lib/model/geo_point_dto.dart @@ -21,6 +21,8 @@ class GeoPointDTO { this.categorieId, this.latitude, this.longitude, + this.imageResourceId, + this.imageUrl, this.schedules = const [], this.prices = const [], this.phone = const [], @@ -43,6 +45,10 @@ class GeoPointDTO { String? longitude; + String? imageResourceId; + + String? imageUrl; + List? schedules; List? prices; @@ -63,6 +69,8 @@ class GeoPointDTO { other.categorieId == categorieId && other.latitude == latitude && other.longitude == longitude && + other.imageResourceId == imageResourceId && + other.imageUrl == imageUrl && other.schedules == schedules && other.prices == prices && other.phone == phone && @@ -80,6 +88,8 @@ class GeoPointDTO { (categorieId == null ? 0 : categorieId!.hashCode) + (latitude == null ? 0 : latitude!.hashCode) + (longitude == null ? 0 : longitude!.hashCode) + + (imageResourceId == null ? 0 : imageResourceId!.hashCode) + + (imageUrl == null ? 0 : imageUrl!.hashCode) + (schedules == null ? 0 : schedules!.hashCode) + (prices == null ? 0 : prices!.hashCode) + (phone == null ? 0 : phone!.hashCode) + @@ -87,7 +97,7 @@ class GeoPointDTO { (site == null ? 0 : site!.hashCode); @override - String toString() => 'GeoPointDTO[id=$id, title=$title, description=$description, contents=$contents, categorie=$categorie, categorieId=$categorieId, latitude=$latitude, longitude=$longitude, schedules=$schedules, prices=$prices, phone=$phone, email=$email, site=$site]'; + String toString() => 'GeoPointDTO[id=$id, title=$title, description=$description, contents=$contents, categorie=$categorie, categorieId=$categorieId, latitude=$latitude, longitude=$longitude, imageResourceId=$imageResourceId, imageUrl=$imageUrl, schedules=$schedules, prices=$prices, phone=$phone, email=$email, site=$site]'; Map toJson() { final json = {}; @@ -131,6 +141,16 @@ class GeoPointDTO { } else { json[r'longitude'] = null; } + if (this.imageResourceId != null) { + json[r'imageResourceId'] = this.imageResourceId; + } else { + json[r'imageResourceId'] = null; + } + if (this.imageUrl != null) { + json[r'imageUrl'] = this.imageUrl; + } else { + json[r'imageUrl'] = null; + } if (this.schedules != null) { json[r'schedules'] = this.schedules; } else { @@ -186,6 +206,8 @@ class GeoPointDTO { categorieId: mapValueOfType(json, r'categorieId'), latitude: mapValueOfType(json, r'latitude'), longitude: mapValueOfType(json, r'longitude'), + imageResourceId: mapValueOfType(json, r'imageResourceId'), + imageUrl: mapValueOfType(json, r'imageUrl'), schedules: TranslationDTO.listFromJson(json[r'schedules']), prices: TranslationDTO.listFromJson(json[r'prices']), phone: TranslationDTO.listFromJson(json[r'phone']), diff --git a/manager_api_new/lib/model/map_dto.dart b/manager_api_new/lib/model/map_dto.dart index 3507560..28d7aeb 100644 --- a/manager_api_new/lib/model/map_dto.dart +++ b/manager_api_new/lib/model/map_dto.dart @@ -21,6 +21,8 @@ class MapDTO { this.iconResourceId, this.iconSource, this.categories = const [], + this.latitude, + this.longitude, }); /// @@ -45,31 +47,39 @@ class MapDTO { List? categories; + String? latitude; + + String? longitude; + @override bool operator ==(Object other) => identical(this, other) || other is MapDTO && - other.zoom == zoom && - other.mapType == mapType && - other.mapTypeMapbox == mapTypeMapbox && - other.mapProvider == mapProvider && - other.points == points && - other.iconResourceId == iconResourceId && - other.iconSource == iconSource && - other.categories == categories; + other.zoom == zoom && + other.mapType == mapType && + other.mapTypeMapbox == mapTypeMapbox && + other.mapProvider == mapProvider && + other.points == points && + other.iconResourceId == iconResourceId && + other.iconSource == iconSource && + other.categories == categories && + other.latitude == latitude && + other.longitude == longitude; @override int get hashCode => - // ignore: unnecessary_parenthesis - (zoom == null ? 0 : zoom!.hashCode) + - (mapType == null ? 0 : mapType!.hashCode) + - (mapTypeMapbox == null ? 0 : mapTypeMapbox!.hashCode) + - (mapProvider == null ? 0 : mapProvider!.hashCode) + - (points == null ? 0 : points!.hashCode) + - (iconResourceId == null ? 0 : iconResourceId!.hashCode) + - (iconSource == null ? 0 : iconSource!.hashCode) + - (categories == null ? 0 : categories!.hashCode); + // ignore: unnecessary_parenthesis + (zoom == null ? 0 : zoom!.hashCode) + + (mapType == null ? 0 : mapType!.hashCode) + + (mapTypeMapbox == null ? 0 : mapTypeMapbox!.hashCode) + + (mapProvider == null ? 0 : mapProvider!.hashCode) + + (points == null ? 0 : points!.hashCode) + + (iconResourceId == null ? 0 : iconResourceId!.hashCode) + + (iconSource == null ? 0 : iconSource!.hashCode) + + (categories == null ? 0 : categories!.hashCode) + + (latitude == null ? 0 : latitude!.hashCode) + + (longitude == null ? 0 : longitude!.hashCode); @override - String toString() => 'MapDTO[zoom=$zoom, mapType=$mapType, mapTypeMapbox=$mapTypeMapbox, mapProvider=$mapProvider, points=$points, iconResourceId=$iconResourceId, iconSource=$iconSource, categories=$categories]'; + String toString() => 'MapDTO[zoom=$zoom, mapType=$mapType, mapTypeMapbox=$mapTypeMapbox, mapProvider=$mapProvider, points=$points, iconResourceId=$iconResourceId, iconSource=$iconSource, categories=$categories, latitude=$latitude, longitude=$longitude]'; Map toJson() { final json = {}; @@ -113,6 +123,16 @@ class MapDTO { } else { json[r'categories'] = null; } + if (this.latitude != null) { + json[r'latitude'] = this.latitude; + } else { + json[r'latitude'] = null; + } + if (this.longitude != null) { + json[r'longitude'] = this.longitude; + } else { + json[r'longitude'] = null; + } return json; } @@ -143,6 +163,8 @@ class MapDTO { iconResourceId: mapValueOfType(json, r'iconResourceId'), iconSource: mapValueOfType(json, r'iconSource'), categories: CategorieDTO.listFromJson(json[r'categories']), + latitude: mapValueOfType(json, r'latitude'), + longitude: mapValueOfType(json, r'longitude'), ); } return null; diff --git a/pubspec.yaml b/pubspec.yaml index c762b39..914ed88 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 2.0.2+6 +version: 2.0.3+7 environment: sdk: ">=3.1.0 <4.0.0"