react-native-nitro-location-tracking 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/LICENSE +20 -0
  2. package/NitroLocationTracking.podspec +29 -0
  3. package/README.md +39 -0
  4. package/android/CMakeLists.txt +24 -0
  5. package/android/build.gradle +122 -0
  6. package/android/src/main/AndroidManifest.xml +18 -0
  7. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  8. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/ConnectionManager.kt +137 -0
  9. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/LocationEngine.kt +93 -0
  10. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/LocationForegroundService.kt +65 -0
  11. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NativeDBWriter.kt +80 -0
  12. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NitroLocationTracking.kt +180 -0
  13. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NitroLocationTrackingPackage.kt +22 -0
  14. package/android/src/main/java/com/margelo/nitro/nitrolocationtracking/NotificationService.kt +75 -0
  15. package/ios/ConnectionManager.swift +144 -0
  16. package/ios/LocationEngine.swift +146 -0
  17. package/ios/NativeDBWriter.swift +121 -0
  18. package/ios/NitroLocationTracking.swift +127 -0
  19. package/ios/NotificationService.swift +31 -0
  20. package/lib/module/LocationSmoother.js +33 -0
  21. package/lib/module/LocationSmoother.js.map +1 -0
  22. package/lib/module/NitroLocationTracking.nitro.js +4 -0
  23. package/lib/module/NitroLocationTracking.nitro.js.map +1 -0
  24. package/lib/module/bearing.js +19 -0
  25. package/lib/module/bearing.js.map +1 -0
  26. package/lib/module/db.js +234 -0
  27. package/lib/module/db.js.map +1 -0
  28. package/lib/module/index.js +68 -0
  29. package/lib/module/index.js.map +1 -0
  30. package/lib/module/package.json +1 -0
  31. package/lib/typescript/package.json +1 -0
  32. package/lib/typescript/src/LocationSmoother.d.ts +19 -0
  33. package/lib/typescript/src/LocationSmoother.d.ts.map +1 -0
  34. package/lib/typescript/src/NitroLocationTracking.nitro.d.ts +59 -0
  35. package/lib/typescript/src/NitroLocationTracking.nitro.d.ts.map +1 -0
  36. package/lib/typescript/src/bearing.d.ts +9 -0
  37. package/lib/typescript/src/bearing.d.ts.map +1 -0
  38. package/lib/typescript/src/db.d.ts +1 -0
  39. package/lib/typescript/src/db.d.ts.map +1 -0
  40. package/lib/typescript/src/index.d.ts +21 -0
  41. package/lib/typescript/src/index.d.ts.map +1 -0
  42. package/nitro.json +17 -0
  43. package/nitrogen/generated/android/c++/JAccuracyLevel.hpp +61 -0
  44. package/nitrogen/generated/android/c++/JConnectionConfig.hpp +81 -0
  45. package/nitrogen/generated/android/c++/JConnectionState.hpp +61 -0
  46. package/nitrogen/generated/android/c++/JFunc_void_ConnectionState.hpp +77 -0
  47. package/nitrogen/generated/android/c++/JFunc_void_LocationData.hpp +77 -0
  48. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
  49. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  50. package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.cpp +179 -0
  51. package/nitrogen/generated/android/c++/JHybridNitroLocationTrackingSpec.hpp +83 -0
  52. package/nitrogen/generated/android/c++/JLocationConfig.hpp +91 -0
  53. package/nitrogen/generated/android/c++/JLocationData.hpp +81 -0
  54. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/AccuracyLevel.kt +24 -0
  55. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/ConnectionConfig.kt +56 -0
  56. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/ConnectionState.kt +24 -0
  57. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/Func_void_ConnectionState.kt +80 -0
  58. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/Func_void_LocationData.kt +80 -0
  59. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/Func_void_bool.kt +80 -0
  60. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/Func_void_std__string.kt +80 -0
  61. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/HybridNitroLocationTrackingSpec.kt +146 -0
  62. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/LocationConfig.kt +62 -0
  63. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/LocationData.kt +56 -0
  64. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolocationtracking/nitrolocationtrackingOnLoad.kt +35 -0
  65. package/nitrogen/generated/android/nitrolocationtracking+autolinking.cmake +81 -0
  66. package/nitrogen/generated/android/nitrolocationtracking+autolinking.gradle +27 -0
  67. package/nitrogen/generated/android/nitrolocationtrackingOnLoad.cpp +52 -0
  68. package/nitrogen/generated/android/nitrolocationtrackingOnLoad.hpp +25 -0
  69. package/nitrogen/generated/ios/NitroLocationTracking+autolinking.rb +60 -0
  70. package/nitrogen/generated/ios/NitroLocationTracking-Swift-Cxx-Bridge.cpp +73 -0
  71. package/nitrogen/generated/ios/NitroLocationTracking-Swift-Cxx-Bridge.hpp +231 -0
  72. package/nitrogen/generated/ios/NitroLocationTracking-Swift-Cxx-Umbrella.hpp +61 -0
  73. package/nitrogen/generated/ios/NitroLocationTrackingAutolinking.mm +33 -0
  74. package/nitrogen/generated/ios/NitroLocationTrackingAutolinking.swift +26 -0
  75. package/nitrogen/generated/ios/c++/HybridNitroLocationTrackingSpecSwift.cpp +11 -0
  76. package/nitrogen/generated/ios/c++/HybridNitroLocationTrackingSpecSwift.hpp +206 -0
  77. package/nitrogen/generated/ios/swift/AccuracyLevel.swift +44 -0
  78. package/nitrogen/generated/ios/swift/ConnectionConfig.swift +59 -0
  79. package/nitrogen/generated/ios/swift/ConnectionState.swift +44 -0
  80. package/nitrogen/generated/ios/swift/Func_void_ConnectionState.swift +46 -0
  81. package/nitrogen/generated/ios/swift/Func_void_LocationData.swift +46 -0
  82. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  83. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
  84. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  85. package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec.swift +72 -0
  86. package/nitrogen/generated/ios/swift/HybridNitroLocationTrackingSpec_cxx.swift +362 -0
  87. package/nitrogen/generated/ios/swift/LocationConfig.swift +69 -0
  88. package/nitrogen/generated/ios/swift/LocationData.swift +59 -0
  89. package/nitrogen/generated/shared/c++/AccuracyLevel.hpp +80 -0
  90. package/nitrogen/generated/shared/c++/ConnectionConfig.hpp +107 -0
  91. package/nitrogen/generated/shared/c++/ConnectionState.hpp +80 -0
  92. package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.cpp +38 -0
  93. package/nitrogen/generated/shared/c++/HybridNitroLocationTrackingSpec.hpp +92 -0
  94. package/nitrogen/generated/shared/c++/LocationConfig.hpp +117 -0
  95. package/nitrogen/generated/shared/c++/LocationData.hpp +107 -0
  96. package/package.json +174 -0
  97. package/src/LocationSmoother.ts +46 -0
  98. package/src/NitroLocationTracking.nitro.ts +79 -0
  99. package/src/bearing.ts +22 -0
  100. package/src/db.ts +232 -0
  101. package/src/index.tsx +92 -0
