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