xref: /expo/packages/expo-maps/src/Events.ts (revision ee0de234)
1import { EventEmitter, Subscription, ProxyNativeModule } from 'expo-modules-core';
2import { Platform } from 'react-native';
3
4import {
5  CameraPosition,
6  MapCluster,
7  Marker,
8  Point,
9  PointOfInterest,
10  UserLocation,
11} from './Common.types';
12import { NativeExpoAppleMapsModule, NativeExpoGoogleMapsModule } from './ExpoMaps';
13
14let module: ProxyNativeModule;
15if (Platform.OS === 'ios') {
16  module = NativeExpoAppleMapsModule;
17} else {
18  module = NativeExpoGoogleMapsModule;
19}
20
21const emitter = new EventEmitter(module);
22
23const MapsEventsNames = {
24  ON_MARKER_CLICK_EVENT: 'onMarkerClick',
25  ON_MARKER_DRAG_STARTED_EVENT: 'onMarkerDragStarted',
26  ON_MARKER_DRAG_ENDED_EVENT: 'onMarkerDragEnded',
27};
28
29/**
30 * Type of an argument of MarkerClick listener.
31 */
32export type MarkerClickEvent = {
33  /**
34   * Id of the marker that was clicked.
35   */
36  id: string;
37};
38
39/**
40 * Type of an argument of MarkerDragEnded listener.
41 */
42export type MarkerDragEndedEvent = {
43  /**
44   * Id of the marker that was dragged.
45   */
46  id: string;
47  /**
48   * Latitude of the dragged marker.
49   */
50  latitude: number;
51  /**
52   * Longitude of the dragged marker.
53   */
54  longitude: number;
55};
56
57/**
58 * Type of an argument of MarkerDragStarted listener.
59 */
60export type MarkerDragStartedEvent = {
61  /**
62   * Id of the marker that was dragged.
63   */
64  id: string;
65};
66
67/**
68 * Represents data returned on click event.
69 */
70export type OnMapPressEvent = {
71  /**
72   * Coordinates the place where the user clicked.
73   * Represented by {@link Point}
74   */
75  nativeEvent: Point;
76};
77
78/**
79 * Type used for marker related events. eq. onMarkerClick, onMarkerDrag etc. contains marker's ID and position
80 */
81export type MarkerEvent = {
82  nativeEvent: Marker;
83};
84
85/**
86 * Represents data returned when a cluster press event is called
87 */
88export type ClusterPressEvent = {
89  nativeEvent: MapCluster;
90};
91
92/**
93 * Represents data returned on RegionChangeEvent
94 */
95export type OnRegionChangeEvent = {
96  /**
97   * Information on cameraPosition.
98   * Represented by {@link CameraPosition}
99   */
100  nativeEvent: CameraPosition;
101};
102
103/**
104 * Represents data returned on PoiClickEvent
105 */
106export type OnPoiClickEvent = {
107  /**
108   * Information on the clicked point of interest.
109   * Represented by {@link PointOfInterest}
110   */
111  nativeEvent: PointOfInterest;
112};
113
114/**
115 * Event returned when the location button is pressed
116 */
117export type OnLocationButtonPressEvent = {
118  nativeEvent: UserLocation;
119};
120
121/**
122 * Event returned when the current location dot is pressed
123 */
124export type OnLocationDotPressEvent = {
125  nativeEvent: UserLocation;
126};
127
128/**
129 * Event returned when the user changes their location
130 */
131export type OnLocationChangeEvent = {
132  nativeEvent: UserLocation;
133};
134
135/**
136 * Adds a new listener to be called when a marker or cluster is clicked.
137 * @returns Subscription which can be used later to remove this particular listener.
138 */
139export function addOnMarkerClickListener(
140  listener: (event: MarkerClickEvent) => void
141): Subscription {
142  return emitter.addListener<MarkerClickEvent>(MapsEventsNames.ON_MARKER_CLICK_EVENT, listener);
143}
144
145/**
146 * Removes all listeners registered to listen for MarkerClick event.
147 */
148export function removeAllOnMarkerClickListeners() {
149  emitter.removeAllListeners(MapsEventsNames.ON_MARKER_CLICK_EVENT);
150}
151
152/**
153 * Adds a new listener to be called when a user starts dragging a marker.
154 * Does not work for markers which are children of Cluster.
155 * @returns Subscription which can be used later to remove this particular listener.
156 */
157export function addOnMarkerDragStartedListener(
158  listener: (event: MarkerDragStartedEvent) => void
159): Subscription {
160  return emitter.addListener<MarkerDragStartedEvent>(
161    MapsEventsNames.ON_MARKER_DRAG_STARTED_EVENT,
162    listener
163  );
164}
165
166/**
167 * Removes all listeners registered to listen for MarkerDragStarted event.
168 */
169export function removeAllOnMarkerDragStartedListeners() {
170  emitter.removeAllListeners(MapsEventsNames.ON_MARKER_DRAG_STARTED_EVENT);
171}
172
173/**
174 * Adds a new listener to be called when a user drops a marker.
175 * Does not work for markers which are children of Cluster.
176 * @returns Subscription which can be used later to remove this particular listener.
177 */
178export function addOnMarkerDragEndedListener(
179  listener: (event: MarkerDragEndedEvent) => void
180): Subscription {
181  return emitter.addListener<MarkerDragEndedEvent>(
182    MapsEventsNames.ON_MARKER_DRAG_ENDED_EVENT,
183    listener
184  );
185}
186
187/**
188 * Removes all listeners registered to listen for MarkerDragEnded event.
189 */
190export function removeAllOnMarkerDragEndedListeners() {
191  emitter.removeAllListeners(MapsEventsNames.ON_MARKER_DRAG_ENDED_EVENT);
192}
193
194/**
195 * Removes particular listener, which was earlier registered.
196 */
197export function removeEventListener(subscription: Subscription) {
198  emitter.removeSubscription(subscription);
199}
200
201/**
202 * Removes all registered listeners.
203 */
204export function removeAllListeners() {
205  for (const event in MapsEventsNames) {
206    emitter.removeAllListeners(MapsEventsNames[event]);
207  }
208}
209