@@ -0,0 +1,79 @@
1
+ import type { HybridObject } from 'react-native-nitro-modules';
2
+
3
+ // ─── Enums ───────────────────────────────────────────
4
+
5
+ export type AccuracyLevel = 'high' | 'balanced' | 'low';
6
+ export type ConnectionState = 'connected' | 'disconnected' | 'reconnecting';
7
+
8
+ // ─── Types ───────────────────────────────────────────
9
+
10
+ export interface LocationData {
11
+ latitude: number;
12
+ longitude: number;
13
+ altitude: number;
14
+ speed: number; // m/s
15
+ bearing: number; // degrees
16
+ accuracy: number; // meters
17
+ timestamp: number; // unix ms
18
+ }
19
+
20
+ export interface LocationConfig {
21
+ desiredAccuracy: AccuracyLevel;
22
+ distanceFilter: number; // meters
23
+ intervalMs: number; // Android only
24
+ fastestIntervalMs: number; // Android only
25
+ stopTimeout: number; // minutes before declaring stopped
26
+ stopOnTerminate: boolean; // keep tracking after app close (Android)
27
+ startOnBoot: boolean; // restart tracking after reboot (Android)
28
+ foregroundNotificationTitle: string;
29
+ foregroundNotificationText: string;
30
+ }
31
+
32
+ export interface ConnectionConfig {
33
+ wsUrl: string;
34
+ restUrl: string;
35
+ authToken: string;
36
+ reconnectIntervalMs: number;
37
+ maxReconnectAttempts: number;
38
+ batchSize: number; // locations per batch upload
39
+ syncIntervalMs: number; // how often to flush queue
40
+ }
41
+
42
+ export type LocationCallback = (location: LocationData) => void;
43
+ export type ConnectionStateCallback = (state: ConnectionState) => void;
44
+ export type MessageCallback = (message: string) => void;
45
+
46
+ // ─── Hybrid Object ──────────────────────────────────
47
+
48
+ export interface NitroLocationTracking
49
+ extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
50
+ // === Location Engine ===
51
+ configure(config: LocationConfig): void;
52
+ startTracking(): void;
53
+ stopTracking(): void;
54
+ getCurrentLocation(): Promise<LocationData>;
55
+ isTracking(): boolean;
56
+
57
+ onLocation(callback: LocationCallback): void;
58
+ onMotionChange(callback: (isMoving: boolean) => void): void;
59
+
60
+ // === Connection Manager ===
61
+ configureConnection(config: ConnectionConfig): void;
62
+ connectWebSocket(): void;
63
+ disconnectWebSocket(): void;
64
+ sendMessage(message: string): void;
65
+ getConnectionState(): ConnectionState;
66
+
67
+ onConnectionStateChange(callback: ConnectionStateCallback): void;
68
+ onMessage(callback: MessageCallback): void;
69
+
70
+ // === Sync Control ===
71
+ forceSync(): Promise<boolean>;
72
+
73
+ // === Notifications ===
74
+ showLocalNotification(title: string, body: string): void;
75
+ updateForegroundNotification(title: string, body: string): void;
76
+
77
+ // === Lifecycle ===
78
+ destroy(): void;
79
+ }
package/src/bearing.ts ADDED
@@ -0,0 +1,22 @@
1
+ export function shortestRotation(from: number, to: number): number {
2
+ let diff = to - from;
3
+ while (diff > 180) diff -= 360;
4
+ while (diff < -180) diff += 360;
5
+ return from + diff;
6
+ }
7
+
8
+ export function calculateBearing(
9
+ from: { latitude: number; longitude: number },
10
+ to: { latitude: number; longitude: number }
11
+ ): number {
12
+ const toRad = (d: number) => (d * Math.PI) / 180;
13
+ const toDeg = (r: number) => (r * 180) / Math.PI;
14
+ const dLon = toRad(to.longitude - from.longitude);
15
+ const lat1 = toRad(from.latitude);
16
+ const lat2 = toRad(to.latitude);
17
+ const y = Math.sin(dLon) * Math.cos(lat2);
18
+ const x =
19
+ Math.cos(lat1) * Math.sin(lat2) -
20
+ Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
21
+ return (toDeg(Math.atan2(y, x)) + 360) % 360;
22
+ }
package/src/db.ts ADDED
@@ -0,0 +1,232 @@
1
+ // import { open } from 'react-native-nitro-sqlite'
2
+
3
+ // // Open the SAME database that native module writes to
4
+ // export const db = open({ name: 'nitro_location.db' })
5
+
6
+ // // Enable WAL for safe concurrent access with native writer
7
+ // db.execute('PRAGMA journal_mode = WAL')
8
+
9
+ // // ─── Additional Tables (JS-managed) ────────────────
10
+
11
+ // db.execute(`
12
+ // CREATE TABLE IF NOT EXISTS rides (
13
+ // id TEXT PRIMARY KEY,
14
+ // driver_id TEXT,
15
+ // rider_id TEXT,
16
+ // status TEXT DEFAULT 'pending',
17
+ // pickup_lat REAL, pickup_lng REAL,
18
+ // dropoff_lat REAL, dropoff_lng REAL,
19
+ // pickup_address TEXT, dropoff_address TEXT,
20
+ // fare_amount REAL,
21
+ // distance_km REAL,
22
+ // duration_minutes REAL,
23
+ // started_at INTEGER,
24
+ // completed_at INTEGER,
25
+ // created_at INTEGER DEFAULT (strftime('%s','now') * 1000)
26
+ // )
27
+ // `)
28
+
29
+ // db.execute(`
30
+ // CREATE TABLE IF NOT EXISTS earnings (
31
+ // id TEXT PRIMARY KEY,
32
+ // date TEXT UNIQUE,
33
+ // ride_count INTEGER DEFAULT 0,
34
+ // total_amount REAL DEFAULT 0,
35
+ // total_distance REAL DEFAULT 0,
36
+ // online_hours REAL DEFAULT 0
37
+ // )
38
+ // `)
39
+
40
+ // db.execute(`
41
+ // CREATE TABLE IF NOT EXISTS settings (
42
+ // key TEXT PRIMARY KEY,
43
+ // value TEXT
44
+ // )
45
+ // `)
46
+
47
+ // // ─── Query Helpers — Locations ──────────────────────
48
+
49
+ // export function getRecentLocations(limit = 100) {
50
+ // return db.execute(
51
+ // 'SELECT * FROM locations ORDER BY timestamp DESC LIMIT ?',
52
+ // [limit]
53
+ // )
54
+ // }
55
+
56
+ // export function getRideLocations(rideId: string) {
57
+ // return db.execute(
58
+ // `
59
+ // SELECT latitude, longitude, speed, bearing, timestamp
60
+ // FROM locations WHERE ride_id = ? ORDER BY timestamp ASC
61
+ // `,
62
+ // [rideId]
63
+ // )
64
+ // }
65
+
66
+ // export function getLocationsBetween(startMs: number, endMs: number) {
67
+ // return db.execute(
68
+ // `
69
+ // SELECT * FROM locations
70
+ // WHERE timestamp BETWEEN ? AND ? ORDER BY timestamp ASC
71
+ // `,
72
+ // [startMs, endMs]
73
+ // )
74
+ // }
75
+
76
+ // export function getUnsyncedCount(): number {
77
+ // return db.execute(
78
+ // 'SELECT COUNT(*) as count FROM locations WHERE synced = 0'
79
+ // ).rows.item(0)!.count as number
80
+ // }
81
+
82
+ // // ─── Query Helpers — Analytics ──────────────────────
83
+
84
+ // export function getTodayStats() {
85
+ // const today = new Date().toISOString().split('T')[0]!
86
+ // return db.execute(
87
+ // `
88
+ // SELECT COUNT(*) as trips,
89
+ // COALESCE(SUM(fare_amount), 0) as earnings,
90
+ // COALESCE(SUM(distance_km), 0) as distance,
91
+ // COALESCE(SUM(duration_minutes), 0) as minutes
92
+ // FROM rides
93
+ // WHERE date(started_at / 1000, 'unixepoch') = ?
94
+ // AND status = 'completed'
95
+ // `,
96
+ // [today]
97
+ // )
98
+ // }
99
+
100
+ // export function getWeeklyEarnings() {
101
+ // return db.execute(
102
+ // `
103
+ // SELECT date(started_at / 1000, 'unixepoch') as day,
104
+ // COUNT(*) as trips, SUM(fare_amount) as earnings,
105
+ // SUM(distance_km) as distance
106
+ // FROM rides WHERE started_at > ? AND status = 'completed'
107
+ // GROUP BY day ORDER BY day ASC
108
+ // `,
109
+ // [Date.now() - 7 * 86400000]
110
+ // )
111
+ // }
112
+
113
+ // export function getSpeedHistory(lastHours = 1) {
114
+ // return db.execute(
115
+ // `
116
+ // SELECT CAST(timestamp / 60000 AS INTEGER) * 60000 as minute,
117
+ // AVG(speed) as avg_speed, MAX(speed) as max_speed
118
+ // FROM locations WHERE timestamp > ?
119
+ // GROUP BY minute ORDER BY minute ASC
120
+ // `,
121
+ // [Date.now() - lastHours * 3600000]
122
+ // )
123
+ // }
124
+
125
+ // export function getPickupHeatmap(limit = 50) {
126
+ // return db.execute(
127
+ // `
128
+ // SELECT ROUND(pickup_lat, 3) as lat, ROUND(pickup_lng, 3) as lng,
129
+ // COUNT(*) as ride_count
130
+ // FROM rides WHERE status = 'completed'
131
+ // GROUP BY lat, lng ORDER BY ride_count DESC LIMIT ?
132
+ // `,
133
+ // [limit]
134
+ // )
135
+ // }
136
+
137
+ // export function getPeakHours() {
138
+ // return db.execute(`
139
+ // SELECT CAST(strftime('%H', started_at / 1000, 'unixepoch') AS INTEGER) as hour,
140
+ // COUNT(*) as trips, AVG(fare_amount) as avg_fare
141
+ // FROM rides WHERE status = 'completed'
142
+ // GROUP BY hour ORDER BY hour ASC
143
+ // `)
144
+ // }
145
+
146
+ // // ─── Query Helpers — Ride Management ────────────────
147
+
148
+ // export function createRide(ride: {
149
+ // id: string
150
+ // driverId?: string
151
+ // riderId?: string
152
+ // pickupLat: number
153
+ // pickupLng: number
154
+ // pickupAddress: string
155
+ // dropoffLat: number
156
+ // dropoffLng: number
157
+ // dropoffAddress: string
158
+ // }) {
159
+ // return db.execute(
160
+ // `
161
+ // INSERT INTO rides (id, driver_id, rider_id, status,
162
+ // pickup_lat, pickup_lng, pickup_address,
163
+ // dropoff_lat, dropoff_lng, dropoff_address, started_at)
164
+ // VALUES (?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?)
165
+ // `,
166
+ // [
167
+ // ride.id,
168
+ // ride.driverId ?? null,
169
+ // ride.riderId ?? null,
170
+ // ride.pickupLat,
171
+ // ride.pickupLng,
172
+ // ride.pickupAddress,
173
+ // ride.dropoffLat,
174
+ // ride.dropoffLng,
175
+ // ride.dropoffAddress,
176
+ // Date.now(),
177
+ // ]
178
+ // )
179
+ // }
180
+
181
+ // export function completeRide(
182
+ // rideId: string,
183
+ // fare: number,
184
+ // distKm: number
185
+ // ) {
186
+ // const now = Date.now()
187
+ // db.execute(
188
+ // `
189
+ // UPDATE rides SET status = 'completed', fare_amount = ?,
190
+ // distance_km = ?, completed_at = ?,
191
+ // duration_minutes = (? - started_at) / 60000.0
192
+ // WHERE id = ?
193
+ // `,
194
+ // [fare, distKm, now, now, rideId]
195
+ // )
196
+ // }
197
+
198
+ // export function getRideHistory(limit = 20) {
199
+ // return db.execute(
200
+ // `
201
+ // SELECT * FROM rides WHERE status = 'completed'
202
+ // ORDER BY completed_at DESC LIMIT ?
203
+ // `,
204
+ // [limit]
205
+ // )
206
+ // }
207
+
208
+ // export function getRideWithLocations(rideId: string) {
209
+ // const ride = db.execute('SELECT * FROM rides WHERE id = ?', [rideId])
210
+ // const locs = db.execute(
211
+ // `
212
+ // SELECT latitude, longitude, speed, bearing, timestamp
213
+ // FROM locations WHERE ride_id = ? ORDER BY timestamp ASC
214
+ // `,
215
+ // [rideId]
216
+ // )
217
+ // return { ride: ride.rows.item(0), locations: locs.rows._array }
218
+ // }
219
+
220
+ // // ─── Settings Helper ────────────────────────────────
221
+
222
+ // export function getSetting(key: string): string | null {
223
+ // const r = db.execute('SELECT value FROM settings WHERE key = ?', [key])
224
+ // return r.rows.length > 0 ? (r.rows.item(0)!.value as string) : null
225
+ // }
226
+
227
+ // export function setSetting(key: string, value: string) {
228
+ // db.execute(
229
+ // 'INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)',
230
+ // [key, value]
231
+ // )
232
+ // }
package/src/index.tsx ADDED
@@ -0,0 +1,92 @@
1
+ import { useState, useEffect, useCallback, useRef } from 'react';
2
+ import { NitroModules } from 'react-native-nitro-modules';
3
+ import type {
4
+ NitroLocationTracking,
5
+ LocationData,
6
+ LocationConfig,
7
+ ConnectionConfig,
8
+ } from './NitroLocationTracking.nitro';
9
+
10
+ const NitroLocationModule =
11
+ NitroModules.createHybridObject<NitroLocationTracking>(
12
+ 'NitroLocationTracking'
13
+ );
14
+
15
+ export default NitroLocationModule;
16
+ export { LocationSmoother } from './LocationSmoother';
17
+ export { shortestRotation, calculateBearing } from './bearing';
18
+ // export * from './db'
19
+ export type {
20
+ NitroLocationTracking,
21
+ LocationData,
22
+ LocationConfig,
23
+ ConnectionConfig,
24
+ } from './NitroLocationTracking.nitro';
25
+
26
+ export function useDriverLocation(config: LocationConfig) {
27
+ const [location, setLocation] = useState<LocationData | null>(null);
28
+ const [isMoving, setIsMoving] = useState(false);
29
+ const [isTracking, setIsTracking] = useState(false);
30
+
31
+ // Stabilize config by value so the effect doesn't re-run on every render
32
+ const configJson = JSON.stringify(config);
33
+
34
+ // Keep a ref to track whether we started, so cleanup only stops if we did
35
+ const trackingRef = useRef(false);
36
+
37
+ useEffect(() => {
38
+ const parsed = JSON.parse(configJson) as LocationConfig;
39
+ NitroLocationModule.configure(parsed);
40
+ NitroLocationModule.onLocation(setLocation);
41
+ NitroLocationModule.onMotionChange(setIsMoving);
42
+ return () => {
43
+ if (trackingRef.current) {
44
+ NitroLocationModule.stopTracking();
45
+ trackingRef.current = false;
46
+ }
47
+ };
48
+ }, [configJson]);
49
+
50
+ return {
51
+ location,
52
+ isMoving,
53
+ isTracking,
54
+ startTracking: useCallback(() => {
55
+ NitroLocationModule.startTracking();
56
+ trackingRef.current = true;
57
+ setIsTracking(true);
58
+ }, []),
59
+ stopTracking: useCallback(() => {
60
+ NitroLocationModule.stopTracking();
61
+ trackingRef.current = false;
62
+ setIsTracking(false);
63
+ }, []),
64
+ };
65
+ }
66
+
67
+ export function useRideConnection(config: ConnectionConfig) {
68
+ const [connectionState, setConnectionState] = useState<
69
+ 'connected' | 'disconnected' | 'reconnecting'
70
+ >('disconnected');
71
+ const [lastMessage, setLastMessage] = useState<string | null>(null);
72
+
73
+ useEffect(() => {
74
+ NitroLocationModule.configureConnection(config);
75
+ NitroLocationModule.onConnectionStateChange(setConnectionState);
76
+ NitroLocationModule.onMessage(setLastMessage);
77
+ return () => {
78
+ NitroLocationModule.disconnectWebSocket();
79
+ };
80
+ }, [config]);
81
+
82
+ return {
83
+ connectionState,
84
+ lastMessage,
85
+ connect: useCallback(() => NitroLocationModule.connectWebSocket(), []),
86
+ disconnect: useCallback(
87
+ () => NitroLocationModule.disconnectWebSocket(),
88
+ []
89
+ ),
90
+ send: useCallback((m: string) => NitroLocationModule.sendMessage(m), []),
91
+ };
92
+ }