rorystephenson / flutter_map_marker_popup

Popups for flutter_map markers
BSD 3-Clause "New" or "Revised" License
103 stars 84 forks source link

Listen for popup events? #35

Closed magnuswikhog closed 2 years ago

magnuswikhog commented 2 years ago

I just updated the plugin from an older version, and noticed that PopupController doesn't expose the streamController anymore. I found that it is still there, but moved to PopupControllerImpl.

So now I'm wondering, what is the proper way to listen for popup events? I need to take some action when a popup has been shown or hidden. Importing and using PopupControllerImpl feels like a hack (and IntelliJ gives a warning that I shouldn't import implementation files from another package), but I can't find any other way to do it.

rorystephenson commented 2 years ago

Hi @magnuswikhog, thanks for opening the issue.

I've had a double check and you're absolutely right, there is currently no way to listen for popup events without accessing PopupControllerImpl which is definitely not a good solution.

I could expose the PopupEvent stream although I'm wondering if a better solution is possible. Those events don't necessarily tell you what is happening to the popup. For example TogglePopupEvent tells you that a popup is being toggled but unless you know if it's visible or not then you don't know whether that popup will be shown or hidden. The same is true for other events like HideAllPopupsEvent which will only actually hide a popup if it is visible. However maybe this is good enough for your needs?

I'd be interested to know a bit more about your use case to know whether it's possible to come up with something better for you and other users.

magnuswikhog commented 2 years ago

Hi and thanks!

In my app I have a "follow me" mode that moves the map when the user moves so that their position is always at the center of the map. This mode can be toggled off manually. It is also toggled off automatically if the user drags the map, because otherwise the map would jump back to their current location when the next location update arrives.

I also want to toggle the "follow me" mode off automatically when a popup is being displayed, because otherwise the popup could end up moving off screen as the user moves, which would be annoying if they're reading it (I'm displaying quite a lot of information in the popup).

Right now I'm using the hack of reaching in and listening to the streamController in PopupControllerImpl to do this:

    popupSubscription = popupControllerImpl.streamController?.stream?.listen((event){
      if( event is ShowPopupsAlsoFor || event is ShowPopupsOnlyFor ){
        setState((){
          stopFollowing();
        });
      }
    });

So as you can see I'm only listening for events that show the popup, not ones that could be hiding it. I agree that it becomes a bit less clear how to handle for example the TogglePopupEvent. In those cases, perhaps the selectedMarkers list could be used to determine if a popup is showing or not?

rorystephenson commented 2 years ago

Closed automatically as I merged a commit which adds the requested behaviour. It works exactly as you suggested (providing the selectedMarkers) as I think that's the most elegant solution which is not overly specific to a single use case. Thanks for the suggestion!

Let me know if it works OK for you.

kirpit commented 1 year ago

Hi there! I just didn't want to open a new issue as the problem is exactly related to this one again.

See I'm simply trying to center the map to the selected marker by listening on the onPopupEvent but having difficulty to get / compare the type of the event. Firstly, the sealed class PopupEvent is not exposed and I cannot explicitly define the event type in parameters. Secondly, I cannot compare it to anything because its implemented classes are not exposed either:

image

I'm not sure which one I'm supposed to compare it to; whether ShowedPopupsOnlyForImpl or ShowedPopupsOnlyForEvent but adding these lines to the flutter_map_marker_popup.dart library file to would expose them and it works as expected:

// Exposes `PopupEvent` and its abstract subclasses.
export 'src/state/popup_event.dart';
// Exposes `*Impl` classes
export 'src/state/popup_event_impl.dart';

Both event is ShowedPopupsOnlyForEvent and event is ShowedPopupsOnlyForImpl work okay and if the first comparison is fine, we don't even need to include the second export..

PS: I'm currently checking selectedMarkers.length == 1 as a work around but I'm surprised no one complained about this so far.

rorystephenson commented 1 year ago

See I'm simply trying to center the map to the selected marker by listening on the onPopupEvent...

PS: I'm currently checking selectedMarkers.length == 1 as a work around but I'm surprised no one complained about this so far.

Is there a reason you can't use markerCenterAnimation?

kirpit commented 1 year ago

Is there a reason you can't use markerCenterAnimation?

ahh sweet! I've missed that on doco, was almost going to do that manually. thanks heaps, it's indeed useful.

but I guess it doesn't remove the problem if anyone wants to implement that event. I leave it for you guys to decide whether to fix or not, and how.