From b08d8788f170958ca853b079b01f03a2d8c66663 Mon Sep 17 00:00:00 2001 From: manavmodi Date: Mon, 4 Nov 2024 17:11:04 -0500 Subject: [PATCH 01/13] changes for map --- lib/ui/explore/ExploreMapPanel.dart | 13 ++++++++++++- lib/ui/explore/ExploreStoriedSightsBottomSheet.dart | 5 ++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index be2cb05d5..b647b0ec1 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -195,6 +195,7 @@ class _ExploreMapPanelState extends State bool _filtersDropdownVisible = false; List? _explores; + List? _filteredExplores; bool _exploreProgress = false; Future?>? _exploreTask; @@ -471,6 +472,9 @@ class _ExploreMapPanelState extends State _centerMapOnExplore(place, zoom: false); _selectMapExplore(place); }, + onFilteredPlacesChanged: (List filteredPlaces) { + _updateMapMarkers(filteredPlaces); + }, ), _buildExploreTypesDropDownContainer(), ]), @@ -478,6 +482,11 @@ class _ExploreMapPanelState extends State ]); } + void _updateMapMarkers(List filteredExplores) { + _filteredExplores = filteredExplores; + _buildMapContentData(_filteredExplores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: true); + } + // Map Widget Widget _buildContent() { @@ -1880,16 +1889,18 @@ class _ExploreMapPanelState extends State if (mounted && (exploreTask == _exploreTask)) { setState(() { _explores = explores; + _filteredExplores = explores; _exploreTask = null; _exploreProgress = false; _mapKey = UniqueKey(); // force map rebuild }); _selectMapExplore(null); _displayContentPopups(); - } + } } } + Future _refreshExplores() async { Future?> exploreTask = _loadExplores(); List? explores = await (_exploreTask = exploreTask); diff --git a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart index 2d821373e..88afefcb3 100644 --- a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart +++ b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart @@ -19,8 +19,9 @@ import 'package:flutter_markdown/flutter_markdown.dart'; class ExploreStoriedSightsBottomSheet extends StatefulWidget { final List places; final Function(places_model.Place) onPlaceSelected; + final void Function(List filteredPlaces)? onFilteredPlacesChanged; - ExploreStoriedSightsBottomSheet({Key? key, required this.places, required this.onPlaceSelected}) : super(key: key); + ExploreStoriedSightsBottomSheet({Key? key, required this.places, required this.onPlaceSelected, this.onFilteredPlacesChanged}) : super(key: key); @override ExploreStoriedSightsBottomSheetState createState() => ExploreStoriedSightsBottomSheetState(); @@ -693,6 +694,8 @@ class ExploreStoriedSightsBottomSheetState extends State Date: Mon, 4 Nov 2024 17:36:45 -0500 Subject: [PATCH 02/13] some extra changes --- lib/ui/explore/ExploreMapPanel.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index b647b0ec1..53e789837 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -483,8 +483,11 @@ class _ExploreMapPanelState extends State } void _updateMapMarkers(List filteredExplores) { - _filteredExplores = filteredExplores; - _buildMapContentData(_filteredExplores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: true); + _mapController?.getZoomLevel().then((double value) { + _filteredExplores = filteredExplores; + _buildMapContentData(_filteredExplores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: true, zoom: value); + }); + } // Map Widget From 5dcb5af6ecc9b52a3d65d0d39001c378ffb3c0ee Mon Sep 17 00:00:00 2001 From: Mihail Varbanov Date: Tue, 5 Nov 2024 11:41:59 +0200 Subject: [PATCH 03/13] More consistent synchronization between ExploreStoriedSightsBottomSheet content and ExploreMapPanel markers [#4458]. --- lib/ui/explore/ExploreMapPanel.dart | 38 ++++++++++--------- .../ExploreStoriedSightsBottomSheet.dart | 4 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index 53e789837..ef3453903 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -376,7 +376,7 @@ class _ExploreMapPanelState extends State } else if (name == Storage.notifySettingChanged) { if (param == Storage.debugMapThresholdDistanceKey) { - _buildMapContentData(_explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, zoom: _lastMarkersUpdateZoom, showProgress: true); + _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, zoom: _lastMarkersUpdateZoom, showProgress: true); } else if (param == Storage.debugMapShowLevelsKey) { setStateIfMounted(() { }); @@ -468,13 +468,8 @@ class _ExploreMapPanelState extends State ExploreStoriedSightsBottomSheet( key: _storiedSightsKey, places: _explores?.whereType().toList() ?? [], - onPlaceSelected: (places_model.Place place) { - _centerMapOnExplore(place, zoom: false); - _selectMapExplore(place); - }, - onFilteredPlacesChanged: (List filteredPlaces) { - _updateMapMarkers(filteredPlaces); - }, + onPlaceSelected: _onStoriedSitesPlaceSelected, + onFilteredPlacesChanged: _onStoriedSitesFilteredPlacesChanged, ), _buildExploreTypesDropDownContainer(), ]), @@ -482,14 +477,6 @@ class _ExploreMapPanelState extends State ]); } - void _updateMapMarkers(List filteredExplores) { - _mapController?.getZoomLevel().then((double value) { - _filteredExplores = filteredExplores; - _buildMapContentData(_filteredExplores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: true, zoom: value); - }); - - } - // Map Widget Widget _buildContent() { @@ -591,7 +578,7 @@ class _ExploreMapPanelState extends State _lastMarkersUpdateZoom = value; } else if ((_lastMarkersUpdateZoom! - value).abs() > _groupMarkersUpdateThresoldDelta) { - _buildMapContentData(_explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, zoom: value, showProgress: true); + _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, zoom: value, showProgress: true); } }); } @@ -639,6 +626,19 @@ class _ExploreMapPanelState extends State } } + void _onStoriedSitesPlaceSelected(places_model.Place place) { + _centerMapOnExplore(place, zoom: false); + _selectMapExplore(place); + } + + void _onStoriedSitesFilteredPlacesChanged(List? filteredExplores) { + if (!DeepCollectionEquality().equals(_filteredExplores, filteredExplores)) { + _mapController?.getZoomLevel().then((double value) { + _filteredExplores = (filteredExplores != null) ? List.from(filteredExplores) : null; + _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: true, zoom: value); + }); + } + } void _centerMapOnExplore(dynamic explore, {bool zoom = true}) async { LatLng? targetPosition; @@ -1892,7 +1892,7 @@ class _ExploreMapPanelState extends State if (mounted && (exploreTask == _exploreTask)) { setState(() { _explores = explores; - _filteredExplores = explores; + _filteredExplores = null; _exploreTask = null; _exploreProgress = false; _mapKey = UniqueKey(); // force map rebuild @@ -1913,6 +1913,7 @@ class _ExploreMapPanelState extends State if (mounted && (exploreTask == _exploreTask)) { setState(() { _explores = explores; + _filteredExplores = null; _exploreProgress = false; _exploreTask = null; }); @@ -2097,6 +2098,7 @@ class _ExploreMapPanelState extends State if (mounted) { setState(() { _explores = explores; + _filteredExplores = null; }); } }); diff --git a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart index 88afefcb3..80eebaaa2 100644 --- a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart +++ b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart @@ -19,7 +19,7 @@ import 'package:flutter_markdown/flutter_markdown.dart'; class ExploreStoriedSightsBottomSheet extends StatefulWidget { final List places; final Function(places_model.Place) onPlaceSelected; - final void Function(List filteredPlaces)? onFilteredPlacesChanged; + final void Function(List? filteredPlaces)? onFilteredPlacesChanged; ExploreStoriedSightsBottomSheet({Key? key, required this.places, required this.onPlaceSelected, this.onFilteredPlacesChanged}) : super(key: key); @@ -695,7 +695,7 @@ class ExploreStoriedSightsBottomSheetState extends State Date: Tue, 5 Nov 2024 12:29:39 -0500 Subject: [PATCH 04/13] Fix the explorebar issue --- lib/ui/explore/ExploreMapPanel.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index ef3453903..1cdca77b8 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -500,7 +500,10 @@ class _ExploreMapPanelState extends State Widget _buildMapContent() { return Stack(children: [ _buildMapView(), - _buildMapExploreBar(), + Visibility( + visible: _selectedMapType != ExploreMapType.StoriedSites, + child: _buildMapExploreBar() + ), Visibility(visible: _markersProgress, child: Positioned.fill(child: Center(child: From f79ec4f1ece47217fc139eefef49fb50067e814d Mon Sep 17 00:00:00 2001 From: manavmodi Date: Tue, 5 Nov 2024 13:21:01 -0500 Subject: [PATCH 05/13] add filter fixes --- .../ExploreStoriedSightsBottomSheet.dart | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart index 80eebaaa2..44cde1a63 100644 --- a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart +++ b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart @@ -666,29 +666,32 @@ class ExploreStoriedSightsBottomSheetState extends State _customPlaces!.contains(place)).toList(); - } else { - filteredPlaces = filteredPlaces.where((place) { - bool matchesFilter = false; - if (_selectedFilters.contains('Visited')) { - if (place.userData?.visited != null && place.userData!.visited!.isNotEmpty) { - if (_selectedFilters.length > 1) { - matchesFilter = _matchesOtherFilters(place); - } else { - matchesFilter = true; - } + // Apply custom places filter if selected + if (_selectedFilters.contains(_customSelectionFilterKey)) { + filteredPlaces = filteredPlaces.where((place) => _customPlaces!.contains(place)).toList(); + } + + Set filtersToApply = Set.from(_selectedFilters); + filtersToApply.remove(_customSelectionFilterKey); + + if (filtersToApply.isNotEmpty) { + filteredPlaces = filteredPlaces.where((place) { + bool matchesFilter = false; + if (filtersToApply.contains('Visited')) { + if (place.userData?.visited != null && place.userData!.visited!.isNotEmpty) { + if (filtersToApply.length > 1) { + matchesFilter = _matchesOtherFilters(place, filters: filtersToApply); } else { - matchesFilter = false; + matchesFilter = true; } } else { - matchesFilter = place.tags != null && place.tags!.any((tag) => _selectedFilters.contains(tag)); + matchesFilter = false; } - return matchesFilter; - }).toList(); - } + } else { + matchesFilter = place.tags != null && place.tags!.any((tag) => filtersToApply.contains(tag)); + } + return matchesFilter; + }).toList(); } setState(() { @@ -698,9 +701,9 @@ class ExploreStoriedSightsBottomSheetState extends State otherFilters = Set.from(_selectedFilters)..remove('Visited'); + bool _matchesOtherFilters(places_model.Place place, {Set? filters}) { + Set otherFilters = filters ?? Set.from(_selectedFilters)..remove('Visited'); + otherFilters.remove('Visited'); if (place.tags == null || place.tags!.isEmpty) { return false; } From b2d85252ca9ca8cc4052901c0e35873523261f6d Mon Sep 17 00:00:00 2001 From: manavmodi Date: Tue, 5 Nov 2024 13:22:19 -0500 Subject: [PATCH 06/13] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efb89fd00..44a35d5a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased ## Added +- Filter pins on map to match filters/search for storied sites [#4458](https://github.com/rokwire/illinois-app/issues/4458) - Add search to Bottomsheet [#4456](https://github.com/rokwire/illinois-app/issues/4456) ## [6.0.56] - 2024-11-04 ### Fixed From 47af14b44bb1d272c6cc2fb103e3592202f8267c Mon Sep 17 00:00:00 2001 From: manavmodi Date: Tue, 5 Nov 2024 17:53:06 -0500 Subject: [PATCH 07/13] Add color pin feature --- assets/strings.en.json | 2 +- assets/strings.es.json | 2 +- assets/strings.zh.json | 2 +- lib/ui/explore/ExploreMapPanel.dart | 61 +++++++++++-------- .../ExploreStoriedSightsBottomSheet.dart | 6 +- 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/assets/strings.en.json b/assets/strings.en.json index e322cdb41..7630536b2 100644 --- a/assets/strings.en.json +++ b/assets/strings.en.json @@ -1153,7 +1153,7 @@ "panel.explore.storied_sites.title": "Storied Sites", "panel.explore.storied_sites.load.error": "Failed to load stored site details", - "panel.explore.storied_sites.check_in.try_again": "Check-in failed. Please try again.", + "panel.explore.storied_sites.check_in.try_again": "Check-in failed. Please sign in and try again.", "panel.explore.storied_sites.check_in.failed": "Check-in failed due to an error.", "panel.explore.storied_sites.one.day": "You can only check in once per day.", "panel.explore.storied_sites.failed.clear": "Failed to clear check-in date. Please try again.", diff --git a/assets/strings.es.json b/assets/strings.es.json index 32ce490e9..1e94cd2ec 100644 --- a/assets/strings.es.json +++ b/assets/strings.es.json @@ -1152,7 +1152,7 @@ "panel.explore.storied_sites.title": "Storied Sites", "panel.explore.storied_sites.load.error": "Failed to load stored site details", - "panel.explore.storied_sites.check_in.try_again": "Check-in failed. Please try again.", + "panel.explore.storied_sites.check_in.try_again": "Check-in failed. Please sign in and try again.", "panel.explore.storied_sites.check_in.failed": "Check-in failed due to an error.", "panel.explore.storied_sites.one.day": "You can only check in once per day.", "panel.explore.storied_sites.failed.clear": "Failed to clear check-in date. Please try again.", diff --git a/assets/strings.zh.json b/assets/strings.zh.json index 5b482cb89..82f341d48 100644 --- a/assets/strings.zh.json +++ b/assets/strings.zh.json @@ -1152,7 +1152,7 @@ "panel.explore.storied_sites.title": "Storied Sites", "panel.explore.storied_sites.load.error": "Failed to load stored site details", - "panel.explore.storied_sites.check_in.try_again": "Check-in failed. Please try again.", + "panel.explore.storied_sites.check_in.try_again": "Check-in failed. Please sign in and try again.", "panel.explore.storied_sites.check_in.failed": "Check-in failed due to an error.", "panel.explore.storied_sites.one.day": "You can only check in once per day.", "panel.explore.storied_sites.failed.clear": "Failed to clear check-in date. Please try again.", diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index 1cdca77b8..8fef13720 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -470,6 +470,7 @@ class _ExploreMapPanelState extends State places: _explores?.whereType().toList() ?? [], onPlaceSelected: _onStoriedSitesPlaceSelected, onFilteredPlacesChanged: _onStoriedSitesFilteredPlacesChanged, + onBackPressed: _onStoriedSitesBackPressed, ), _buildExploreTypesDropDownContainer(), ]), @@ -477,6 +478,10 @@ class _ExploreMapPanelState extends State ]); } + void _onStoriedSitesBackPressed() { + _selectMapExplore(null); + } + // Map Widget Widget _buildContent() { @@ -618,11 +623,12 @@ class _ExploreMapPanelState extends State if (_selectedMapType == ExploreMapType.StoriedSites) { if (origin is Place) { _storiedSightsKey.currentState?.selectPlace(origin); - // _centerMapOnExplore(origin); + _selectMapExplore(origin); } else if (origin is List) { List places = origin.cast(); _storiedSightsKey.currentState?.selectPlaces(places); _centerMapOnExplore(places); + _selectMapExplore(places); } } else { _selectMapExplore(origin); @@ -836,16 +842,20 @@ class _ExploreMapPanelState extends State } else if (_selectedMapExplore != null) { _pinMapExplore(null); + _selectedMapExplore = null; _mapExploreBarAnimationController?.reverse().then((_) { - setStateIfMounted(() { - _selectedMapExplore = null; - }); + setStateIfMounted(() {}); _updateSelectedMapStopRoutes(); }); - } - else { + } else { _pinMapExplore(null); } + if (_selectedMapType == ExploreMapType.StoriedSites) { + // Get the current zoom level + _mapController?.getZoomLevel().then((double value) { + _buildMapContentData(_filteredExplores ?? _explores, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); + }); + } _logAnalyticsSelect(explore); } @@ -2132,7 +2142,7 @@ class _ExploreMapPanelState extends State // Map Content - Future _buildMapContentData(List? explores, {Explore? pinnedExplore, bool updateCamera = false, bool showProgress = false, double? zoom}) async { + Future _buildMapContentData(List? explores, {Explore? pinnedExplore, bool updateCamera = false, bool showProgress = false, double? zoom, bool forceRefresh = false}) async { LatLngBounds? exploresBounds = ExploreMap.boundsOfList(explores); CameraUpdate? targetCameraUpdate; @@ -2168,8 +2178,8 @@ class _ExploreMapPanelState extends State thresoldDistance = 0; exploreMarkerGroups = (explores != null) ? { ExploreMap.validFromList(explores) } : null; } - - if (!DeepCollectionEquality().equals(_exploreMarkerGroups, exploreMarkerGroups)) { + + if (forceRefresh || !DeepCollectionEquality().equals(_exploreMarkerGroups, exploreMarkerGroups)) { Future> buildMarkersTask = _buildMarkers(context, exploreGroups: exploreMarkerGroups, pinnedExplore: pinnedExplore); _buildMarkersTask = buildMarkersTask; if (showProgress && mounted) { @@ -2354,26 +2364,29 @@ class _ExploreMapPanelState extends State if (explore is MTDStop) { String markerAsset = 'images/map-marker-mtd-stop.png'; markerIcon = _markerIconCache[markerAsset] ?? - (_markerIconCache[markerAsset] = await BitmapDescriptor.fromAssetImage(imageConfiguration, markerAsset)); + (_markerIconCache[markerAsset] = await BitmapDescriptor.fromAssetImage(imageConfiguration, markerAsset)); markerAnchor = Offset(0.5, 0.5); - } - else { + } else { Color? exploreColor = explore?.mapMarkerColor; - markerIcon = (exploreColor != null) ? BitmapDescriptor.defaultMarkerWithHue(ColorUtils.hueFromColor(exploreColor).toDouble()) : BitmapDescriptor.defaultMarker; + if (_selectedMapType == ExploreMapType.StoriedSites && explore == _selectedMapExplore) { + exploreColor = Styles().colors.fillColorSecondary; + } + markerIcon = (exploreColor != null) + ? BitmapDescriptor.defaultMarkerWithHue(ColorUtils.hueFromColor(exploreColor).toDouble()) + : BitmapDescriptor.defaultMarker; markerAnchor = Offset(0.5, 1); } return Marker( - markerId: MarkerId("${markerPosition.latitude.toStringAsFixed(6)}:${markerPosition.latitude.toStringAsFixed(6)}"), - position: markerPosition, - icon: markerIcon, - anchor: markerAnchor, - consumeTapEvents: true, - onTap: () => _onTapMarker(explore), - infoWindow: InfoWindow( - title: explore?.mapMarkerTitle, - snippet: explore?.mapMarkerSnippet, - anchor: markerAnchor) - ); + markerId: MarkerId("${markerPosition.latitude.toStringAsFixed(6)}:${markerPosition.longitude.toStringAsFixed(6)}"), + position: markerPosition, + icon: markerIcon, + anchor: markerAnchor, + consumeTapEvents: true, + onTap: () => _onTapMarker(explore), + infoWindow: InfoWindow( + title: explore?.mapMarkerTitle, + snippet: explore?.mapMarkerSnippet, + anchor: markerAnchor)); } return null; } diff --git a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart index 44cde1a63..27ef4b0ff 100644 --- a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart +++ b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart @@ -20,8 +20,9 @@ class ExploreStoriedSightsBottomSheet extends StatefulWidget { final List places; final Function(places_model.Place) onPlaceSelected; final void Function(List? filteredPlaces)? onFilteredPlacesChanged; + final VoidCallback? onBackPressed; - ExploreStoriedSightsBottomSheet({Key? key, required this.places, required this.onPlaceSelected, this.onFilteredPlacesChanged}) : super(key: key); + ExploreStoriedSightsBottomSheet({Key? key, required this.places, required this.onPlaceSelected, this.onFilteredPlacesChanged, this.onBackPressed}) : super(key: key); @override ExploreStoriedSightsBottomSheetState createState() => ExploreStoriedSightsBottomSheetState(); @@ -186,6 +187,7 @@ class ExploreStoriedSightsBottomSheetState extends State { _placeCheckInDates.remove(now); }); - AppToast.showMessage(Localization().getStringEx('panel.explore.storied_sites.check_in.try_again', 'Check-in failed. Please try again.')); + AppToast.showMessage(Localization().getStringEx('panel.explore.storied_sites.check_in.try_again', 'Check-in failed. Please sign in and try again.')); } } catch (e) { if (mounted) { From b49177b00882947e14b7487ae52015f2c2b29fb8 Mon Sep 17 00:00:00 2001 From: manavmodi Date: Wed, 6 Nov 2024 11:47:12 -0500 Subject: [PATCH 08/13] Small filter fix --- .../ExploreStoriedSightsBottomSheet.dart | 35 ++++++------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart index 27ef4b0ff..a724ab468 100644 --- a/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart +++ b/lib/ui/explore/ExploreStoriedSightsBottomSheet.dart @@ -673,26 +673,22 @@ class ExploreStoriedSightsBottomSheetState extends State _customPlaces!.contains(place)).toList(); } + // Prepare other filters excluding 'Visited' and custom selection Set filtersToApply = Set.from(_selectedFilters); filtersToApply.remove(_customSelectionFilterKey); + bool isVisitedFilterSelected = filtersToApply.contains('Visited'); + if (isVisitedFilterSelected) { + // Filter to only visited places + filteredPlaces = filteredPlaces.where((place) => place.userData?.visited != null && place.userData!.visited!.isNotEmpty).toList(); + // Remove 'Visited' from filters to apply remaining filters + filtersToApply.remove('Visited'); + } + // Apply remaining filters if (filtersToApply.isNotEmpty) { filteredPlaces = filteredPlaces.where((place) { - bool matchesFilter = false; - if (filtersToApply.contains('Visited')) { - if (place.userData?.visited != null && place.userData!.visited!.isNotEmpty) { - if (filtersToApply.length > 1) { - matchesFilter = _matchesOtherFilters(place, filters: filtersToApply); - } else { - matchesFilter = true; - } - } else { - matchesFilter = false; - } - } else { - matchesFilter = place.tags != null && place.tags!.any((tag) => filtersToApply.contains(tag)); - } - return matchesFilter; + if (place.tags == null || place.tags!.isEmpty) return false; + return place.tags!.any((tag) => filtersToApply.contains(tag)); }).toList(); } @@ -703,15 +699,6 @@ class ExploreStoriedSightsBottomSheetState extends State? filters}) { - Set otherFilters = filters ?? Set.from(_selectedFilters)..remove('Visited'); - otherFilters.remove('Visited'); - if (place.tags == null || place.tags!.isEmpty) { - return false; - } - return place.tags!.any((tag) => otherFilters.contains(tag)); - } - Widget _buildDragHandle() { return Container( width: 88.0, From 6c52b0c0be41e8da4af80f2033c061fb73fbbb4c Mon Sep 17 00:00:00 2001 From: manavmodi Date: Wed, 6 Nov 2024 12:36:49 -0500 Subject: [PATCH 09/13] Clean up the code --- lib/model/Analytics.dart | 2 ++ lib/ui/explore/ExploreMapPanel.dart | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/model/Analytics.dart b/lib/model/Analytics.dart index 575b1f66c..cce5dd062 100644 --- a/lib/model/Analytics.dart +++ b/lib/model/Analytics.dart @@ -49,6 +49,7 @@ class AnalyticsFeature { static const AnalyticsFeature MapMyLocations = AnalyticsFeature("Map: My Locations", priority: -1); static const AnalyticsFeature MapMentalHealth = AnalyticsFeature("Map: Therapist", priority: -1); static const AnalyticsFeature MapStateFarm = AnalyticsFeature("Map: State Farm", priority: -1); + static const AnalyticsFeature StoriedSites = AnalyticsFeature("Map: Storied Sites", priority: -1); static const AnalyticsFeature Events = AnalyticsFeature("Events", key: "Event"); static const AnalyticsFeature EventsAll = AnalyticsFeature("Events: All", priority: -1); @@ -139,6 +140,7 @@ class AnalyticsFeature { MapMyLocations, MapMentalHealth, MapStateFarm, + StoriedSites, Events, EventsAll, diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index 8fef13720..9237f72fe 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -89,6 +89,7 @@ class ExploreMapPanel extends StatefulWidget with AnalyticsInfo { ExploreMapType.MyLocations: AnalyticsFeature.MapMyLocations, ExploreMapType.MentalHealth: AnalyticsFeature.MapMentalHealth, ExploreMapType.StateFarmWayfinding: AnalyticsFeature.MapStateFarm, + ExploreMapType.StoriedSites: AnalyticsFeature.StoriedSites, }; final Map params = {}; @@ -229,6 +230,7 @@ class _ExploreMapPanelState extends State Future?>? _buildMarkersTask; Explore? _pinnedMapExplore; dynamic _selectedMapExplore; + Explore? _selectedStoriedSiteExplore; AnimationController? _mapExploreBarAnimationController; String? _loadingMapStopIdRoutes; @@ -832,6 +834,15 @@ class _ExploreMapPanelState extends State } void _selectMapExplore(dynamic explore) { + if (_selectedMapType == ExploreMapType.StoriedSites) { + setState(() { + _selectedStoriedSiteExplore = explore is Explore ? explore : null; + }); + // Rebuild markers to reflect the change in selected marker + _mapController?.getZoomLevel().then((double value) { + _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); + }); + } if (explore != null) { _pinMapExplore(((explore is ExplorePOI) && StringUtils.isEmpty(explore.placeId)) ? explore : null); setStateIfMounted(() { @@ -850,12 +861,6 @@ class _ExploreMapPanelState extends State } else { _pinMapExplore(null); } - if (_selectedMapType == ExploreMapType.StoriedSites) { - // Get the current zoom level - _mapController?.getZoomLevel().then((double value) { - _buildMapContentData(_filteredExplores ?? _explores, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); - }); - } _logAnalyticsSelect(explore); } @@ -1378,6 +1383,9 @@ class _ExploreMapPanelState extends State _clearActiveFilter(); _selectedMapType = widget._lastSelectedExploreType = item; _itemsDropDownValuesVisible = false; + if (_selectedMapType != ExploreMapType.StoriedSites) { + _selectedStoriedSiteExplore = null; + } }); if (lastExploreType != item) { _targetMapStyle = _currentMapStyle; @@ -2368,7 +2376,7 @@ class _ExploreMapPanelState extends State markerAnchor = Offset(0.5, 0.5); } else { Color? exploreColor = explore?.mapMarkerColor; - if (_selectedMapType == ExploreMapType.StoriedSites && explore == _selectedMapExplore) { + if (_selectedMapType == ExploreMapType.StoriedSites && explore == _selectedStoriedSiteExplore) { exploreColor = Styles().colors.fillColorSecondary; } markerIcon = (exploreColor != null) From 52b2e1a1ceae6ebdeeec767c5e94687acc0ceed6 Mon Sep 17 00:00:00 2001 From: manavmodi Date: Wed, 6 Nov 2024 12:37:48 -0500 Subject: [PATCH 10/13] small fix --- lib/ui/explore/ExploreMapPanel.dart | 35 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index 9237f72fe..96867c5e7 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -843,24 +843,27 @@ class _ExploreMapPanelState extends State _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); }); } - if (explore != null) { - _pinMapExplore(((explore is ExplorePOI) && StringUtils.isEmpty(explore.placeId)) ? explore : null); - setStateIfMounted(() { - _selectedMapExplore = explore; - }); - _updateSelectedMapStopRoutes(); - _mapExploreBarAnimationController?.forward(); - } - else if (_selectedMapExplore != null) { - _pinMapExplore(null); - _selectedMapExplore = null; - _mapExploreBarAnimationController?.reverse().then((_) { - setStateIfMounted(() {}); + else { + if (explore != null) { + _pinMapExplore(((explore is ExplorePOI) && StringUtils.isEmpty(explore.placeId)) ? explore : null); + setStateIfMounted(() { + _selectedMapExplore = explore; + }); _updateSelectedMapStopRoutes(); - }); - } else { - _pinMapExplore(null); + _mapExploreBarAnimationController?.forward(); + } + else if (_selectedMapExplore != null) { + _pinMapExplore(null); + _selectedMapExplore = null; + _mapExploreBarAnimationController?.reverse().then((_) { + setStateIfMounted(() {}); + _updateSelectedMapStopRoutes(); + }); + } else { + _pinMapExplore(null); + } } + _logAnalyticsSelect(explore); } From 83c8a5a9ba1520478fdf58a7311ccdc69aebd90f Mon Sep 17 00:00:00 2001 From: Mihail Varbanov Date: Thu, 7 Nov 2024 09:16:28 +0200 Subject: [PATCH 11/13] More clean up the code [#4458]. --- lib/ui/explore/ExploreMapPanel.dart | 120 ++++++++++++++-------------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index 96867c5e7..9a81cf7c0 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -480,10 +480,6 @@ class _ExploreMapPanelState extends State ]); } - void _onStoriedSitesBackPressed() { - _selectMapExplore(null); - } - // Map Widget Widget _buildContent() { @@ -507,10 +503,8 @@ class _ExploreMapPanelState extends State Widget _buildMapContent() { return Stack(children: [ _buildMapView(), - Visibility( - visible: _selectedMapType != ExploreMapType.StoriedSites, - child: _buildMapExploreBar() - ), + if (_selectedMapType != ExploreMapType.StoriedSites) + _buildMapExploreBar(), Visibility(visible: _markersProgress, child: Positioned.fill(child: Center(child: @@ -623,16 +617,9 @@ class _ExploreMapPanelState extends State void _onTapMarker(dynamic origin) { if (_selectedMapType == ExploreMapType.StoriedSites) { - if (origin is Place) { - _storiedSightsKey.currentState?.selectPlace(origin); - _selectMapExplore(origin); - } else if (origin is List) { - List places = origin.cast(); - _storiedSightsKey.currentState?.selectPlaces(places); - _centerMapOnExplore(places); - _selectMapExplore(places); - } - } else { + _selectStoriedSiteExplore(origin); + } + else { _selectMapExplore(origin); } } @@ -651,6 +638,32 @@ class _ExploreMapPanelState extends State } } + void _onStoriedSitesBackPressed() { + _selectStoriedSiteExplore(null); + } + + void _selectStoriedSiteExplore(dynamic explore) { + + if (explore is Place) { + _storiedSightsKey.currentState?.selectPlace(explore); + } else if (explore is List) { + List places = explore.cast(); + _storiedSightsKey.currentState?.selectPlaces(places); + _centerMapOnExplore(places); + } + + setState(() { + _selectedStoriedSiteExplore = explore is Explore ? explore : null; + }); + + // Rebuild markers to reflect the change in selected marker + _mapController?.getZoomLevel().then((double value) { + _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); + }); + + _logAnalyticsSelect(explore); + } + void _centerMapOnExplore(dynamic explore, {bool zoom = true}) async { LatLng? targetPosition; @@ -834,34 +847,25 @@ class _ExploreMapPanelState extends State } void _selectMapExplore(dynamic explore) { - if (_selectedMapType == ExploreMapType.StoriedSites) { - setState(() { - _selectedStoriedSiteExplore = explore is Explore ? explore : null; - }); - // Rebuild markers to reflect the change in selected marker - _mapController?.getZoomLevel().then((double value) { - _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); + if (explore != null) { + _pinMapExplore(((explore is ExplorePOI) && StringUtils.isEmpty(explore.placeId)) ? explore : null); + setStateIfMounted(() { + _selectedMapExplore = explore; }); + _updateSelectedMapStopRoutes(); + _mapExploreBarAnimationController?.forward(); } - else { - if (explore != null) { - _pinMapExplore(((explore is ExplorePOI) && StringUtils.isEmpty(explore.placeId)) ? explore : null); + else if (_selectedMapExplore != null) { + _pinMapExplore(null); + _mapExploreBarAnimationController?.reverse().then((_) { setStateIfMounted(() { - _selectedMapExplore = explore; + _selectedMapExplore = null; }); _updateSelectedMapStopRoutes(); - _mapExploreBarAnimationController?.forward(); - } - else if (_selectedMapExplore != null) { - _pinMapExplore(null); - _selectedMapExplore = null; - _mapExploreBarAnimationController?.reverse().then((_) { - setStateIfMounted(() {}); - _updateSelectedMapStopRoutes(); - }); - } else { - _pinMapExplore(null); - } + }); + } + else { + _pinMapExplore(null); } _logAnalyticsSelect(explore); @@ -1386,9 +1390,6 @@ class _ExploreMapPanelState extends State _clearActiveFilter(); _selectedMapType = widget._lastSelectedExploreType = item; _itemsDropDownValuesVisible = false; - if (_selectedMapType != ExploreMapType.StoriedSites) { - _selectedStoriedSiteExplore = null; - } }); if (lastExploreType != item) { _targetMapStyle = _currentMapStyle; @@ -1922,6 +1923,7 @@ class _ExploreMapPanelState extends State _mapKey = UniqueKey(); // force map rebuild }); _selectMapExplore(null); + _selectStoriedSiteExplore(null); _displayContentPopups(); } } @@ -2375,29 +2377,29 @@ class _ExploreMapPanelState extends State if (explore is MTDStop) { String markerAsset = 'images/map-marker-mtd-stop.png'; markerIcon = _markerIconCache[markerAsset] ?? - (_markerIconCache[markerAsset] = await BitmapDescriptor.fromAssetImage(imageConfiguration, markerAsset)); + (_markerIconCache[markerAsset] = await BitmapDescriptor.fromAssetImage(imageConfiguration, markerAsset)); markerAnchor = Offset(0.5, 0.5); - } else { + } + else { Color? exploreColor = explore?.mapMarkerColor; if (_selectedMapType == ExploreMapType.StoriedSites && explore == _selectedStoriedSiteExplore) { exploreColor = Styles().colors.fillColorSecondary; } - markerIcon = (exploreColor != null) - ? BitmapDescriptor.defaultMarkerWithHue(ColorUtils.hueFromColor(exploreColor).toDouble()) - : BitmapDescriptor.defaultMarker; + markerIcon = (exploreColor != null) ? BitmapDescriptor.defaultMarkerWithHue(ColorUtils.hueFromColor(exploreColor).toDouble()) : BitmapDescriptor.defaultMarker; markerAnchor = Offset(0.5, 1); } return Marker( - markerId: MarkerId("${markerPosition.latitude.toStringAsFixed(6)}:${markerPosition.longitude.toStringAsFixed(6)}"), - position: markerPosition, - icon: markerIcon, - anchor: markerAnchor, - consumeTapEvents: true, - onTap: () => _onTapMarker(explore), - infoWindow: InfoWindow( - title: explore?.mapMarkerTitle, - snippet: explore?.mapMarkerSnippet, - anchor: markerAnchor)); + markerId: MarkerId("${markerPosition.latitude.toStringAsFixed(6)}:${markerPosition.longitude.toStringAsFixed(6)}"), + position: markerPosition, + icon: markerIcon, + anchor: markerAnchor, + consumeTapEvents: true, + onTap: () => _onTapMarker(explore), + infoWindow: InfoWindow( + title: explore?.mapMarkerTitle, + snippet: explore?.mapMarkerSnippet, + anchor: markerAnchor) + ); } return null; } From 6ff5721c46a78c7acf280f990bcae43d2d87073f Mon Sep 17 00:00:00 2001 From: Mihail Varbanov Date: Thu, 7 Nov 2024 10:33:06 +0200 Subject: [PATCH 12/13] Don't rebuild entire markers set just to change color of a single known marker [#4458]. --- lib/ui/explore/ExploreMapPanel.dart | 71 +++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/lib/ui/explore/ExploreMapPanel.dart b/lib/ui/explore/ExploreMapPanel.dart index 9a81cf7c0..dfacb09f3 100644 --- a/lib/ui/explore/ExploreMapPanel.dart +++ b/lib/ui/explore/ExploreMapPanel.dart @@ -643,27 +643,53 @@ class _ExploreMapPanelState extends State } void _selectStoriedSiteExplore(dynamic explore) { - if (explore is Place) { _storiedSightsKey.currentState?.selectPlace(explore); - } else if (explore is List) { + } + else if (explore is List) { List places = explore.cast(); _storiedSightsKey.currentState?.selectPlaces(places); _centerMapOnExplore(places); } - setState(() { - _selectedStoriedSiteExplore = explore is Explore ? explore : null; - }); - - // Rebuild markers to reflect the change in selected marker - _mapController?.getZoomLevel().then((double value) { - _buildMapContentData(_filteredExplores ?? _explores, pinnedExplore: _pinnedMapExplore, updateCamera: false, showProgress: false, zoom: value, forceRefresh: true); - }); + _updateSelectedStoriedSiteMarker(explore is Explore ? explore : null); _logAnalyticsSelect(explore); } + Future _updateSelectedStoriedSiteMarker(Explore? selectedStoriedSiteExplore) async { + Set? targetMarkers = (_targetMarkers != null) ? Set.from(_targetMarkers!) : null; + if ((targetMarkers != null) && (_selectedStoriedSiteExplore != selectedStoriedSiteExplore)) { + ImageConfiguration imageConfiguration = createLocalImageConfiguration(context); + + if (_selectedStoriedSiteExplore != null) { + Marker? selectedStoriedSiteMarker = targetMarkers.exploreMarker(_selectedStoriedSiteExplore); + Marker? selectedStoriedSiteMarkerUpd = await _createExploreMarker(_selectedStoriedSiteExplore, imageConfiguration: imageConfiguration); + if ((selectedStoriedSiteMarker != null) && (selectedStoriedSiteMarkerUpd != null)) { + targetMarkers.remove(selectedStoriedSiteMarker); + targetMarkers.add(selectedStoriedSiteMarkerUpd); + } + } + + _selectedStoriedSiteExplore = selectedStoriedSiteExplore; + + if (_selectedStoriedSiteExplore != null) { + Marker? selectedStoriedSiteMarker = targetMarkers.exploreMarker(_selectedStoriedSiteExplore); + Marker? selectedStoriedSiteMarkerUpd = await _createExploreMarker(_selectedStoriedSiteExplore, imageConfiguration: imageConfiguration, markerColor: Styles().colors.fillColorSecondary); + if ((selectedStoriedSiteMarker != null) && (selectedStoriedSiteMarkerUpd != null)) { + targetMarkers.remove(selectedStoriedSiteMarker); + targetMarkers.add(selectedStoriedSiteMarkerUpd); + } + } + } + + if (!DeepCollectionEquality().equals(_targetMarkers, targetMarkers)) { + setStateIfMounted((){ + _targetMarkers = targetMarkers; + }); + } + } + void _centerMapOnExplore(dynamic explore, {bool zoom = true}) async { LatLng? targetPosition; @@ -2155,7 +2181,7 @@ class _ExploreMapPanelState extends State // Map Content - Future _buildMapContentData(List? explores, {Explore? pinnedExplore, bool updateCamera = false, bool showProgress = false, double? zoom, bool forceRefresh = false}) async { + Future _buildMapContentData(List? explores, {Explore? pinnedExplore, bool updateCamera = false, bool showProgress = false, double? zoom}) async { LatLngBounds? exploresBounds = ExploreMap.boundsOfList(explores); CameraUpdate? targetCameraUpdate; @@ -2192,7 +2218,7 @@ class _ExploreMapPanelState extends State exploreMarkerGroups = (explores != null) ? { ExploreMap.validFromList(explores) } : null; } - if (forceRefresh || !DeepCollectionEquality().equals(_exploreMarkerGroups, exploreMarkerGroups)) { + if (!DeepCollectionEquality().equals(_exploreMarkerGroups, exploreMarkerGroups)) { Future> buildMarkersTask = _buildMarkers(context, exploreGroups: exploreMarkerGroups, pinnedExplore: pinnedExplore); _buildMarkersTask = buildMarkersTask; if (showProgress && mounted) { @@ -2369,7 +2395,7 @@ class _ExploreMapPanelState extends State } - Future _createExploreMarker(Explore? explore, {required ImageConfiguration imageConfiguration}) async { + Future _createExploreMarker(Explore? explore, {required ImageConfiguration imageConfiguration, Color? markerColor }) async { LatLng? markerPosition = explore?.exploreLocation?.exploreLocationMapCoordinate; if (markerPosition != null) { BitmapDescriptor? markerIcon; @@ -2381,10 +2407,7 @@ class _ExploreMapPanelState extends State markerAnchor = Offset(0.5, 0.5); } else { - Color? exploreColor = explore?.mapMarkerColor; - if (_selectedMapType == ExploreMapType.StoriedSites && explore == _selectedStoriedSiteExplore) { - exploreColor = Styles().colors.fillColorSecondary; - } + Color? exploreColor = markerColor ?? explore?.mapMarkerColor; markerIcon = (exploreColor != null) ? BitmapDescriptor.defaultMarkerWithHue(ColorUtils.hueFromColor(exploreColor).toDouble()) : BitmapDescriptor.defaultMarker; markerAnchor = Offset(0.5, 1); } @@ -2560,4 +2583,16 @@ String? _exploreMapTypeToString(ExploreMapType? value) { class ExploreMapSearchEventsParam { final String searchText; ExploreMapSearchEventsParam(this.searchText); -} \ No newline at end of file +} + +extension _MapMarkersSet on Set { + + Marker? exploreMarker(Explore? explore) { + LatLng? markerPosition = explore?.exploreLocation?.exploreLocationMapCoordinate; + String? markerId = (markerPosition != null) ? "${markerPosition.latitude.toStringAsFixed(6)}:${markerPosition.longitude.toStringAsFixed(6)}" : null; + return (markerId != null) ? markerById(MarkerId(markerId)) : null; + } + + Marker? markerById(MarkerId markerId) => + firstWhereOrNull((marker) => marker.markerId == markerId); +} From fa836046921d4a931e249eb1741124ddd8f5bc42 Mon Sep 17 00:00:00 2001 From: Mihail Varbanov Date: Thu, 7 Nov 2024 10:44:05 +0200 Subject: [PATCH 13/13] Fixed CHANGELOG.md formatting. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44a35d5a5..d53455008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Added - Filter pins on map to match filters/search for storied sites [#4458](https://github.com/rokwire/illinois-app/issues/4458) - Add search to Bottomsheet [#4456](https://github.com/rokwire/illinois-app/issues/4456) + ## [6.0.56] - 2024-11-04 ### Fixed - Bug fixes on the stories sites bottomsheet [#4454](https://github.com/rokwire/illinois-app/issues/4454) @@ -32,7 +33,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added user_auth_type standard analytics property [#4419](https://github.com/rokwire/illinois-app/issues/4419). - ## [6.0.51] - 2024-10-15 ### Fixed - Fixed Poll UI issues [#4414](https://github.com/rokwire/illinois-app/issues/4414).