Skip to content

Commit

Permalink
Merge pull request #4459 from rokwire/4458-feature-filter-pins-on-map…
Browse files Browse the repository at this point in the history
…-to-match-filterssearch-for-storied-sites

[FEATURE] Filter pins on map to match filters/search for storied sites
  • Loading branch information
mihail-varbanov authored Nov 7, 2024
2 parents 02a9050 + fa83604 commit e3459bf
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 60 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ 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
- Bug fixes on the stories sites bottomsheet [#4454](https://github.com/rokwire/illinois-app/issues/4454)
Expand All @@ -31,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).
Expand Down
2 changes: 1 addition & 1 deletion assets/strings.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down
2 changes: 1 addition & 1 deletion assets/strings.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down
2 changes: 1 addition & 1 deletion assets/strings.zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down
2 changes: 2 additions & 0 deletions lib/model/Analytics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -139,6 +140,7 @@ class AnalyticsFeature {
MapMyLocations,
MapMentalHealth,
MapStateFarm,
StoriedSites,

Events,
EventsAll,
Expand Down
126 changes: 103 additions & 23 deletions lib/ui/explore/ExploreMapPanel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, dynamic> params = <String, dynamic>{};
Expand Down Expand Up @@ -195,6 +196,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
bool _filtersDropdownVisible = false;

List<Explore>? _explores;
List<Explore>? _filteredExplores;
bool _exploreProgress = false;
Future<List<Explore>?>? _exploreTask;

Expand Down Expand Up @@ -228,6 +230,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
Future<Set<Marker>?>? _buildMarkersTask;
Explore? _pinnedMapExplore;
dynamic _selectedMapExplore;
Explore? _selectedStoriedSiteExplore;
AnimationController? _mapExploreBarAnimationController;

String? _loadingMapStopIdRoutes;
Expand Down Expand Up @@ -375,7 +378,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
}
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(() { });
Expand Down Expand Up @@ -467,10 +470,9 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
ExploreStoriedSightsBottomSheet(
key: _storiedSightsKey,
places: _explores?.whereType<Place>().toList() ?? [],
onPlaceSelected: (places_model.Place place) {
_centerMapOnExplore(place, zoom: false);
_selectMapExplore(place);
},
onPlaceSelected: _onStoriedSitesPlaceSelected,
onFilteredPlacesChanged: _onStoriedSitesFilteredPlacesChanged,
onBackPressed: _onStoriedSitesBackPressed,
),
_buildExploreTypesDropDownContainer(),
]),
Expand Down Expand Up @@ -501,7 +503,8 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
Widget _buildMapContent() {
return Stack(children: [
_buildMapView(),
_buildMapExploreBar(),
if (_selectedMapType != ExploreMapType.StoriedSites)
_buildMapExploreBar(),
Visibility(visible: _markersProgress, child:
Positioned.fill(child:
Center(child:
Expand Down Expand Up @@ -579,7 +582,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
_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);
}
});
}
Expand Down Expand Up @@ -614,19 +617,78 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>

void _onTapMarker(dynamic origin) {
if (_selectedMapType == ExploreMapType.StoriedSites) {
if (origin is Place) {
_storiedSightsKey.currentState?.selectPlace(origin);
// _centerMapOnExplore(origin);
} else if (origin is List<Explore>) {
List<places_model.Place> places = origin.cast<places_model.Place>();
_storiedSightsKey.currentState?.selectPlaces(places);
_centerMapOnExplore(places);
}
} else {
_selectStoriedSiteExplore(origin);
}
else {
_selectMapExplore(origin);
}
}

void _onStoriedSitesPlaceSelected(places_model.Place place) {
_centerMapOnExplore(place, zoom: false);
_selectMapExplore(place);
}

void _onStoriedSitesFilteredPlacesChanged(List<places_model.Place>? 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 _onStoriedSitesBackPressed() {
_selectStoriedSiteExplore(null);
}

void _selectStoriedSiteExplore(dynamic explore) {
if (explore is Place) {
_storiedSightsKey.currentState?.selectPlace(explore);
}
else if (explore is List<Explore>) {
List<places_model.Place> places = explore.cast<places_model.Place>();
_storiedSightsKey.currentState?.selectPlaces(places);
_centerMapOnExplore(places);
}

_updateSelectedStoriedSiteMarker(explore is Explore ? explore : null);

_logAnalyticsSelect(explore);
}

Future<void> _updateSelectedStoriedSiteMarker(Explore? selectedStoriedSiteExplore) async {
Set<Marker>? targetMarkers = (_targetMarkers != null) ? Set<Marker>.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;
Expand Down Expand Up @@ -831,6 +893,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
else {
_pinMapExplore(null);
}

_logAnalyticsSelect(explore);
}

Expand Down Expand Up @@ -1880,16 +1943,19 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
if (mounted && (exploreTask == _exploreTask)) {
setState(() {
_explores = explores;
_filteredExplores = null;
_exploreTask = null;
_exploreProgress = false;
_mapKey = UniqueKey(); // force map rebuild
});
_selectMapExplore(null);
_selectStoriedSiteExplore(null);
_displayContentPopups();
}
}
}
}


Future<void> _refreshExplores() async {
Future<List<Explore>?> exploreTask = _loadExplores();
List<Explore>? explores = await (_exploreTask = exploreTask);
Expand All @@ -1899,6 +1965,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
if (mounted && (exploreTask == _exploreTask)) {
setState(() {
_explores = explores;
_filteredExplores = null;
_exploreProgress = false;
_exploreTask = null;
});
Expand Down Expand Up @@ -2083,6 +2150,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
if (mounted) {
setState(() {
_explores = explores;
_filteredExplores = null;
});
}
});
Expand Down Expand Up @@ -2149,7 +2217,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
thresoldDistance = 0;
exploreMarkerGroups = (explores != null) ? <dynamic>{ ExploreMap.validFromList(explores) } : null;
}

if (!DeepCollectionEquality().equals(_exploreMarkerGroups, exploreMarkerGroups)) {
Future<Set<Marker>> buildMarkersTask = _buildMarkers(context, exploreGroups: exploreMarkerGroups, pinnedExplore: pinnedExplore);
_buildMarkersTask = buildMarkersTask;
Expand Down Expand Up @@ -2327,7 +2395,7 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
}


Future<Marker?> _createExploreMarker(Explore? explore, {required ImageConfiguration imageConfiguration}) async {
Future<Marker?> _createExploreMarker(Explore? explore, {required ImageConfiguration imageConfiguration, Color? markerColor }) async {
LatLng? markerPosition = explore?.exploreLocation?.exploreLocationMapCoordinate;
if (markerPosition != null) {
BitmapDescriptor? markerIcon;
Expand All @@ -2339,19 +2407,19 @@ class _ExploreMapPanelState extends State<ExploreMapPanel>
markerAnchor = Offset(0.5, 0.5);
}
else {
Color? exploreColor = explore?.mapMarkerColor;
Color? exploreColor = markerColor ?? explore?.mapMarkerColor;
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)}"),
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,
title: explore?.mapMarkerTitle,
snippet: explore?.mapMarkerSnippet,
anchor: markerAnchor)
);
Expand Down Expand Up @@ -2515,4 +2583,16 @@ String? _exploreMapTypeToString(ExploreMapType? value) {
class ExploreMapSearchEventsParam {
final String searchText;
ExploreMapSearchEventsParam(this.searchText);
}
}

extension _MapMarkersSet on Set<Marker> {

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

0 comments on commit e3459bf

Please sign in to comment.