From 8f06ec0191d86fb751f46cfcdfba1dea0943e7f1 Mon Sep 17 00:00:00 2001 From: pinpong Date: Sun, 9 Nov 2025 19:53:39 +0700 Subject: [PATCH 01/40] chore: add dev tag script --- release.config.cjs | 9 +-------- scripts/create-dev-tag.sh | 8 ++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) create mode 100755 scripts/create-dev-tag.sh diff --git a/release.config.cjs b/release.config.cjs index cfeeab1..7b5dc9c 100644 --- a/release.config.cjs +++ b/release.config.cjs @@ -26,14 +26,7 @@ const execPlugin = isDev : [ '@semantic-release/exec', { - successCmd: ` - VERSION=\${nextRelease.version} - IFS='.' read -r major minor patch <<<"$VERSION" - NEXT_MINOR=$((minor + 1)) - DEV_TAG="v\${major}.\${NEXT_MINOR}.0-dev.0" - git tag "$DEV_TAG" - git push origin "$DEV_TAG" - `, + successCmd: './scripts/create-dev-tag.sh ${nextRelease.version}', }, ]; diff --git a/scripts/create-dev-tag.sh b/scripts/create-dev-tag.sh new file mode 100755 index 0000000..638f568 --- /dev/null +++ b/scripts/create-dev-tag.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +VERSION="$1" +IFS="." read -r major minor patch <<< "$VERSION" +NEXT_MINOR=$((minor + 1)) +DEV_TAG="v${major}.${NEXT_MINOR}.0-dev.0" +echo "[semantic-release] tagging: $DEV_TAG" +git tag "$DEV_TAG" +git push origin "$DEV_TAG" From b216ca4d9f841584511b8b1b4524d39cb74248bd Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 10 Nov 2025 15:41:00 +0700 Subject: [PATCH 02/40] chore: updated dependencies --- example/ios/Podfile.lock | 8 +- example/package.json | 6 +- package.json | 6 +- yarn.lock | 205 +++++++++++++++++++++++---------------- 4 files changed, 133 insertions(+), 92 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index d7e88d9..3fd695b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,6 +1,6 @@ PODS: - boost (1.84.0) - - Clusterer (5.0.1): + - Clusterer (5.0.2): - boost - DoubleConversion - fast_float @@ -46,7 +46,7 @@ PODS: - hermes-engine (0.82.1): - hermes-engine/Pre-built (= 0.82.1) - hermes-engine/Pre-built (0.82.1) - - NitroModules (0.30.2): + - NitroModules (0.31.5): - boost - DoubleConversion - fast_float @@ -3042,7 +3042,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 - Clusterer: 387b4557d9e5cd101b534d53e8302ee404755271 + Clusterer: 6b8e946e6d4593644d04acd9c1fca686e8d4f5cb CocoaLumberjack: 5644158777912b7de7469fa881f8a3f259c2512a DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 @@ -3052,7 +3052,7 @@ SPEC CHECKSUMS: Google-Maps-iOS-Utils: bed22fa703c919259b3901449434d60d994fae20 GoogleMaps: a40d3b1f511f0fa2036e7b08c920c33279b1d5fd hermes-engine: 273e30e7fb618279934b0b95ffab60ecedb7acf5 - NitroModules: 730eae5cd9d112f05252bbf36bfabe4ffd16e931 + NitroModules: afc462ff4c87c9a405ac7e93cd133137c407a7f9 RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: f17e2ebc07876ca9ab8eb6e4b0a4e4647497ae3a RCTRequired: e2c574c1b45231f7efb0834936bd609d75072b63 diff --git a/example/package.json b/example/package.json index 933e994..f68eb7f 100644 --- a/example/package.json +++ b/example/package.json @@ -13,14 +13,14 @@ "dependencies": { "@react-navigation/native": "7.1.19", "@react-navigation/native-stack": "7.6.2", - "@react-navigation/stack": "7.6.2", + "@react-navigation/stack": "7.6.3", "react": "19.1.1", "react-hook-form": "7.66.0", "react-native": "0.82.1", - "react-native-clusterer": "5.0.1", + "react-native-clusterer": "5.0.2", "react-native-gesture-handler": "2.29.1", "react-native-google-maps-plus": "workspace:*", - "react-native-nitro-modules": "0.30.2", + "react-native-nitro-modules": "0.31.5", "react-native-reanimated": "4.1.3", "react-native-safe-area-context": "5.6.2", "react-native-screens": "4.18.0", diff --git a/package.json b/package.json index aa715bd..b2e722f 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "@semantic-release/npm": "13.1.1", "@types/jest": "30.0.0", "@types/react": "19.1.1", - "clang-format-node": "2.0.3", + "clang-format-node": "2.0.4", "conventional-changelog-conventionalcommits": "9.1.0", "del-cli": "7.0.0", "eslint": "9.39.1", @@ -102,14 +102,14 @@ "eslint-plugin-ft-flow": "3.0.11", "eslint-plugin-prettier": "5.5.4", "jest": "30.2.0", - "lefthook": "2.0.2", + "lefthook": "2.0.3", "nitrogen": "0.31.5", "prettier": "3.6.2", "react": "19.1.1", "react-native": "0.82.1", "react-native-builder-bob": "0.40.14", "react-native-nitro-modules": "0.31.5", - "semantic-release": "25.0.1", + "semantic-release": "25.0.2", "typescript": "5.9.3" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index 3cee9ef..d10adca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3484,9 +3484,9 @@ __metadata: languageName: node linkType: hard -"@react-navigation/stack@npm:7.6.2": - version: 7.6.2 - resolution: "@react-navigation/stack@npm:7.6.2" +"@react-navigation/stack@npm:7.6.3": + version: 7.6.3 + resolution: "@react-navigation/stack@npm:7.6.3" dependencies: "@react-navigation/elements": ^2.8.1 color: ^4.2.3 @@ -3497,7 +3497,7 @@ __metadata: react-native-gesture-handler: ">= 2.0.0" react-native-safe-area-context: ">= 4.0.0" react-native-screens: ">= 4.0.0" - checksum: 4b9fa85d3c6f34aa645af1e497ff9005142998fbad2a0891ed4bb8f266148581235ac172081d38729ab2b7ba3138706d7df165ae0f6da2c2be0a6be83ef2e2ec + checksum: 6e74a8bda940abcdeb303b259acaa601749fbfdc35245f5f31f82c06680178710e58db62ca895fd3b9f2cfed39e652e01b01db32e529fbefd60adc576bd9d197 languageName: node linkType: hard @@ -3964,7 +3964,7 @@ __metadata: languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.3": +"@types/normalize-package-data@npm:^2.4.3, @types/normalize-package-data@npm:^2.4.4": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" checksum: 65dff72b543997b7be8b0265eca7ace0e34b75c3e5fee31de11179d08fa7124a7a5587265d53d0409532ecb7f7fba662c2012807963e1f9b059653ec2c83ee05 @@ -5311,13 +5311,13 @@ __metadata: languageName: node linkType: hard -"clang-format-node@npm:2.0.3": - version: 2.0.3 - resolution: "clang-format-node@npm:2.0.3" +"clang-format-node@npm:2.0.4": + version: 2.0.4 + resolution: "clang-format-node@npm:2.0.4" bin: clang-format: build/cli.js clang-format-node: build/cli.js - checksum: 15d708e6887cc9a4045c5403826a925c8f2c4ff6700f447cc31fce49a979b299388d3ea7790428d33130fc8d0c550a429f92a927dc5852b20fdcfbee3cc03e7c + checksum: b660c807579d6cc867afbeec9cec118ea2fe43233f2b5fa0c335b175125795b184fd0935185b6c08d6057a3994843c89eb5c544edc8615a710a6175c3514e43b languageName: node linkType: hard @@ -7011,7 +7011,7 @@ __metadata: languageName: node linkType: hard -"find-up-simple@npm:^1.0.0": +"find-up-simple@npm:^1.0.0, find-up-simple@npm:^1.0.1": version: 1.0.1 resolution: "find-up-simple@npm:1.0.1" checksum: 6e374bffda9f8425314eab47ef79752b6e77dcc95c0ad17d257aef48c32fe07bbc41bcafbd22941c25bb94fffaaaa8e178d928867d844c58100c7fe19ec82f72 @@ -9388,90 +9388,90 @@ __metadata: languageName: node linkType: hard -"lefthook-darwin-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-darwin-arm64@npm:2.0.2" +"lefthook-darwin-arm64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-darwin-arm64@npm:2.0.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lefthook-darwin-x64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-darwin-x64@npm:2.0.2" +"lefthook-darwin-x64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-darwin-x64@npm:2.0.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lefthook-freebsd-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-freebsd-arm64@npm:2.0.2" +"lefthook-freebsd-arm64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-freebsd-arm64@npm:2.0.3" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"lefthook-freebsd-x64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-freebsd-x64@npm:2.0.2" +"lefthook-freebsd-x64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-freebsd-x64@npm:2.0.3" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lefthook-linux-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-linux-arm64@npm:2.0.2" +"lefthook-linux-arm64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-linux-arm64@npm:2.0.3" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"lefthook-linux-x64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-linux-x64@npm:2.0.2" +"lefthook-linux-x64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-linux-x64@npm:2.0.3" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"lefthook-openbsd-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-openbsd-arm64@npm:2.0.2" +"lefthook-openbsd-arm64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-openbsd-arm64@npm:2.0.3" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"lefthook-openbsd-x64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-openbsd-x64@npm:2.0.2" +"lefthook-openbsd-x64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-openbsd-x64@npm:2.0.3" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"lefthook-windows-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-windows-arm64@npm:2.0.2" +"lefthook-windows-arm64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-windows-arm64@npm:2.0.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lefthook-windows-x64@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook-windows-x64@npm:2.0.2" +"lefthook-windows-x64@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook-windows-x64@npm:2.0.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"lefthook@npm:2.0.2": - version: 2.0.2 - resolution: "lefthook@npm:2.0.2" - dependencies: - lefthook-darwin-arm64: 2.0.2 - lefthook-darwin-x64: 2.0.2 - lefthook-freebsd-arm64: 2.0.2 - lefthook-freebsd-x64: 2.0.2 - lefthook-linux-arm64: 2.0.2 - lefthook-linux-x64: 2.0.2 - lefthook-openbsd-arm64: 2.0.2 - lefthook-openbsd-x64: 2.0.2 - lefthook-windows-arm64: 2.0.2 - lefthook-windows-x64: 2.0.2 +"lefthook@npm:2.0.3": + version: 2.0.3 + resolution: "lefthook@npm:2.0.3" + dependencies: + lefthook-darwin-arm64: 2.0.3 + lefthook-darwin-x64: 2.0.3 + lefthook-freebsd-arm64: 2.0.3 + lefthook-freebsd-x64: 2.0.3 + lefthook-linux-arm64: 2.0.3 + lefthook-linux-x64: 2.0.3 + lefthook-openbsd-arm64: 2.0.3 + lefthook-openbsd-x64: 2.0.3 + lefthook-windows-arm64: 2.0.3 + lefthook-windows-x64: 2.0.3 dependenciesMeta: lefthook-darwin-arm64: optional: true @@ -9495,7 +9495,7 @@ __metadata: optional: true bin: lefthook: bin/index.js - checksum: 42244148e5d9ff916c4f2baa3897861703f19b1610935193e6231d08abfef9d44344945ba174d1ab9e33dd37d51d000abea2734d5d13b626ac2e79673644dedd + checksum: 647e13826c3eed30453734eb8d932f196c7f1334559bd8ef01dce4a07b0ce64e356eddfbb552b827d6dc25e4be15fb564ee6b2f7483de70890b8fb131468a677 languageName: node linkType: hard @@ -10655,6 +10655,17 @@ __metadata: languageName: node linkType: hard +"normalize-package-data@npm:^8.0.0": + version: 8.0.0 + resolution: "normalize-package-data@npm:8.0.0" + dependencies: + hosted-git-info: ^9.0.0 + semver: ^7.3.5 + validate-npm-package-license: ^3.0.4 + checksum: 226ef14e168caeeeb0ae21f70f0296d8c29cc55a484e1561d1f1771156f049f5896cd50f38b9a8b4bbe30f2fea32fb9e5491449249137faecb3fd169b3db8118 + languageName: node + linkType: hard + "normalize-path@npm:^3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" @@ -11319,7 +11330,7 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^8.0.0": +"parse-json@npm:^8.0.0, parse-json@npm:^8.3.0": version: 8.3.0 resolution: "parse-json@npm:8.3.0" dependencies: @@ -11884,16 +11895,16 @@ __metadata: languageName: node linkType: hard -"react-native-clusterer@npm:5.0.1": - version: 5.0.1 - resolution: "react-native-clusterer@npm:5.0.1" +"react-native-clusterer@npm:5.0.2": + version: 5.0.2 + resolution: "react-native-clusterer@npm:5.0.2" dependencies: "@mapbox/geo-viewport": ^0.5.0 peerDependencies: react: "*" react-native: "*" - react-native-nitro-modules: ^0.30.2 - checksum: b8701b1d8d7fa5ec66cf9e4a81e0a66977c0b49f6221ed0718ed6e30a071988913350d2490c5d624cdb02e48ba6eee61c85592d9d1da8dc57b9a2eb13da45430 + react-native-nitro-modules: ^0.31.5 + checksum: 6f8efbc4c9e7e2e4598a7b2d3c138729f286c1cde3d0967f48837e8c3e194715f5e091423e03b26f8c1e4a1ebbe4cb183813122b8ad1ecf12f132035ce9336df languageName: node linkType: hard @@ -11926,17 +11937,17 @@ __metadata: "@react-native/typescript-config": 0.82.1 "@react-navigation/native": 7.1.19 "@react-navigation/native-stack": 7.6.2 - "@react-navigation/stack": 7.6.2 + "@react-navigation/stack": 7.6.3 "@types/react": 19.1.1 react: 19.1.1 react-hook-form: 7.66.0 react-native: 0.82.1 react-native-builder-bob: 0.40.14 - react-native-clusterer: 5.0.1 + react-native-clusterer: 5.0.2 react-native-gesture-handler: 2.29.1 react-native-google-maps-plus: "workspace:*" react-native-monorepo-config: 0.3.0 - react-native-nitro-modules: 0.30.2 + react-native-nitro-modules: 0.31.5 react-native-reanimated: 4.1.3 react-native-safe-area-context: 5.6.2 react-native-screens: 4.18.0 @@ -11964,7 +11975,7 @@ __metadata: "@semantic-release/npm": 13.1.1 "@types/jest": 30.0.0 "@types/react": 19.1.1 - clang-format-node: 2.0.3 + clang-format-node: 2.0.4 conventional-changelog-conventionalcommits: 9.1.0 del-cli: 7.0.0 eslint: 9.39.1 @@ -11972,14 +11983,14 @@ __metadata: eslint-plugin-ft-flow: 3.0.11 eslint-plugin-prettier: 5.5.4 jest: 30.2.0 - lefthook: 2.0.2 + lefthook: 2.0.3 nitrogen: 0.31.5 prettier: 3.6.2 react: 19.1.1 react-native: 0.82.1 react-native-builder-bob: 0.40.14 react-native-nitro-modules: 0.31.5 - semantic-release: 25.0.1 + semantic-release: 25.0.2 typescript: 5.9.3 peerDependencies: expo: "*" @@ -12022,16 +12033,6 @@ __metadata: languageName: node linkType: hard -"react-native-nitro-modules@npm:0.30.2": - version: 0.30.2 - resolution: "react-native-nitro-modules@npm:0.30.2" - peerDependencies: - react: "*" - react-native: "*" - checksum: da06b99c7f2def27c43da39a9eef2535b36bef48ef4cd45f49c0180fa735a0407a6f2feb6a30d39c4645a849230827e391ebc23e74236bde98a6f6176c6b291a - languageName: node - linkType: hard - "react-native-nitro-modules@npm:0.31.5, react-native-nitro-modules@npm:^0.31.5": version: 0.31.5 resolution: "react-native-nitro-modules@npm:0.31.5" @@ -12186,6 +12187,30 @@ __metadata: languageName: node linkType: hard +"read-package-up@npm:^12.0.0": + version: 12.0.0 + resolution: "read-package-up@npm:12.0.0" + dependencies: + find-up-simple: ^1.0.1 + read-pkg: ^10.0.0 + type-fest: ^5.2.0 + checksum: b8fc1645228e2b136e75afd4e8d87eec9bff18382668a59f1fc409ee0596e65ba452ff65c5717a311ed9a8796debada9a4a547820593208a0ac659f6cfef86e7 + languageName: node + linkType: hard + +"read-pkg@npm:^10.0.0": + version: 10.0.0 + resolution: "read-pkg@npm:10.0.0" + dependencies: + "@types/normalize-package-data": ^2.4.4 + normalize-package-data: ^8.0.0 + parse-json: ^8.3.0 + type-fest: ^5.2.0 + unicorn-magic: ^0.3.0 + checksum: 8ad56dc93d36cae8827e4917cfbf299b862e23389d7befd889d05a9fee771514631751991782d016ea96a3f10f87b4aee9972cb284e088b0011edff47e08aef5 + languageName: node + linkType: hard + "read-pkg@npm:^9.0.0": version: 9.0.1 resolution: "read-pkg@npm:9.0.1" @@ -12537,9 +12562,9 @@ __metadata: languageName: node linkType: hard -"semantic-release@npm:25.0.1": - version: 25.0.1 - resolution: "semantic-release@npm:25.0.1" +"semantic-release@npm:25.0.2": + version: 25.0.2 + resolution: "semantic-release@npm:25.0.2" dependencies: "@semantic-release/commit-analyzer": ^13.0.1 "@semantic-release/error": ^4.0.0 @@ -12564,7 +12589,7 @@ __metadata: micromatch: ^4.0.2 p-each-series: ^3.0.0 p-reduce: ^3.0.0 - read-package-up: ^11.0.0 + read-package-up: ^12.0.0 resolve-from: ^5.0.0 semver: ^7.3.2 semver-diff: ^5.0.0 @@ -12572,7 +12597,7 @@ __metadata: yargs: ^18.0.0 bin: semantic-release: bin/semantic-release.js - checksum: 0f1df43c11dc36e9384ae98ad097ff40cf9d6cd640dd6519ee2835ca6bfa04e27e8b96ffcbc7005713b4f7a3001c58fd9fc2f3fef05c6090f57373c39cb5d018 + checksum: af92eed5fbef9fbbe749c3c0a47a855872db4ae5fb1824dcc0ecabb289cf6e011b8b07987d865299075cc60541bea5662b29aba381d91c90e148095f42f4fdd9 languageName: node linkType: hard @@ -13418,6 +13443,13 @@ __metadata: languageName: node linkType: hard +"tagged-tag@npm:^1.0.0": + version: 1.0.0 + resolution: "tagged-tag@npm:1.0.0" + checksum: e37653df3e495daa7ea7790cb161b810b00075bba2e4d6c93fb06a709e747e3ae9da11a120d0489833203926511b39e038a2affbd9d279cfb7a2f3fcccd30b5d + languageName: node + linkType: hard + "tar@npm:^7.4.3, tar@npm:^7.5.1": version: 7.5.2 resolution: "tar@npm:7.5.2" @@ -13696,6 +13728,15 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^5.2.0": + version: 5.2.0 + resolution: "type-fest@npm:5.2.0" + dependencies: + tagged-tag: ^1.0.0 + checksum: 238eb0f14bd840db77c834ce5ed264d28aa79d1ed1e7b8606985f17cc01c9c1b6f266f780a132512764f81816e51b7a72a6e537188702fb985e1971ad2dcc920 + languageName: node + linkType: hard + "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" From 0cee1b2144dd840a5caa47f095aa4460a9564ff4 Mon Sep 17 00:00:00 2001 From: iaudouard Date: Sun, 9 Nov 2025 17:18:12 +0000 Subject: [PATCH 03/40] fix(ios): added nitromodules import to module & view impl files --- ios/GoogleMapViewImpl.swift | 1 + ios/RNGoogleMapsPlusModule.swift | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ios/GoogleMapViewImpl.swift b/ios/GoogleMapViewImpl.swift index a87be91..b553f12 100644 --- a/ios/GoogleMapViewImpl.swift +++ b/ios/GoogleMapViewImpl.swift @@ -2,6 +2,7 @@ import CoreLocation import GoogleMaps import GoogleMapsUtils import UIKit +import NitroModules final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate, GMSIndoorDisplayDelegate { diff --git a/ios/RNGoogleMapsPlusModule.swift b/ios/RNGoogleMapsPlusModule.swift index 82c7336..18de6b6 100644 --- a/ios/RNGoogleMapsPlusModule.swift +++ b/ios/RNGoogleMapsPlusModule.swift @@ -1,3 +1,5 @@ +import NitroModules + final class RNGoogleMapsPlusModule: HybridRNGoogleMapsPlusModuleSpec { private let permissionHandler: PermissionHandler private let locationHandler: LocationHandler From b573d7e0297c2bf9e1fb17e26cafd794977a62ed Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 11 Nov 2025 11:59:06 +0700 Subject: [PATCH 04/40] chore: updated README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 0dcf8f9..64e04a3 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ [![Dev Release](https://img.shields.io/npm/v/react-native-google-maps-plus/dev.svg?label=dev%20release&color=orange)](https://www.npmjs.com/package/react-native-google-maps-plus) [![Build](https://github.com/pinpong/react-native-google-maps-plus/actions/workflows/release.yml/badge.svg)](https://github.com/pinpong/react-native-google-maps-plus/actions/workflows/release.yml) ![React Native](https://img.shields.io/badge/react--native-%3E%3D0.81.0-61dafb.svg?logo=react) -![Platform: Android](https://img.shields.io/badge/android-supported-brightgreen.svg?logo=android&logoColor=white) -![Platform: iOS](https://img.shields.io/badge/ios-supported-lightgrey.svg?logo=apple&logoColor=black) React Native wrapper for Android & iOS Google Maps SDK. From e7af5dccec97a7fbc2cd6b2e3e24c28d4923aa16 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 11 Nov 2025 12:53:59 +0700 Subject: [PATCH 05/40] chore(android): remove packagingOptions --- android/build.gradle | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 7e3f97c..e8e7152 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -70,27 +70,6 @@ android { } } - packagingOptions { - excludes = [ - "META-INF", - "META-INF/**", - "**/libc++_shared.so", - "**/libfbjni.so", - "**/libjsi.so", - "**/libfolly_json.so", - "**/libfolly_runtime.so", - "**/libglog.so", - "**/libhermes.so", - "**/libhermes-executor-debug.so", - "**/libhermes_executor.so", - "**/libreactnative.so", - "**/libreactnativejni.so", - "**/libturbomodulejsijni.so", - "**/libreact_nativemodule_core.so", - "**/libjscexecutor.so" - ] - } - buildFeatures { buildConfig true prefab true From 3662eb7627683e62ceb0cc258b4597c2bb52709f Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 11 Nov 2025 12:54:57 +0700 Subject: [PATCH 06/40] chore(example): update dependencies --- example/ios/Podfile.lock | 12 ++++++------ example/package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 3fd695b..adfc8e8 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2537,7 +2537,7 @@ PODS: - SocketRocket - SVGKit (= 3.0.0) - Yoga - - RNReanimated (4.1.3): + - RNReanimated (4.1.5): - boost - DoubleConversion - fast_float @@ -2564,11 +2564,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated (= 4.1.3) + - RNReanimated/reanimated (= 4.1.5) - RNWorklets - SocketRocket - Yoga - - RNReanimated/reanimated (4.1.3): + - RNReanimated/reanimated (4.1.5): - boost - DoubleConversion - fast_float @@ -2595,11 +2595,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated/apple (= 4.1.3) + - RNReanimated/reanimated/apple (= 4.1.5) - RNWorklets - SocketRocket - Yoga - - RNReanimated/reanimated/apple (4.1.3): + - RNReanimated/reanimated/apple (4.1.5): - boost - DoubleConversion - fast_float @@ -3121,7 +3121,7 @@ SPEC CHECKSUMS: ReactCommon: 801eff8cb9c940c04d3a89ce399c343ee3eff654 RNGestureHandler: 67501c6d447027581aa1d8e5a7a3ea5a7f0a89ff RNGoogleMapsPlus: d94844f2d397099f2153d5f9a29e96f70f547bde - RNReanimated: 8f0185df21f0dea34ee8c9611ba88c17a290ed9a + RNReanimated: 05c5a85c3ee54ac68d60c8a9b42dbc441e3326ca RNScreens: 98771ad898d1c0528fc8139606bbacf5a2e9d237 RNWorklets: ab618bf7d1c7fd2cb793b9f0f39c3e29274b3ebf SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 diff --git a/example/package.json b/example/package.json index f68eb7f..018ae17 100644 --- a/example/package.json +++ b/example/package.json @@ -21,7 +21,7 @@ "react-native-gesture-handler": "2.29.1", "react-native-google-maps-plus": "workspace:*", "react-native-nitro-modules": "0.31.5", - "react-native-reanimated": "4.1.3", + "react-native-reanimated": "4.1.5", "react-native-safe-area-context": "5.6.2", "react-native-screens": "4.18.0", "react-native-worklets": "0.6.1", diff --git a/yarn.lock b/yarn.lock index d10adca..4fa669f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11948,7 +11948,7 @@ __metadata: react-native-google-maps-plus: "workspace:*" react-native-monorepo-config: 0.3.0 react-native-nitro-modules: 0.31.5 - react-native-reanimated: 4.1.3 + react-native-reanimated: 4.1.5 react-native-safe-area-context: 5.6.2 react-native-screens: 4.18.0 react-native-worklets: 0.6.1 @@ -12043,9 +12043,9 @@ __metadata: languageName: node linkType: hard -"react-native-reanimated@npm:4.1.3": - version: 4.1.3 - resolution: "react-native-reanimated@npm:4.1.3" +"react-native-reanimated@npm:4.1.5": + version: 4.1.5 + resolution: "react-native-reanimated@npm:4.1.5" dependencies: react-native-is-edge-to-edge: ^1.2.1 semver: 7.7.2 @@ -12054,7 +12054,7 @@ __metadata: react: "*" react-native: "*" react-native-worklets: ">=0.5.0" - checksum: 5f3b7298dd721b5da7f8bab64c557624d08b8715502f4ba2ff9118f31d852e3d9734ffbfaacd1302468ba68d4790689eead39605645a80f737802c8de0008064 + checksum: 5439c2f5c27af9590719a4c412f3cb8415c626e346885821898ae50c7e3cdf00bc21058a1bc29cafa1366231f414c6979fae852acf0713ba7bdc7e5ba351827c languageName: node linkType: hard From ddf33036386f00b7ecfd1eb588fefa868e7ecb75 Mon Sep 17 00:00:00 2001 From: pinpong Date: Wed, 12 Nov 2025 10:28:42 +0700 Subject: [PATCH 07/40] feat(ios): add location activity type support --- example/src/components/MapWrapper.tsx | 6 ++- .../components/maptConfigDialog/validator.ts | 2 + example/src/screens/LocationScreen.tsx | 51 ++++++++++++++++-- ios/GoogleMapViewImpl.swift | 12 +++-- ios/LocationHandler.swift | 52 ++++++++++++------- ...RNIOSLocationActivityType+Extensions.swift | 18 +++++++ src/types.ts | 9 ++++ 7 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 ios/extensions/RNIOSLocationActivityType+Extensions.swift diff --git a/example/src/components/MapWrapper.tsx b/example/src/components/MapWrapper.tsx index b0fa0d3..20895e5 100644 --- a/example/src/components/MapWrapper.tsx +++ b/example/src/components/MapWrapper.tsx @@ -13,13 +13,14 @@ import type { RNMapUiSettings, RNMapZoomConfig, RNRegion, + RNIndoorBuilding, + RNIndoorLevel, } from 'react-native-google-maps-plus'; import { GoogleMapsView, RNAndroidLocationPriority, - type RNIndoorBuilding, - type RNIndoorLevel, RNIOSLocationAccuracy, + RNIOSLocationActivityType, RNLocationErrorCode, RNMapErrorCode, } from 'react-native-google-maps-plus'; @@ -103,6 +104,7 @@ export default function MapWrapper(props: Props) { ios: { desiredAccuracy: RNIOSLocationAccuracy.ACCURACY_BEST, distanceFilterMeters: 10, + activityType: RNIOSLocationActivityType.NAVIGATION, }, }), [] diff --git a/example/src/components/maptConfigDialog/validator.ts b/example/src/components/maptConfigDialog/validator.ts index e13e473..2998da4 100644 --- a/example/src/components/maptConfigDialog/validator.ts +++ b/example/src/components/maptConfigDialog/validator.ts @@ -15,6 +15,7 @@ import { RNAndroidLocationPermissionResult, RNAndroidLocationPriority, RNIOSLocationAccuracy, + RNIOSLocationActivityType, RNIOSPermissionResult, RNLocationErrorCode, RNMapErrorCode, @@ -272,6 +273,7 @@ const RNAndroidLocationConfigValidator = object({ export const RNIOSLocationConfigValidator = object({ desiredAccuracy: optional(enums(enumValues(RNIOSLocationAccuracy))), distanceFilterMeters: optional(number()), + activityType: optional(enums(enumValues(RNIOSLocationActivityType))), }); export const RNLocationConfigValidator = object({ diff --git a/example/src/screens/LocationScreen.tsx b/example/src/screens/LocationScreen.tsx index 7f5242e..e51c6a5 100644 --- a/example/src/screens/LocationScreen.tsx +++ b/example/src/screens/LocationScreen.tsx @@ -1,14 +1,55 @@ -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; import MapWrapper from '../components/MapWrapper'; import ControlPanel from '../components/ControlPanel'; -import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; +import { + type GoogleMapsViewRef, + RNAndroidLocationPriority, + RNIOSLocationAccuracy, + RNIOSLocationActivityType, + type RNLocationConfig, +} from 'react-native-google-maps-plus'; +import { RNLocationConfigValidator } from '../components/maptConfigDialog/validator'; +import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; +import { useHeaderButton } from '../hooks/useHeaderButton'; +import { useNavigation } from '@react-navigation/native'; export default function LocationScreen() { const mapRef = useRef(null); + const navigation = useNavigation(); + const [locationConfig, setLocationConfig] = useState({ + android: { + priority: RNAndroidLocationPriority.PRIORITY_HIGH_ACCURACY, + interval: 5000, + minUpdateInterval: 5000, + }, + ios: { + desiredAccuracy: RNIOSLocationAccuracy.ACCURACY_BEST, + distanceFilterMeters: 10, + activityType: RNIOSLocationActivityType.NAVIGATION, + }, + }); + const [dialogVisible, setDialogVisible] = useState(true); + + useHeaderButton(navigation, 'Edit', () => setDialogVisible(true)); return ( - - - + <> + + + + + + visible={dialogVisible} + title="Edit marker" + initialData={locationConfig} + validator={RNLocationConfigValidator} + onClose={() => setDialogVisible(false)} + onSave={(c) => setLocationConfig(c)} + /> + ); } diff --git a/ios/GoogleMapViewImpl.swift b/ios/GoogleMapViewImpl.swift index b553f12..2358f81 100644 --- a/ios/GoogleMapViewImpl.swift +++ b/ios/GoogleMapViewImpl.swift @@ -1,8 +1,8 @@ import CoreLocation import GoogleMaps import GoogleMapsUtils -import UIKit import NitroModules +import UIKit final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate, GMSIndoorDisplayDelegate { @@ -273,10 +273,12 @@ GMSIndoorDisplayDelegate { @MainActor var locationConfig: RNLocationConfig? { didSet { - locationHandler.desiredAccuracy = - locationConfig?.ios?.desiredAccuracy?.toCLLocationAccuracy - locationHandler.distanceFilterMeters = - locationConfig?.ios?.distanceFilterMeters + locationHandler.updateConfig( + desiredAccuracy: locationConfig?.ios?.desiredAccuracy? + .toCLLocationAccuracy, + distanceFilterMeters: locationConfig?.ios?.distanceFilterMeters, + activityType: locationConfig?.ios?.activityType?.toCLActivityType, + ) } } diff --git a/ios/LocationHandler.swift b/ios/LocationHandler.swift index 25ccce1..50468a1 100644 --- a/ios/LocationHandler.swift +++ b/ios/LocationHandler.swift @@ -6,22 +6,19 @@ private let kCLLocationAccuracyDefault: CLLocationAccuracy = kCLLocationAccuracyBest private let kCLDistanceFilterNoneDefault: CLLocationDistance = kCLDistanceFilterNone +private let kCLActivityTypeDefault: CLActivityType = .other final class LocationHandler: NSObject, CLLocationManagerDelegate { private let manager = CLLocationManager() - var desiredAccuracy: CLLocationAccuracy? = kCLLocationAccuracyDefault { - didSet { - manager.desiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyBest - } - } + private var isActive = false - var distanceFilterMeters: CLLocationDistance? = kCLDistanceFilterNoneDefault { - didSet { - manager.distanceFilter = distanceFilterMeters ?? kCLDistanceFilterNone - } - } + private var currentDesiredAccuracy: CLLocationAccuracy = + kCLLocationAccuracyDefault + private var currentDistanceFilter: CLLocationDistance = + kCLDistanceFilterNoneDefault + private var currentActivityType: CLActivityType = kCLActivityTypeDefault var onUpdate: ((CLLocation) -> Void)? var onError: ((_ error: RNLocationErrorCode) -> Void)? @@ -30,7 +27,21 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate { super.init() manager.delegate = self manager.pausesLocationUpdatesAutomatically = true - manager.activityType = .other + } + + func updateConfig( + desiredAccuracy: CLLocationAccuracy?, + distanceFilterMeters: CLLocationDistance?, + activityType: CLActivityType? + ) { + currentDesiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyDefault + manager.desiredAccuracy = currentDesiredAccuracy + + currentDistanceFilter = distanceFilterMeters ?? kCLDistanceFilterNoneDefault + manager.distanceFilter = currentDistanceFilter + + currentActivityType = activityType ?? kCLActivityTypeDefault + manager.activityType = currentActivityType } func showLocationDialog() { @@ -71,11 +82,19 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate { } func start() { - stop() - startUpdates() + guard !isActive else { return } + isActive = true + + manager.location.map { + onUpdate?($0) + } + + manager.startUpdatingLocation() } func stop() { + guard isActive else { return } + isActive = false manager.stopUpdatingLocation() } @@ -104,13 +123,6 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate { } } - private func startUpdates() { - manager.desiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyDefault - manager.distanceFilter = - distanceFilterMeters ?? kCLDistanceFilterNoneDefault - manager.startUpdatingLocation() - } - func locationManager( _ manager: CLLocationManager, didFailWithError error: Error diff --git a/ios/extensions/RNIOSLocationActivityType+Extensions.swift b/ios/extensions/RNIOSLocationActivityType+Extensions.swift new file mode 100644 index 0000000..7802377 --- /dev/null +++ b/ios/extensions/RNIOSLocationActivityType+Extensions.swift @@ -0,0 +1,18 @@ +import CoreLocation + +extension RNIOSLocationActivityType { + var toCLActivityType: CLActivityType { + switch self { + case .other: + return .other + case .navigation: + return .otherNavigation + case .automotive: + return .automotiveNavigation + case .fitness: + return .fitness + case .airborne: + return .airborne + } + } +} diff --git a/src/types.ts b/src/types.ts index bc9a857..3f8cbc0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -297,6 +297,7 @@ export enum RNAndroidLocationPriority { export type RNIOSLocationConfig = { desiredAccuracy?: RNIOSLocationAccuracy; distanceFilterMeters?: number; + activityType?: RNIOSLocationActivityType; }; export enum RNIOSLocationAccuracy { @@ -306,6 +307,14 @@ export enum RNIOSLocationAccuracy { ACCURACY_KILOMETER = 3, } +export enum RNIOSLocationActivityType { + OTHER = 0, + NAVIGATION = 1, + AUTOMOTIVE = 2, + FITNESS = 3, + AIRBORNE = 4, +} + export type RNLocationPermissionResult = { android?: RNAndroidLocationPermissionResult; ios?: RNIOSPermissionResult; From b6d00e3866317ebf74e62569b91e701f44b6799f Mon Sep 17 00:00:00 2001 From: pinpong Date: Wed, 12 Nov 2025 17:55:56 +0700 Subject: [PATCH 08/40] chore(example): memoize callbacks --- example/src/components/MapWrapper.tsx | 132 +------------- example/src/hooks/useMapCallbacks.ts | 222 +++++++++++++++++++++++ example/src/hooks/useNitroCallback.ts | 15 ++ example/src/screens/ClsuteringScreen.tsx | 10 +- example/src/screens/MarkersScreen.tsx | 8 +- 5 files changed, 256 insertions(+), 131 deletions(-) create mode 100644 example/src/hooks/useMapCallbacks.ts create mode 100644 example/src/hooks/useNitroCallback.ts diff --git a/example/src/components/MapWrapper.tsx b/example/src/components/MapWrapper.tsx index 20895e5..be81ccf 100644 --- a/example/src/components/MapWrapper.tsx +++ b/example/src/components/MapWrapper.tsx @@ -1,33 +1,25 @@ -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import type { ViewProps } from 'react-native'; import { ActivityIndicator, StyleSheet, View } from 'react-native'; import type { GoogleMapsViewRef, - RNCamera, RNGoogleMapsPlusViewProps, RNInitialProps, - RNLatLng, - RNLocation, RNLocationConfig, RNMapPadding, RNMapUiSettings, RNMapZoomConfig, - RNRegion, - RNIndoorBuilding, - RNIndoorLevel, } from 'react-native-google-maps-plus'; import { GoogleMapsView, RNAndroidLocationPriority, RNIOSLocationAccuracy, RNIOSLocationActivityType, - RNLocationErrorCode, - RNMapErrorCode, } from 'react-native-google-maps-plus'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { callback } from 'react-native-nitro-modules'; import type { AppTheme } from '../theme'; import { useAppTheme } from '../hooks/useAppTheme'; +import { useMapCallbacks } from '../hooks/useMapCallbacks'; type Props = ViewProps & RNGoogleMapsPlusViewProps & { @@ -35,25 +27,13 @@ type Props = ViewProps & children?: React.ReactNode; }; -function wrapCallback void>( - propCallback: T | undefined, - fallback?: (...args: Parameters) => void -) { - return callback({ - f: ((...args: Parameters) => { - propCallback?.(...args); - fallback?.(...args); - }) as T, - }); -} - export default function MapWrapper(props: Props) { const { children, ...rest } = props; const theme = useAppTheme(); const styles = useMemo(() => getThemedStyles(theme), [theme]); const layout = useSafeAreaInsets(); - const [mapLoaded, setMapLoaded] = React.useState(false); + const [mapLoaded, setMapLoaded] = useState(false); const initialProps: RNInitialProps = useMemo( () => ({ camera: { @@ -110,11 +90,12 @@ export default function MapWrapper(props: Props) { [] ); + const mapCallbacks = useMapCallbacks(props, props.mapRef, setMapLoaded); + return ( (props.mapRef.current = ref))} initialProps={props.initialProps ?? initialProps} uiSettings={props.uiSettings ?? uiSettings} myLocationEnabled={props.myLocationEnabled ?? true} @@ -129,108 +110,7 @@ export default function MapWrapper(props: Props) { mapZoomConfig={props.mapZoomConfig ?? mapZoomConfig} mapPadding={props.mapPadding ?? mapPadding} locationConfig={props.locationConfig ?? locationConfig} - onMapError={wrapCallback(props.onMapError, (e: RNMapErrorCode) => - console.log('Map error:', e) - )} - onMapReady={wrapCallback(props.onMapReady, (ready: boolean) => - console.log('Map is ready:', ready) - )} - onMapLoaded={wrapCallback( - props.onMapLoaded, - (region: RNRegion, camera: RNCamera) => { - console.log('Map is loaded:', region, camera); - setMapLoaded(true); - } - )} - onMapPress={wrapCallback(props.onMapPress, (c: RNLatLng) => - console.log('Map press:', c) - )} - onMapLongPress={wrapCallback(props.onMapLongPress, (c: RNLatLng) => - console.log('Map long press:', c) - )} - onPoiPress={wrapCallback( - props.onPoiPress, - (placeId: string, name: string, coordinate: RNLatLng) => - console.log('Poi press:', placeId, name, coordinate) - )} - onMarkerPress={wrapCallback(props.onMarkerPress, (id: string) => - console.log('Marker press:', id) - )} - onPolylinePress={wrapCallback(props.onPolylinePress, (id: string) => - console.log('Polyline press:', id) - )} - onPolygonPress={wrapCallback(props.onPolygonPress, (id: string) => - console.log('Polygon press:', id) - )} - onCirclePress={wrapCallback(props.onCirclePress, (id: string) => - console.log('Circle press:', id) - )} - onMarkerDragStart={wrapCallback( - props.onMarkerDragStart, - (id: string, latLng: RNLatLng) => - console.log('Marker drag start:', id, latLng) - )} - onMarkerDrag={wrapCallback( - props.onMarkerDrag, - (id: string, latLng: RNLatLng) => - console.log('Marker drag:', id, latLng) - )} - onMarkerDragEnd={wrapCallback( - props.onMarkerDragEnd, - (id: string, latLng: RNLatLng) => - console.log('Marker drag end:', id, latLng) - )} - onIndoorBuildingFocused={wrapCallback( - props.onIndoorBuildingFocused, - (building: RNIndoorBuilding) => - console.log('Indoor building focused:', building) - )} - onIndoorLevelActivated={wrapCallback( - props.onIndoorLevelActivated, - (level: RNIndoorLevel) => - console.log('Indoor level activated:', level) - )} - onInfoWindowPress={wrapCallback(props.onInfoWindowPress, (id: string) => - console.log('InfoWindow press:', id) - )} - onInfoWindowClose={wrapCallback(props.onInfoWindowClose, (id: string) => - console.log('InfoWindow close:', id) - )} - onInfoWindowLongPress={wrapCallback( - props.onInfoWindowLongPress, - (id: string) => console.log('InfoWindow long press:', id) - )} - onMyLocationPress={wrapCallback( - props.onMyLocationPress, - (location: RNLocation) => console.log('MyLocation press:', location) - )} - onMyLocationButtonPress={wrapCallback( - props.onMyLocationButtonPress, - (pressed: boolean) => console.log('MyLocation button press:', pressed) - )} - onCameraChangeStart={wrapCallback( - props.onCameraChangeStart, - (r: RNRegion, cam: RNCamera, g: boolean) => - console.log('Camera start:', r, cam, g) - )} - onCameraChange={wrapCallback( - props.onCameraChange, - (r: RNRegion, cam: RNCamera, g: boolean) => - console.log('Camera changed:', r, cam, g) - )} - onCameraChangeComplete={wrapCallback( - props.onCameraChangeComplete, - (r: RNRegion, cam: RNCamera, g: boolean) => - console.log('Camera complete:', r, cam, g) - )} - onLocationUpdate={wrapCallback( - props.onLocationUpdate, - (l: RNLocation) => console.log('Location:', l) - )} - onLocationError={wrapCallback( - props.onLocationError, - (e: RNLocationErrorCode) => console.log('Location error:', e) - )} + {...mapCallbacks} /> {children} {!mapLoaded && ( diff --git a/example/src/hooks/useMapCallbacks.ts b/example/src/hooks/useMapCallbacks.ts new file mode 100644 index 0000000..8e1435c --- /dev/null +++ b/example/src/hooks/useMapCallbacks.ts @@ -0,0 +1,222 @@ +import React, { useCallback } from 'react'; +import { + type GoogleMapsViewRef, + type RNCamera, + type RNGoogleMapsPlusViewProps, + type RNIndoorBuilding, + type RNIndoorLevel, + type RNLatLng, + type RNLocation, + RNLocationErrorCode, + RNMapErrorCode, + type RNRegion, +} from 'react-native-google-maps-plus'; +import { useNitroCallback } from './useNitroCallback'; + +export function useMapCallbacks( + props: RNGoogleMapsPlusViewProps, + mapRef: React.RefObject, + setMapLoaded: (loaded: boolean) => void +) { + const hybridRef = useNitroCallback( + useCallback( + (ref: GoogleMapsViewRef) => { + mapRef.current = ref; + }, + [mapRef] + ) + ); + + const onMapError = useNitroCallback( + props.onMapError, + useCallback((e: RNMapErrorCode) => console.log('Map error:', e), []) + ); + + const onMapReady = useNitroCallback( + props.onMapReady, + useCallback((ready: boolean) => console.log('Map is ready:', ready), []) + ); + + const onMapLoaded = useNitroCallback( + props.onMapLoaded, + useCallback( + (region: RNRegion, camera: RNCamera) => { + console.log('Map is loaded:', region, camera); + setMapLoaded(true); + }, + [setMapLoaded] + ) + ); + + const onMapPress = useNitroCallback( + props.onMapPress, + useCallback((c: RNLatLng) => console.log('Map press:', c), []) + ); + + const onMapLongPress = useNitroCallback( + props.onMapLongPress, + useCallback((c: RNLatLng) => console.log('Map long press:', c), []) + ); + + const onPoiPress = useNitroCallback( + props.onPoiPress, + useCallback( + (placeId: string, name: string, coordinate: RNLatLng) => + console.log('Poi press:', placeId, name, coordinate), + [] + ) + ); + + const onMarkerPress = useNitroCallback( + props.onMarkerPress, + useCallback((id: string) => console.log('Marker press:', id), []) + ); + + const onPolylinePress = useNitroCallback( + props.onPolylinePress, + useCallback((id: string) => console.log('Polyline press:', id), []) + ); + + const onPolygonPress = useNitroCallback( + props.onPolygonPress, + useCallback((id: string) => console.log('Polygon press:', id), []) + ); + + const onCirclePress = useNitroCallback( + props.onCirclePress, + useCallback((id: string) => console.log('Circle press:', id), []) + ); + + const onMarkerDragStart = useNitroCallback( + props.onMarkerDragStart, + useCallback( + (id: string, latLng: RNLatLng) => + console.log('Marker drag start:', id, latLng), + [] + ) + ); + + const onMarkerDrag = useNitroCallback( + props.onMarkerDrag, + useCallback( + (id: string, latLng: RNLatLng) => console.log('Marker drag:', id, latLng), + [] + ) + ); + + const onMarkerDragEnd = useNitroCallback( + props.onMarkerDragEnd, + useCallback( + (id: string, latLng: RNLatLng) => + console.log('Marker drag end:', id, latLng), + [] + ) + ); + + const onIndoorBuildingFocused = useNitroCallback( + props.onIndoorBuildingFocused, + useCallback((b: RNIndoorBuilding) => console.log('Indoor building:', b), []) + ); + + const onIndoorLevelActivated = useNitroCallback( + props.onIndoorLevelActivated, + useCallback((l: RNIndoorLevel) => console.log('Indoor level:', l), []) + ); + + const onInfoWindowPress = useNitroCallback( + props.onInfoWindowPress, + useCallback((id: string) => console.log('InfoWindow press:', id), []) + ); + + const onInfoWindowClose = useNitroCallback( + props.onInfoWindowClose, + useCallback((id: string) => console.log('InfoWindow close:', id), []) + ); + + const onInfoWindowLongPress = useNitroCallback( + props.onInfoWindowLongPress, + useCallback((id: string) => console.log('InfoWindow long press:', id), []) + ); + + const onMyLocationPress = useNitroCallback( + props.onMyLocationPress, + useCallback((l: RNLocation) => console.log('MyLocation press:', l), []) + ); + + const onMyLocationButtonPress = useNitroCallback( + props.onMyLocationButtonPress, + useCallback( + (press: boolean) => console.log('MyLocation button press:', press), + [] + ) + ); + + const onCameraChangeStart = useNitroCallback( + props.onCameraChangeStart, + useCallback( + (r: RNRegion, cam: RNCamera, g: boolean) => + console.log('Camera start:', r, cam, g), + [] + ) + ); + + const onCameraChange = useNitroCallback( + props.onCameraChange, + useCallback( + (r: RNRegion, cam: RNCamera, g: boolean) => + console.log('Camera change:', r, cam, g), + [] + ) + ); + + const onCameraChangeComplete = useNitroCallback( + props.onCameraChangeComplete, + useCallback( + (r: RNRegion, cam: RNCamera, g: boolean) => + console.log('Camera complete:', r, cam, g), + [] + ) + ); + + const onLocationUpdate = useNitroCallback( + props.onLocationUpdate, + useCallback((l: RNLocation) => console.log('Location:', l), []) + ); + + const onLocationError = useNitroCallback( + props.onLocationError, + useCallback( + (e: RNLocationErrorCode) => console.log('Location error:', e), + [] + ) + ); + + return { + hybridRef, + onMapError, + onMapReady, + onMapLoaded, + onMapPress, + onMapLongPress, + onPoiPress, + onMarkerPress, + onPolylinePress, + onPolygonPress, + onCirclePress, + onMarkerDragStart, + onMarkerDrag, + onMarkerDragEnd, + onIndoorBuildingFocused, + onIndoorLevelActivated, + onInfoWindowPress, + onInfoWindowClose, + onInfoWindowLongPress, + onMyLocationPress, + onMyLocationButtonPress, + onCameraChangeStart, + onCameraChange, + onCameraChangeComplete, + onLocationUpdate, + onLocationError, + }; +} diff --git a/example/src/hooks/useNitroCallback.ts b/example/src/hooks/useNitroCallback.ts new file mode 100644 index 0000000..5d3b999 --- /dev/null +++ b/example/src/hooks/useNitroCallback.ts @@ -0,0 +1,15 @@ +import { useMemo } from 'react'; +import { callback } from 'react-native-nitro-modules'; +export function useNitroCallback void>( + propCallback: T | undefined, + fallback?: (...args: Parameters) => void +) { + return useMemo(() => { + console.log('useNitroCallback'); + const fn = (...args: Parameters) => { + propCallback?.(...args); + fallback?.(...args); + }; + return callback(fn); + }, [propCallback, fallback]); +} diff --git a/example/src/screens/ClsuteringScreen.tsx b/example/src/screens/ClsuteringScreen.tsx index 6344fc7..546d2a9 100644 --- a/example/src/screens/ClsuteringScreen.tsx +++ b/example/src/screens/ClsuteringScreen.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState, useMemo } from 'react'; +import React, { useRef, useState, useMemo, useCallback } from 'react'; import MapWrapper from '../components/MapWrapper'; import ControlPanel from '../components/ControlPanel'; import type { @@ -106,12 +106,16 @@ export default function ClusteringScreen() { }); }, [points]); + const handleMapLoaded = useCallback((r: RNRegion) => setRegion(r), []); + + const handleCameraChange = useCallback((r: RNRegion) => setRegion(r), []); + return ( setRegion(r)} - onCameraChange={(r: RNRegion) => setRegion(r)} + onMapLoaded={handleMapLoaded} + onCameraChange={handleCameraChange} > diff --git a/example/src/screens/MarkersScreen.tsx b/example/src/screens/MarkersScreen.tsx index 1668342..9371475 100644 --- a/example/src/screens/MarkersScreen.tsx +++ b/example/src/screens/MarkersScreen.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useRef, useState } from 'react'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; import MapWrapper from '../components/MapWrapper'; import { makeMarker } from '../utils/mapGenerators'; import type { @@ -98,13 +98,17 @@ export default function MarkersScreen() { [markers] ); + const handleMarkerPress = useCallback((id: string) => { + mapRef.current?.showMarkerInfoWindow(id); + }, []); + return ( <> mapRef.current?.showMarkerInfoWindow(id)} + onMarkerPress={handleMarkerPress} > From 2c89c93c7a9f2a7d996eed11a4a4fc561b13f4ed Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 08:05:37 +0700 Subject: [PATCH 09/40] chore: update dependencies --- example/ios/Podfile.lock | 4 ++-- example/package.json | 4 ++-- package.json | 6 +++--- yarn.lock | 36 ++++++++++++++++++------------------ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index adfc8e8..16b6ed6 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -46,7 +46,7 @@ PODS: - hermes-engine (0.82.1): - hermes-engine/Pre-built (= 0.82.1) - hermes-engine/Pre-built (0.82.1) - - NitroModules (0.31.5): + - NitroModules (0.31.6): - boost - DoubleConversion - fast_float @@ -3052,7 +3052,7 @@ SPEC CHECKSUMS: Google-Maps-iOS-Utils: bed22fa703c919259b3901449434d60d994fae20 GoogleMaps: a40d3b1f511f0fa2036e7b08c920c33279b1d5fd hermes-engine: 273e30e7fb618279934b0b95ffab60ecedb7acf5 - NitroModules: afc462ff4c87c9a405ac7e93cd133137c407a7f9 + NitroModules: edf2d33c02fd8cbb0021e031d380d286b17f527b RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: f17e2ebc07876ca9ab8eb6e4b0a4e4647497ae3a RCTRequired: e2c574c1b45231f7efb0834936bd609d75072b63 diff --git a/example/package.json b/example/package.json index 018ae17..098f774 100644 --- a/example/package.json +++ b/example/package.json @@ -20,7 +20,7 @@ "react-native-clusterer": "5.0.2", "react-native-gesture-handler": "2.29.1", "react-native-google-maps-plus": "workspace:*", - "react-native-nitro-modules": "0.31.5", + "react-native-nitro-modules": "0.31.6", "react-native-reanimated": "4.1.5", "react-native-safe-area-context": "5.6.2", "react-native-screens": "4.18.0", @@ -38,7 +38,7 @@ "@react-native/metro-config": "0.82.1", "@react-native/typescript-config": "0.82.1", "@types/react": "19.1.1", - "react-native-builder-bob": "0.40.14", + "react-native-builder-bob": "0.40.15", "react-native-monorepo-config": "0.3.0" }, "engines": { diff --git a/package.json b/package.json index b2e722f..c788a8f 100644 --- a/package.json +++ b/package.json @@ -103,12 +103,12 @@ "eslint-plugin-prettier": "5.5.4", "jest": "30.2.0", "lefthook": "2.0.3", - "nitrogen": "0.31.5", + "nitrogen": "0.31.6", "prettier": "3.6.2", "react": "19.1.1", "react-native": "0.82.1", - "react-native-builder-bob": "0.40.14", - "react-native-nitro-modules": "0.31.5", + "react-native-builder-bob": "0.40.15", + "react-native-nitro-modules": "0.31.6", "semantic-release": "25.0.2", "typescript": "5.9.3" }, diff --git a/yarn.lock b/yarn.lock index 4fa669f..0eef235 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10558,18 +10558,18 @@ __metadata: languageName: node linkType: hard -"nitrogen@npm:0.31.5": - version: 0.31.5 - resolution: "nitrogen@npm:0.31.5" +"nitrogen@npm:0.31.6": + version: 0.31.6 + resolution: "nitrogen@npm:0.31.6" dependencies: chalk: ^5.3.0 - react-native-nitro-modules: ^0.31.5 + react-native-nitro-modules: ^0.31.6 ts-morph: ^27.0.0 yargs: ^18.0.0 zod: ^4.0.5 bin: nitrogen: lib/index.js - checksum: defb6948f1f5727ae4e6412870226fb52a2b6ebe96fe5501a4093c5c513d55c465ae20f066c914d8540125818d55ab03b156b4e085213667724425b730c11ab3 + checksum: 8c0ea6fa929fd8a358e1cca9e6518902b0ebfd11a1b5ad325fd0807aefa4e7ee4231ded3448208b10765a687d32a99f8e35f46e45effaedec176c16ffdf36eed languageName: node linkType: hard @@ -11863,9 +11863,9 @@ __metadata: languageName: node linkType: hard -"react-native-builder-bob@npm:0.40.14": - version: 0.40.14 - resolution: "react-native-builder-bob@npm:0.40.14" +"react-native-builder-bob@npm:0.40.15": + version: 0.40.15 + resolution: "react-native-builder-bob@npm:0.40.15" dependencies: "@babel/core": ^7.25.2 "@babel/plugin-transform-flow-strip-types": ^7.26.5 @@ -11891,7 +11891,7 @@ __metadata: yargs: ^17.5.1 bin: bob: bin/bob - checksum: f7a95477535ccf749affb79f539faf925ff23a3864b0ad4fd4eb0e729f246e1c6357b392857156695d22005a60aa9f9f7bb773e2582f0e06b5c3f77e5258f00d + checksum: abe76dfce15679da3c8c475d39127bc1cb970118be3bd964b63bb6aeabe8d3eb42698f5d86b05386af12ba378f924a7a1e4e22194ca400c92e6961d2000dc682 languageName: node linkType: hard @@ -11942,12 +11942,12 @@ __metadata: react: 19.1.1 react-hook-form: 7.66.0 react-native: 0.82.1 - react-native-builder-bob: 0.40.14 + react-native-builder-bob: 0.40.15 react-native-clusterer: 5.0.2 react-native-gesture-handler: 2.29.1 react-native-google-maps-plus: "workspace:*" react-native-monorepo-config: 0.3.0 - react-native-nitro-modules: 0.31.5 + react-native-nitro-modules: 0.31.6 react-native-reanimated: 4.1.5 react-native-safe-area-context: 5.6.2 react-native-screens: 4.18.0 @@ -11984,12 +11984,12 @@ __metadata: eslint-plugin-prettier: 5.5.4 jest: 30.2.0 lefthook: 2.0.3 - nitrogen: 0.31.5 + nitrogen: 0.31.6 prettier: 3.6.2 react: 19.1.1 react-native: 0.82.1 - react-native-builder-bob: 0.40.14 - react-native-nitro-modules: 0.31.5 + react-native-builder-bob: 0.40.15 + react-native-nitro-modules: 0.31.6 semantic-release: 25.0.2 typescript: 5.9.3 peerDependencies: @@ -12033,13 +12033,13 @@ __metadata: languageName: node linkType: hard -"react-native-nitro-modules@npm:0.31.5, react-native-nitro-modules@npm:^0.31.5": - version: 0.31.5 - resolution: "react-native-nitro-modules@npm:0.31.5" +"react-native-nitro-modules@npm:0.31.6, react-native-nitro-modules@npm:^0.31.6": + version: 0.31.6 + resolution: "react-native-nitro-modules@npm:0.31.6" peerDependencies: react: "*" react-native: "*" - checksum: 957c1c264d5a7bb791ca7aa0c97b577c0ba60bb5765f4bf6fdf64a6f414d33702d94909823b33a4fc1b01f3d51175669c779212e645c21ccd204197ea66ed701 + checksum: d9b5074ae30901d5ef305c3771c87a7eb4872b9f0411fbc0c12d51a3be28d016dc21419fedad9119cdba19977ed826c5c5d716601115f306faccce6a3392d8da languageName: node linkType: hard From 6086de398bde08eefa2fbdd18093730cbbd43abc Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 10:48:50 +0700 Subject: [PATCH 10/40] chore(refactor): package.json --- .eslintignore | 3 +++ .eslintrc.js | 18 ++++++++++++++ .prettierignore | 3 +++ .prettierrc | 7 ++++++ bob.config.js | 14 +++++++++++ package.json | 63 ++++++------------------------------------------- 6 files changed, 52 insertions(+), 56 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .prettierrc create mode 100644 bob.config.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..d7c3dd9 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules/ +lib/ +expoConfig/build/ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..55c15eb --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,18 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + extends: ['@react-native', 'prettier'], + plugins: ['prettier'], + rules: { + 'prettier/prettier': [ + 'warn', + { + quoteProps: 'consistent', + singleQuote: true, + tabWidth: 2, + trailingComma: 'es5', + useTabs: false, + }, + ], + }, +}; diff --git a/.prettierignore b/.prettierignore index 1b763b1..d49e317 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,4 @@ CHANGELOG.md +node_modules/ +lib/ +expoConfig/build/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6707610 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "quoteProps": "consistent", + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "useTabs": false +} diff --git a/bob.config.js b/bob.config.js new file mode 100644 index 0000000..d6328a8 --- /dev/null +++ b/bob.config.js @@ -0,0 +1,14 @@ +/** @type {import('react-native-builder-bob').Config} */ +module.exports = { + source: 'src', + output: 'lib', + targets: [ + 'module', + [ + 'typescript', + { + project: 'tsconfig.json', + }, + ], + ], +}; diff --git a/package.json b/package.json index c788a8f..3ae57a1 100644 --- a/package.json +++ b/package.json @@ -40,31 +40,28 @@ "expo" ], "files": [ - "src", "lib", - "expoConfig/build", - "!**/__tests__", - "!**/__fixtures__", - "!**/__mocks__", - "react-native.config.js", + "src", "nitrogen", - "cpp", "nitro.json", + "android/src", "android/build.gradle", "android/fix-prefab.gradle", "android/gradle.properties", "android/CMakeLists.txt", "android/proguard-rules.pro", - "android/src", "ios/**/*.h", "ios/**/*.m", "ios/**/*.mm", "ios/**/*.cpp", "ios/**/*.swift", + "scripts/svgkit_patch.rb", "app.plugin.js", + "expoConfig/build", + "react-native.config.js", "*.podspec", - "scripts", - "README.md" + "README.md", + "LICENSE" ], "workspaces": [ "example" @@ -123,51 +120,5 @@ "optional": true } }, - "eslintConfig": { - "root": true, - "extends": [ - "@react-native", - "prettier" - ], - "plugins": [ - "prettier" - ], - "rules": { - "prettier/prettier": [ - "warn", - { - "quoteProps": "consistent", - "singleQuote": true, - "tabWidth": 2, - "trailingComma": "es5", - "useTabs": false - } - ] - } - }, - "eslintIgnore": [ - "node_modules/", - "lib/" - ], - "prettier": { - "quoteProps": "consistent", - "singleQuote": true, - "tabWidth": 2, - "trailingComma": "es5", - "useTabs": false - }, - "react-native-builder-bob": { - "source": "src", - "output": "lib", - "targets": [ - "module", - [ - "typescript", - { - "project": "tsconfig.json" - } - ] - ] - }, "packageManager": "yarn@3.6.1" } From 8d52cd9725c4007aa15195491a072cabc8f98eb9 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 10:56:54 +0700 Subject: [PATCH 11/40] chore: update package.json --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3ae57a1..1eb72c8 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,10 @@ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", "test": "jest", "git:clean": "git clean -dfX", - "release": "semantic-release", - "build": "yarn nitrogen && bob build && yarn build:plugin", "build:plugin": "tsc -p expoConfig/tsconfig.json", "nitrogen": "nitrogen --logLevel=\"debug\" && node scripts/nitrogen-patch.js", - "prepare": "bob build" + "release": "semantic-release", + "build": "yarn nitrogen && bob build && yarn build:plugin" }, "keywords": [ "react-native", From 9ffbba204ce938b83b7e0a16a8928969a0698d37 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 12:44:09 +0700 Subject: [PATCH 12/40] chore: update formatter style --- .eslintignore | 3 --- .eslintrc.js | 18 --------------- android/.editorconfig | 12 ++++++++++ .../extensions/RNLatLngBoundsExtension.kt | 1 - .../extensions/ThrowableExtension.kt | 2 ++ ios/.swiftformat | 23 +++++++++++-------- ios/extensions/CLLocation+Extension.swift | 2 +- ios/extensions/RNLineCapType+Extension.swift | 1 - ios/extensions/RNLineJoinType+Extension.swift | 2 -- ios/extensions/String+Extensions.swift | 12 +++++----- 10 files changed, 35 insertions(+), 41 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.js create mode 100644 android/.editorconfig diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index d7c3dd9..0000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -lib/ -expoConfig/build/ diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 55c15eb..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @type {import('eslint').Linter.Config} */ -module.exports = { - root: true, - extends: ['@react-native', 'prettier'], - plugins: ['prettier'], - rules: { - 'prettier/prettier': [ - 'warn', - { - quoteProps: 'consistent', - singleQuote: true, - tabWidth: 2, - trailingComma: 'es5', - useTabs: false, - }, - ], - }, -}; diff --git a/android/.editorconfig b/android/.editorconfig new file mode 100644 index 0000000..b6fb090 --- /dev/null +++ b/android/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +indent_style = space +indent_size = 2 + +max_line_length = 150 \ No newline at end of file diff --git a/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt b/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt index a5b2a66..2999037 100644 --- a/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt +++ b/android/src/main/java/com/rngooglemapsplus/extensions/RNLatLngBoundsExtension.kt @@ -1,6 +1,5 @@ package com.rngooglemapsplus.extensions -import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.LatLngBounds import com.rngooglemapsplus.RNLatLngBounds diff --git a/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt b/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt index 3c29cc4..09ace27 100644 --- a/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt +++ b/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt @@ -16,10 +16,12 @@ fun Throwable.toLocationErrorCode(context: Context): RNLocationErrorCode { when (statusCode) { CommonStatusCodes.NETWORK_ERROR -> RNLocationErrorCode.POSITION_UNAVAILABLE + LocationSettingsStatusCodes.RESOLUTION_REQUIRED, LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE, -> RNLocationErrorCode.SETTINGS_NOT_SATISFIED + else -> RNLocationErrorCode.INTERNAL_ERROR } diff --git a/ios/.swiftformat b/ios/.swiftformat index a4c1ee5..a18d528 100644 --- a/ios/.swiftformat +++ b/ios/.swiftformat @@ -1,17 +1,22 @@ --swiftversion 5.10 +--xcode-indentation enabled --disable conditionalAssignment --disable redundantType --disable unusedArguments + --binary-grouping none --decimal-grouping none --hex-literal-case lowercase --indent 2 ---no-space-operators ---semicolons never ---trailing-commas never ---rules braces,indent ---wrap-arguments preserve ---wrap-parameters preserve ---wrap-collections preserve ---closing-paren same-line ---xcode-indentation enabled + +--max-width 150 + +--wrap-arguments disabled +--wrap-parameters disabled +--wrap-return-type never +--disable wrapMultilineStatementBraces + +--rules indent,braces,spaceInsideParens,spaceInsideBraces,spaceAroundOperators + +--trim-whitespace nonblank-lines +--linebreaks lf diff --git a/ios/extensions/CLLocation+Extension.swift b/ios/extensions/CLLocation+Extension.swift index c94855b..95ac8e0 100644 --- a/ios/extensions/CLLocation+Extension.swift +++ b/ios/extensions/CLLocation+Extension.swift @@ -18,7 +18,7 @@ extension CLLocation { verticalAccuracy: verticalAccuracy, speedAccuracy: speedAccuracy, courseAccuracy: courseAccuracy, - floor: floor.map { Double($0.level)}, + floor: floor.map { Double($0.level) }, isFromMockProvider: false, timestamp: timestamp.timeIntervalSince1970 * 1000 ) diff --git a/ios/extensions/RNLineCapType+Extension.swift b/ios/extensions/RNLineCapType+Extension.swift index 53db3b6..5536094 100644 --- a/ios/extensions/RNLineCapType+Extension.swift +++ b/ios/extensions/RNLineCapType+Extension.swift @@ -7,4 +7,3 @@ extension RNLineCapType { } } } - diff --git a/ios/extensions/RNLineJoinType+Extension.swift b/ios/extensions/RNLineJoinType+Extension.swift index 6621ac0..add9343 100644 --- a/ios/extensions/RNLineJoinType+Extension.swift +++ b/ios/extensions/RNLineJoinType+Extension.swift @@ -6,6 +6,4 @@ extension RNLineJoinType { default: return .miter } } - } - diff --git a/ios/extensions/String+Extensions.swift b/ios/extensions/String+Extensions.swift index 9ea47fd..3daeaf1 100644 --- a/ios/extensions/String+Extensions.swift +++ b/ios/extensions/String+Extensions.swift @@ -90,12 +90,12 @@ extension UIColor { // swiftlint:disable:next large_tuple let (r1, g1, b1): (Double, Double, Double) switch h { - case 0..<60: (r1, g1, b1) = (c, x, 0) - case 60..<120: (r1, g1, b1) = (x, c, 0) - case 120..<180: (r1, g1, b1) = (0, c, x) - case 180..<240: (r1, g1, b1) = (0, x, c) - case 240..<300: (r1, g1, b1) = (x, 0, c) - case 300..<360: (r1, g1, b1) = (c, 0, x) + case 0 ..< 60: (r1, g1, b1) = (c, x, 0) + case 60 ..< 120: (r1, g1, b1) = (x, c, 0) + case 120 ..< 180: (r1, g1, b1) = (0, c, x) + case 180 ..< 240: (r1, g1, b1) = (0, x, c) + case 240 ..< 300: (r1, g1, b1) = (x, 0, c) + case 300 ..< 360: (r1, g1, b1) = (c, 0, x) default: (r1, g1, b1) = (0, 0, 0) } return UIColor( From 605d600c847a65300c4470cca2bb6959924ca417 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 16:24:24 +0700 Subject: [PATCH 13/40] chore(android): update google maps utils --- android/gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/gradle.properties b/android/gradle.properties index 14981ef..7ef839b 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -6,4 +6,4 @@ RNGoogleMapsPlus_ndkVersion=27.1.12297006 RNGoogleMapsPlus_googlePlayServicesBaseVersion=18.9.0 RNGoogleMapsPlus_googlePlayServicesMapsVersion=19.2.0 RNGoogleMapsPlus_googlePlayServicesLocationVersion=21.3.0 -RNGoogleMapsPlus_mapsUtilsVersion=3.19.0 +RNGoogleMapsPlus_mapsUtilsVersion=3.19.1 From c50ff3168ffee3b5f32c8916241d18d5a6708574 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 19:16:39 +0700 Subject: [PATCH 14/40] ci: update workflows --- .github/workflows/pull_request.yml | 8 ++++++++ .github/workflows/release.yml | 2 +- example/ios/Podfile.lock | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f37b9f5..323446a 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -13,6 +13,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 - name: Setup uses: ./.github/actions/setup @@ -37,6 +39,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 - name: Setup uses: ./.github/actions/setup @@ -50,6 +54,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 - name: Setup uses: ./.github/actions/setup @@ -93,6 +99,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 - name: Setup uses: ./.github/actions/setup diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a83f751..cb428cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Checkout uses: actions/checkout@v5.0.0 with: - fetch-depth: 0 # wichtig für semantic-release, damit alle Tags vorhanden sind + fetch-depth: 0 - name: Setup uses: ./.github/actions/setup diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 16b6ed6..856bd0b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2504,7 +2504,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNGoogleMapsPlus (1.8.6): + - RNGoogleMapsPlus (1.8.7): - boost - DoubleConversion - fast_float @@ -3120,7 +3120,7 @@ SPEC CHECKSUMS: ReactCodegen: 0bce2d209e2e802589f4c5ff76d21618200e74cb ReactCommon: 801eff8cb9c940c04d3a89ce399c343ee3eff654 RNGestureHandler: 67501c6d447027581aa1d8e5a7a3ea5a7f0a89ff - RNGoogleMapsPlus: d94844f2d397099f2153d5f9a29e96f70f547bde + RNGoogleMapsPlus: d64028210f2a3b74aa6a7f440ac773c3f1247c93 RNReanimated: 05c5a85c3ee54ac68d60c8a9b42dbc441e3326ca RNScreens: 98771ad898d1c0528fc8139606bbacf5a2e9d237 RNWorklets: ab618bf7d1c7fd2cb793b9f0f39c3e29274b3ebf From 26df301ea705138d079d25f163b54bb3fc734f7e Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 20:07:24 +0700 Subject: [PATCH 15/40] ci: added next release workflow --- .../prepare_dev_for_next_release.yml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/prepare_dev_for_next_release.yml diff --git a/.github/workflows/prepare_dev_for_next_release.yml b/.github/workflows/prepare_dev_for_next_release.yml new file mode 100644 index 0000000..afbc832 --- /dev/null +++ b/.github/workflows/prepare_dev_for_next_release.yml @@ -0,0 +1,68 @@ +name: Prepare dev branch for next release + +on: + push: + branches: [main] + paths: + - 'package.json' + +permissions: + contents: write + +jobs: + update-pods: + name: Update Podfile.lock after release + runs-on: macos-latest + if: startsWith(github.event.head_commit.message, 'release:') + env: + XCODE_VERSION: latest-stable + + steps: + - name: Checkout + uses: actions/checkout@v5.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Setup + uses: ./.github/actions/setup + + - name: Install CocoaPods + working-directory: example + run: yarn ios:pods + + - name: Commit updated Podfile.lock + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git add example/ios/Podfile.lock + + if git diff --cached --quiet; then + echo "No Podfile.lock changes." + exit 0 + fi + + git commit -m "chore(example): update Podfile.lock after release [skip ci]" + git push + + sync-dev: + name: Merge main into dev + runs-on: ubuntu-latest + needs: update-pods + if: startsWith(github.event.head_commit.message, 'release:') + steps: + - name: Checkout + uses: actions/checkout@v5.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Fetch all branches + run: git fetch --all + + - name: Fast-forward dev with main + run: | + git checkout dev + git merge origin/main --ff-only + git push origin dev From a104b0821ab42f5e798c91b7031de769880c021b Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 20:11:26 +0700 Subject: [PATCH 16/40] ci: update release config --- release.config.cjs | 10 ---------- scripts/create-dev-tag.sh | 8 -------- 2 files changed, 18 deletions(-) delete mode 100755 scripts/create-dev-tag.sh diff --git a/release.config.cjs b/release.config.cjs index 7b5dc9c..14e6e3a 100644 --- a/release.config.cjs +++ b/release.config.cjs @@ -21,15 +21,6 @@ const gitPlugin = isDev }, ]; -const execPlugin = isDev - ? false - : [ - '@semantic-release/exec', - { - successCmd: './scripts/create-dev-tag.sh ${nextRelease.version}', - }, - ]; - const sortMap = Object.fromEntries( rules.map((rule, index) => [rule.title, index]) ); @@ -91,6 +82,5 @@ module.exports = { }, ], ...(gitPlugin ? [gitPlugin] : []), - ...(execPlugin ? [execPlugin] : []), ], }; diff --git a/scripts/create-dev-tag.sh b/scripts/create-dev-tag.sh deleted file mode 100755 index 638f568..0000000 --- a/scripts/create-dev-tag.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -VERSION="$1" -IFS="." read -r major minor patch <<< "$VERSION" -NEXT_MINOR=$((minor + 1)) -DEV_TAG="v${major}.${NEXT_MINOR}.0-dev.0" -echo "[semantic-release] tagging: $DEV_TAG" -git tag "$DEV_TAG" -git push origin "$DEV_TAG" From eea7b57303556dd2dad5758b9e4ab4f4e2efefcc Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 20:37:45 +0700 Subject: [PATCH 17/40] chore: updated nitro --- src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 3f8cbc0..c56798f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -343,7 +343,7 @@ export type RNLocation = { }; export type RNLocationAndroid = { - provider?: string | null; + provider?: string; elapsedRealtimeNanos?: number; bearingAccuracyDegrees?: number; speedAccuracyMetersPerSecond?: number; @@ -357,7 +357,7 @@ export type RNLocationIOS = { verticalAccuracy?: number; speedAccuracy?: number; courseAccuracy?: number; - floor?: number | null; + floor?: number; isFromMockProvider?: boolean; timestamp?: number; }; From 6cdf6869139f619324344140b9978ba211ed8941 Mon Sep 17 00:00:00 2001 From: pinpong Date: Thu, 13 Nov 2025 20:38:19 +0700 Subject: [PATCH 18/40] ci: update pr workflow --- .github/workflows/pull_request.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 323446a..86b42da 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -120,10 +120,5 @@ jobs: - name: Create Secrets.xcconfig run: echo MAPS_API_KEY="API_KEY" >> example/ios/Secrets.xcconfig - - name: Install iOS Simulator runtime - run: | - sudo xcodebuild -runFirstLaunch - sudo xcodebuild -downloadPlatform iOS - - name: Build example for iOS run: yarn build:ios From c209cc81bf092e01035b66d53640198f10795b67 Mon Sep 17 00:00:00 2001 From: pinpong Date: Fri, 14 Nov 2025 08:10:10 +0700 Subject: [PATCH 19/40] ci: add pr validation workflow --- .github/workflows/validate_pr_source.yml | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/validate_pr_source.yml diff --git a/.github/workflows/validate_pr_source.yml b/.github/workflows/validate_pr_source.yml new file mode 100644 index 0000000..b977877 --- /dev/null +++ b/.github/workflows/validate_pr_source.yml @@ -0,0 +1,25 @@ +name: Validate main branch PR source + +on: + pull_request_target: + branches: [main] + types: [opened, reopened, synchronize] + +permissions: + pull-requests: write + contents: read + +jobs: + close: + if: ${{ github.event.pull_request.head.ref != 'dev' }} + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Close PR + run: | + echo "Closing PR from invalid source branch: ${{ github.event.pull_request.head.ref }}" + + gh pr comment ${{ github.event.pull_request.number }} \ + --body "This PR targets **main**, but it was created from **${{ github.event.pull_request.head.ref }}**. Only PRs from **dev** are allowed." + gh pr close ${{ github.event.pull_request.number }} From 5b1a89809904cb51d890355cc89b35da1a4631ea Mon Sep 17 00:00:00 2001 From: pinpong Date: Fri, 14 Nov 2025 10:32:15 +0700 Subject: [PATCH 20/40] chore: updated eslint --- eslint.config.mjs | 73 +- example/babel.config.js | 16 +- example/eslint.config.mjs | 11 + example/index.js | 5 +- example/metro.config.js | 1 + example/package.json | 1 + example/react-native.config.js | 1 + example/src/App.tsx | 44 +- example/src/components/ControlPanel.tsx | 14 +- example/src/components/HeaderButton.tsx | 6 +- .../MapConfigDialog.tsx | 9 +- example/src/components/MapWrapper.tsx | 28 +- .../src/{utils => data}/heatMapWeightData.ts | 0 example/src/{utils => data}/kmlData.ts | 0 .../mapStyles.ts => data/mapStylesData.ts} | 0 example/src/hooks/useAppTheme.tsx | 3 +- example/src/hooks/useHeaderButton.tsx | 3 +- example/src/hooks/useMapCallbacks.ts | 4 +- example/src/hooks/useNitroCallback.ts | 2 + example/src/screens/BasicMapScreen.tsx | 21 +- example/src/screens/BlankScreen.tsx | 9 +- example/src/screens/CameraTestScreen.tsx | 6 +- example/src/screens/CirclesScreen.tsx | 15 +- example/src/screens/ClsuteringScreen.tsx | 15 +- example/src/screens/CustomStyleScreen.tsx | 8 +- example/src/screens/HeatmapScreen.tsx | 15 +- example/src/screens/HomeScreen.tsx | 15 +- example/src/screens/IndoorLevelMapScreen.tsx | 6 +- example/src/screens/KmlLayerScreen.tsx | 15 +- example/src/screens/LocationScreen.tsx | 14 +- example/src/screens/MarkersScreen.tsx | 17 +- example/src/screens/PolygonsScreen.tsx | 15 +- example/src/screens/PolylinesScreen.tsx | 15 +- example/src/screens/SnaptshotTestScreen.tsx | 11 +- example/src/screens/StressTestScreen.tsx | 8 +- example/src/screens/SvgMarkersScreen.tsx | 6 +- example/src/screens/UrlTileOverlay.tsx | 15 +- example/src/utils/mapGenerators.ts | 3 +- .../maptConfigDialog => utils}/validator.ts | 19 +- .../utils.ts => utils/validatorUtils.ts} | 0 example/tsconfig.json | 1 + .../src/android/withAndroidGoogleMapsPlus.ts | 3 +- expoConfig/src/index.ts | 14 +- expoConfig/src/ios/withIosGoogleMapsPlus.ts | 1 + package.json | 6 +- scripts/nitrogen-patch.js | 6 +- src/GoogleMapsPlus.tsx | 3 +- src/RNGoogleMapsPlusModule.nitro.ts | 1 + src/RNGoogleMapsPlusView.nitro.ts | 10 +- src/index.tsx | 3 +- yarn.lock | 770 ++++++++++++++---- 51 files changed, 933 insertions(+), 354 deletions(-) create mode 100644 example/eslint.config.mjs rename example/src/components/{maptConfigDialog => }/MapConfigDialog.tsx (97%) rename example/src/{utils => data}/heatMapWeightData.ts (100%) rename example/src/{utils => data}/kmlData.ts (100%) rename example/src/{utils/mapStyles.ts => data/mapStylesData.ts} (100%) rename example/src/{components/maptConfigDialog => utils}/validator.ts (99%) rename example/src/{components/maptConfigDialog/utils.ts => utils/validatorUtils.ts} (100%) diff --git a/eslint.config.mjs b/eslint.config.mjs index ae5fa81..32fb4e2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,13 +1,17 @@ import { fixupConfigRules } from '@eslint/compat'; import { FlatCompat } from '@eslint/eslintrc'; import js from '@eslint/js'; -import prettier from 'eslint-plugin-prettier'; -import { defineConfig } from 'eslint/config'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { defineConfig } from 'eslint/config'; + +import importPlugin from 'eslint-plugin-import'; +import unusedImportsPlugin from 'eslint-plugin-unused-imports'; +import prettierPlugin from 'eslint-plugin-prettier'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); + const compat = new FlatCompat({ baseDirectory: __dirname, recommendedConfig: js.configs.recommended, @@ -17,10 +21,63 @@ const compat = new FlatCompat({ export default defineConfig([ { extends: fixupConfigRules(compat.extends('@react-native', 'prettier')), - plugins: { prettier }, + files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'], + plugins: { + 'import': importPlugin, + 'unused-imports': unusedImportsPlugin, + 'prettier': prettierPlugin, + }, rules: { - 'react/react-in-jsx-scope': 'off', 'prettier/prettier': 'error', + 'react/react-in-jsx-scope': 'off', + 'unused-imports/no-unused-imports': 'error', + 'unused-imports/no-unused-vars': [ + 'error', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'after-used', + argsIgnorePattern: '^_', + }, + ], + 'import/order': [ + 'error', + { + 'groups': [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + 'pathGroups': [ + { + pattern: 'react', + group: 'external', + position: 'before', + }, + { + pattern: 'react-native', + group: 'external', + position: 'before', + }, + { + pattern: '@src/**', + group: 'internal', + position: 'after', + }, + ], + 'pathGroupsExcludedImportTypes': ['react', 'react-native'], + 'newlines-between': 'always', + 'alphabetize': { + order: 'asc', + caseInsensitive: true, + }, + }, + ], 'no-restricted-imports': [ 'error', { @@ -38,9 +95,11 @@ export default defineConfig([ ignores: [ 'node_modules/', 'lib/', - 'expoConfig/build', - '.yarn', - 'eslint.config.mjs', + '.yarn/', + 'expoConfig/build/', + 'dist/', + 'android/', + 'ios/', ], }, ]); diff --git a/example/babel.config.js b/example/babel.config.js index 4f18b89..47cb96e 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -1,5 +1,7 @@ const path = require('path'); + const { getConfig } = require('react-native-builder-bob/babel-config'); + const pkg = require('../package.json'); const root = path.resolve(__dirname, '..'); @@ -7,7 +9,19 @@ const root = path.resolve(__dirname, '..'); module.exports = getConfig( { presets: ['module:@react-native/babel-preset'], - plugins: ['react-native-worklets/plugin'], + plugins: [ + [ + 'module-resolver', + { + root: ['./'], + alias: { + '@src': './src', + }, + extensions: ['.ts', '.tsx', '.js', '.jsx'], + }, + ], + 'react-native-worklets/plugin', + ], }, { root, pkg } ); diff --git a/example/eslint.config.mjs b/example/eslint.config.mjs new file mode 100644 index 0000000..14194a7 --- /dev/null +++ b/example/eslint.config.mjs @@ -0,0 +1,11 @@ +import rootConfig from '../eslint.config.mjs'; + +export default [ + ...rootConfig, + { + files: ['**/*.{js,jsx,ts,tsx}'], + rules: { + 'import/no-relative-parent-imports': 'error', + }, + }, +]; diff --git a/example/index.js b/example/index.js index 470a3ba..4c922fb 100644 --- a/example/index.js +++ b/example/index.js @@ -1,8 +1,9 @@ import { AppRegistry } from 'react-native'; -import App from './src/App'; -import { name as appName } from './app.json'; import { LogBox } from 'react-native'; +import { name as appName } from './app.json'; +import App from './src/App'; + LogBox.ignoreLogs(['InteractionManager has been deprecated']); AppRegistry.registerComponent(appName, () => App); diff --git a/example/metro.config.js b/example/metro.config.js index 2da198e..03cd5fe 100644 --- a/example/metro.config.js +++ b/example/metro.config.js @@ -1,4 +1,5 @@ const path = require('path'); + const { getDefaultConfig } = require('@react-native/metro-config'); const { withMetroConfig } = require('react-native-monorepo-config'); diff --git a/example/package.json b/example/package.json index 098f774..b46e3db 100644 --- a/example/package.json +++ b/example/package.json @@ -38,6 +38,7 @@ "@react-native/metro-config": "0.82.1", "@react-native/typescript-config": "0.82.1", "@types/react": "19.1.1", + "babel-plugin-module-resolver": "5.0.2", "react-native-builder-bob": "0.40.15", "react-native-monorepo-config": "0.3.0" }, diff --git a/example/react-native.config.js b/example/react-native.config.js index 59d9698..2b87ed5 100644 --- a/example/react-native.config.js +++ b/example/react-native.config.js @@ -1,4 +1,5 @@ const path = require('path'); + const pkg = require('../package.json'); module.exports = { diff --git a/example/src/App.tsx b/example/src/App.tsx index 16e85b2..39dd603 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,32 +1,34 @@ import React from 'react'; + +import { useColorScheme } from 'react-native'; + import { DarkTheme, DefaultTheme, NavigationContainer, } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; - -import HomeScreen from './screens/HomeScreen'; -import BasicMapScreen from './screens/BasicMapScreen'; -import MarkersScreen from './screens/MarkersScreen'; -import PolygonsScreen from './screens/PolygonsScreen'; -import PolylinesScreen from './screens/PolylinesScreen'; -import CirclesScreen from './screens/CirclesScreen'; -import HeatmapScreen from './screens/HeatmapScreen'; -import KmlLayerScreen from './screens/KmlLayerScreen'; -import LocationScreen from './screens/LocationScreen'; -import CustomStyleScreen from './screens/CustomStyleScreen'; -import StressTestScreen from './screens/StressTestScreen'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; -import { useColorScheme } from 'react-native'; -import BlankScreen from './screens/BlankScreen'; -import IndoorLevelMapScreen from './screens/IndoorLevelMapScreen'; -import CameraTestScreen from './screens/CameraTestScreen'; -import type { RootStackParamList } from './types/navigation'; -import SnapshotTestScreen from './screens/SnaptshotTestScreen'; -import ClusteringScreen from './screens/ClsuteringScreen'; -import SvgMarkersScreen from './screens/SvgMarkersScreen'; -import UrlTileOverlay from './screens/UrlTileOverlay'; + +import BasicMapScreen from '@src/screens/BasicMapScreen'; +import BlankScreen from '@src/screens/BlankScreen'; +import CameraTestScreen from '@src/screens/CameraTestScreen'; +import CirclesScreen from '@src/screens/CirclesScreen'; +import ClusteringScreen from '@src/screens/ClsuteringScreen'; +import CustomStyleScreen from '@src/screens/CustomStyleScreen'; +import HeatmapScreen from '@src/screens/HeatmapScreen'; +import HomeScreen from '@src/screens/HomeScreen'; +import IndoorLevelMapScreen from '@src/screens/IndoorLevelMapScreen'; +import KmlLayerScreen from '@src/screens/KmlLayerScreen'; +import LocationScreen from '@src/screens/LocationScreen'; +import MarkersScreen from '@src/screens/MarkersScreen'; +import PolygonsScreen from '@src/screens/PolygonsScreen'; +import PolylinesScreen from '@src/screens/PolylinesScreen'; +import SnapshotTestScreen from '@src/screens/SnaptshotTestScreen'; +import StressTestScreen from '@src/screens/StressTestScreen'; +import SvgMarkersScreen from '@src/screens/SvgMarkersScreen'; +import UrlTileOverlay from '@src/screens/UrlTileOverlay'; +import type { RootStackParamList } from '@src/types/navigation'; const Stack = createStackNavigator(); diff --git a/example/src/components/ControlPanel.tsx b/example/src/components/ControlPanel.tsx index 60c6f1a..c33ee70 100644 --- a/example/src/components/ControlPanel.tsx +++ b/example/src/components/ControlPanel.tsx @@ -1,4 +1,5 @@ import React, { useMemo } from 'react'; + import { ScrollView, StyleSheet, @@ -6,6 +7,8 @@ import { TouchableOpacity, View, } from 'react-native'; + +import { useNavigation } from '@react-navigation/native'; import Animated, { Extrapolation, interpolate, @@ -13,15 +16,16 @@ import Animated, { useSharedValue, withTiming, } from 'react-native-reanimated'; -import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; -import { useAppTheme } from '../hooks/useAppTheme'; -import { useNavigation } from '@react-navigation/native'; -import type { RootNavigationProp } from '../types/navigation'; import { type EdgeInsets, useSafeAreaInsets, } from 'react-native-safe-area-context'; -import type { AppTheme } from '../theme'; + +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; +import type { RootNavigationProp } from '@src/types/navigation'; + +import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; export type ButtonItem = { title: string; onPress: () => void }; diff --git a/example/src/components/HeaderButton.tsx b/example/src/components/HeaderButton.tsx index 69ca230..1354fe8 100644 --- a/example/src/components/HeaderButton.tsx +++ b/example/src/components/HeaderButton.tsx @@ -1,7 +1,9 @@ import React, { useMemo } from 'react'; + import { Pressable, StyleSheet, Text } from 'react-native'; -import { useAppTheme } from '../hooks/useAppTheme'; -import type { AppTheme } from '../theme'; + +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; type Props = { title: string; diff --git a/example/src/components/maptConfigDialog/MapConfigDialog.tsx b/example/src/components/MapConfigDialog.tsx similarity index 97% rename from example/src/components/maptConfigDialog/MapConfigDialog.tsx rename to example/src/components/MapConfigDialog.tsx index 39bd26a..53f717c 100644 --- a/example/src/components/maptConfigDialog/MapConfigDialog.tsx +++ b/example/src/components/MapConfigDialog.tsx @@ -1,4 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; + import { View, Text, @@ -10,14 +11,16 @@ import { KeyboardAvoidingView, Platform, } from 'react-native'; + import { type Struct, validate } from 'superstruct'; -import { useAppTheme } from '../../hooks/useAppTheme'; + +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; import { formatSuperstructError, parseWithUndefined, stringifyWithUndefined, -} from './utils'; -import type { AppTheme } from '../../theme'; +} from '@src/utils/validatorUtils'; type Props = { visible: boolean; diff --git a/example/src/components/MapWrapper.tsx b/example/src/components/MapWrapper.tsx index be81ccf..75ef4bc 100644 --- a/example/src/components/MapWrapper.tsx +++ b/example/src/components/MapWrapper.tsx @@ -1,6 +1,20 @@ import React, { useMemo, useState } from 'react'; + import type { ViewProps } from 'react-native'; import { ActivityIndicator, StyleSheet, View } from 'react-native'; + +import { + GoogleMapsView, + RNAndroidLocationPriority, + RNIOSLocationAccuracy, + RNIOSLocationActivityType, +} from 'react-native-google-maps-plus'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; + +import { useAppTheme } from '@src/hooks/useAppTheme'; +import { useMapCallbacks } from '@src/hooks/useMapCallbacks'; +import type { AppTheme } from '@src/theme'; + import type { GoogleMapsViewRef, RNGoogleMapsPlusViewProps, @@ -10,16 +24,6 @@ import type { RNMapUiSettings, RNMapZoomConfig, } from 'react-native-google-maps-plus'; -import { - GoogleMapsView, - RNAndroidLocationPriority, - RNIOSLocationAccuracy, - RNIOSLocationActivityType, -} from 'react-native-google-maps-plus'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import type { AppTheme } from '../theme'; -import { useAppTheme } from '../hooks/useAppTheme'; -import { useMapCallbacks } from '../hooks/useMapCallbacks'; type Props = ViewProps & RNGoogleMapsPlusViewProps & { @@ -65,8 +69,8 @@ export default function MapWrapper(props: Props) { const mapPadding: RNMapPadding = useMemo(() => { return props.children - ? { top: 20, left: 20, bottom: layout.bottom + 80, right: 20 } - : { top: 20, left: 20, bottom: layout.bottom, right: 20 }; + ? { top: 0, left: 0, bottom: layout.bottom + 70, right: 0 } + : { top: 0, left: 0, bottom: layout.bottom, right: 0 }; }, [layout.bottom, props.children]); const mapZoomConfig: RNMapZoomConfig = useMemo( diff --git a/example/src/utils/heatMapWeightData.ts b/example/src/data/heatMapWeightData.ts similarity index 100% rename from example/src/utils/heatMapWeightData.ts rename to example/src/data/heatMapWeightData.ts diff --git a/example/src/utils/kmlData.ts b/example/src/data/kmlData.ts similarity index 100% rename from example/src/utils/kmlData.ts rename to example/src/data/kmlData.ts diff --git a/example/src/utils/mapStyles.ts b/example/src/data/mapStylesData.ts similarity index 100% rename from example/src/utils/mapStyles.ts rename to example/src/data/mapStylesData.ts diff --git a/example/src/hooks/useAppTheme.tsx b/example/src/hooks/useAppTheme.tsx index 98b0514..47c764c 100644 --- a/example/src/hooks/useAppTheme.tsx +++ b/example/src/hooks/useAppTheme.tsx @@ -1,5 +1,6 @@ import { useColorScheme } from 'react-native'; -import { type AppTheme, darkTheme, lightTheme } from '../theme'; + +import { type AppTheme, darkTheme, lightTheme } from '@src/theme'; export function useAppTheme(): AppTheme { const scheme = useColorScheme(); diff --git a/example/src/hooks/useHeaderButton.tsx b/example/src/hooks/useHeaderButton.tsx index cd39644..23672fe 100644 --- a/example/src/hooks/useHeaderButton.tsx +++ b/example/src/hooks/useHeaderButton.tsx @@ -1,7 +1,8 @@ import { useCallback, useLayoutEffect } from 'react'; -import HeaderButton from '../components/HeaderButton'; import React from 'react'; +import HeaderButton from '@src/components/HeaderButton'; + export function useHeaderButton( navigation: any, title: string, diff --git a/example/src/hooks/useMapCallbacks.ts b/example/src/hooks/useMapCallbacks.ts index 8e1435c..2fb3775 100644 --- a/example/src/hooks/useMapCallbacks.ts +++ b/example/src/hooks/useMapCallbacks.ts @@ -1,4 +1,5 @@ import React, { useCallback } from 'react'; + import { type GoogleMapsViewRef, type RNCamera, @@ -11,7 +12,8 @@ import { RNMapErrorCode, type RNRegion, } from 'react-native-google-maps-plus'; -import { useNitroCallback } from './useNitroCallback'; + +import { useNitroCallback } from '@src/hooks/useNitroCallback'; export function useMapCallbacks( props: RNGoogleMapsPlusViewProps, diff --git a/example/src/hooks/useNitroCallback.ts b/example/src/hooks/useNitroCallback.ts index 5d3b999..947e947 100644 --- a/example/src/hooks/useNitroCallback.ts +++ b/example/src/hooks/useNitroCallback.ts @@ -1,5 +1,7 @@ import { useMemo } from 'react'; + import { callback } from 'react-native-nitro-modules'; + export function useNitroCallback void>( propCallback: T | undefined, fallback?: (...args: Parameters) => void diff --git a/example/src/screens/BasicMapScreen.tsx b/example/src/screens/BasicMapScreen.tsx index 042b6b1..ec81eab 100644 --- a/example/src/screens/BasicMapScreen.tsx +++ b/example/src/screens/BasicMapScreen.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; -import ControlPanel from '../components/ControlPanel'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import type { RNBasicMapConfig } from '../types/basicMapConfig'; + import { useNavigation } from '@react-navigation/native'; -import { RNBasicMapConfigValidator } from '../components/maptConfigDialog/validator'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { useHeaderButton } from '../hooks/useHeaderButton'; -import { useAppTheme } from '../hooks/useAppTheme'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useAppTheme } from '@src/hooks/useAppTheme'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import type { RNBasicMapConfig } from '@src/types/basicMapConfig'; +import { RNBasicMapConfigValidator } from '@src/utils/validator'; + +import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; export default function BasicMapScreen() { const mapRef = useRef(null); @@ -47,7 +50,7 @@ export default function BasicMapScreen() { indoorEnabled: undefined, customMapStyle: undefined, mapZoomConfig: { min: 0, max: 20 }, - mapPadding: { top: 20, left: 20, bottom: layout.bottom + 80, right: 20 }, + mapPadding: { top: 0, left: 0, bottom: layout.bottom + 70, right: 0 }, mapType: 'normal', }); diff --git a/example/src/screens/BlankScreen.tsx b/example/src/screens/BlankScreen.tsx index 51e557c..3f21294 100644 --- a/example/src/screens/BlankScreen.tsx +++ b/example/src/screens/BlankScreen.tsx @@ -1,9 +1,12 @@ import React, { useMemo } from 'react'; + import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; + import { useNavigation } from '@react-navigation/native'; -import type { RootNavigationProp } from '../types/navigation'; -import { useAppTheme } from '../hooks/useAppTheme'; -import type { AppTheme } from '../theme'; + +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; +import type { RootNavigationProp } from '@src/types/navigation'; export default function BlankScreen() { const navigation = useNavigation(); diff --git a/example/src/screens/CameraTestScreen.tsx b/example/src/screens/CameraTestScreen.tsx index 572866a..25599ee 100644 --- a/example/src/screens/CameraTestScreen.tsx +++ b/example/src/screens/CameraTestScreen.tsx @@ -1,6 +1,8 @@ import React, { useMemo, useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import ControlPanel from '../components/ControlPanel'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapWrapper from '@src/components/MapWrapper'; + import type { GoogleMapsViewRef, RNCameraUpdate, diff --git a/example/src/screens/CirclesScreen.tsx b/example/src/screens/CirclesScreen.tsx index 5527dd4..240e65f 100644 --- a/example/src/screens/CirclesScreen.tsx +++ b/example/src/screens/CirclesScreen.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { makeCircle } from '../utils/mapGenerators'; + +import { useNavigation } from '@react-navigation/native'; + +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { makeCircle } from '@src/utils/mapGenerators'; +import { RNCircleValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNCircle, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNCircleValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; export default function CirclesScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/ClsuteringScreen.tsx b/example/src/screens/ClsuteringScreen.tsx index 546d2a9..049344a 100644 --- a/example/src/screens/ClsuteringScreen.tsx +++ b/example/src/screens/ClsuteringScreen.tsx @@ -1,16 +1,19 @@ import React, { useRef, useState, useMemo, useCallback } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import ControlPanel from '../components/ControlPanel'; + +import { useClusterer } from 'react-native-clusterer'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapWrapper from '@src/components/MapWrapper'; +import { randomCoordinates } from '@src/utils/mapGenerators'; +import { rnRegionToRegion } from '@src/utils/mapUtils'; + +import type { Supercluster } from 'react-native-clusterer'; import type { GoogleMapsViewRef, RNMarker, RNMarkerSvg, RNRegion, } from 'react-native-google-maps-plus'; -import type { Supercluster } from 'react-native-clusterer'; -import { useClusterer } from 'react-native-clusterer'; -import { randomCoordinates } from '../utils/mapGenerators'; -import { rnRegionToRegion } from '../utils/mapUtils'; export default function ClusteringScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/CustomStyleScreen.tsx b/example/src/screens/CustomStyleScreen.tsx index f61a45d..f852585 100644 --- a/example/src/screens/CustomStyleScreen.tsx +++ b/example/src/screens/CustomStyleScreen.tsx @@ -1,7 +1,9 @@ import React, { useMemo, useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import ControlPanel from '../components/ControlPanel'; -import { silverMapStyle, standardMapStyle } from '../utils/mapStyles'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapWrapper from '@src/components/MapWrapper'; +import { silverMapStyle, standardMapStyle } from '@src/data/mapStylesData'; + import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; export default function CustomStyleScreen() { diff --git a/example/src/screens/HeatmapScreen.tsx b/example/src/screens/HeatmapScreen.tsx index 565d31c..8744d0f 100644 --- a/example/src/screens/HeatmapScreen.tsx +++ b/example/src/screens/HeatmapScreen.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { makeHeatmap } from '../utils/mapGenerators'; + +import { useNavigation } from '@react-navigation/native'; + +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { makeHeatmap } from '@src/utils/mapGenerators'; +import { RNHeatmapValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNHeatmap, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNHeatmapValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; export default function HeatmapScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/HomeScreen.tsx b/example/src/screens/HomeScreen.tsx index 47dc544..96b1f8b 100644 --- a/example/src/screens/HomeScreen.tsx +++ b/example/src/screens/HomeScreen.tsx @@ -1,17 +1,20 @@ import React, { useMemo } from 'react'; + import { ScrollView, StyleSheet, Text, TouchableOpacity } from 'react-native'; + import { useNavigation } from '@react-navigation/native'; -import { useAppTheme } from '../hooks/useAppTheme'; -import type { AppTheme } from '../theme'; -import type { - RootNavigationProp, - RootStackParamList, -} from '../types/navigation'; import { type EdgeInsets, useSafeAreaInsets, } from 'react-native-safe-area-context'; +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; +import type { + RootNavigationProp, + RootStackParamList, +} from '@src/types/navigation'; + const screens = [ { name: 'BasicMap', title: 'Basic Map' }, { name: 'Markers', title: 'Markers' }, diff --git a/example/src/screens/IndoorLevelMapScreen.tsx b/example/src/screens/IndoorLevelMapScreen.tsx index 6e09919..0865db9 100644 --- a/example/src/screens/IndoorLevelMapScreen.tsx +++ b/example/src/screens/IndoorLevelMapScreen.tsx @@ -1,7 +1,9 @@ import React, { useRef } from 'react'; -import MapWrapper from '../components/MapWrapper'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapWrapper from '@src/components/MapWrapper'; + import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; -import ControlPanel from '../components/ControlPanel'; export default function IndoorLevelMapScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/KmlLayerScreen.tsx b/example/src/screens/KmlLayerScreen.tsx index 35852ad..cbdd071 100644 --- a/example/src/screens/KmlLayerScreen.tsx +++ b/example/src/screens/KmlLayerScreen.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { kmlString } from '../utils/kmlData'; + +import { useNavigation } from '@react-navigation/native'; + +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { kmlString } from '@src/data/kmlData'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { RNKMLayerValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNKMLayer, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNKMLayerValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; export default function KmlLayerScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/LocationScreen.tsx b/example/src/screens/LocationScreen.tsx index e51c6a5..c257091 100644 --- a/example/src/screens/LocationScreen.tsx +++ b/example/src/screens/LocationScreen.tsx @@ -1,6 +1,6 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import ControlPanel from '../components/ControlPanel'; + +import { useNavigation } from '@react-navigation/native'; import { type GoogleMapsViewRef, RNAndroidLocationPriority, @@ -8,10 +8,12 @@ import { RNIOSLocationActivityType, type RNLocationConfig, } from 'react-native-google-maps-plus'; -import { RNLocationConfigValidator } from '../components/maptConfigDialog/validator'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useHeaderButton } from '../hooks/useHeaderButton'; -import { useNavigation } from '@react-navigation/native'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { RNLocationConfigValidator } from '@src/utils/validator'; export default function LocationScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/MarkersScreen.tsx b/example/src/screens/MarkersScreen.tsx index 9371475..034d3e6 100644 --- a/example/src/screens/MarkersScreen.tsx +++ b/example/src/screens/MarkersScreen.tsx @@ -1,17 +1,20 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { makeMarker } from '../utils/mapGenerators'; + +import { useNavigation } from '@react-navigation/native'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { makeMarker } from '@src/utils/mapGenerators'; +import { RNMarkerValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNLatLng, RNMarker, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNMarkerValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; import type { RNMapUiSettings } from 'react-native-google-maps-plus'; -import ControlPanel from '../components/ControlPanel'; export function animateSpiral( center: RNLatLng, diff --git a/example/src/screens/PolygonsScreen.tsx b/example/src/screens/PolygonsScreen.tsx index 64008e4..ace865d 100644 --- a/example/src/screens/PolygonsScreen.tsx +++ b/example/src/screens/PolygonsScreen.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { makePolygon } from '../utils/mapGenerators'; + +import { useNavigation } from '@react-navigation/native'; + +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { makePolygon } from '@src/utils/mapGenerators'; +import { RNPolygonValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNPolygon, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNPolygonValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; export default function PolygonsScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/PolylinesScreen.tsx b/example/src/screens/PolylinesScreen.tsx index 234c0da..6f1e1e8 100644 --- a/example/src/screens/PolylinesScreen.tsx +++ b/example/src/screens/PolylinesScreen.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { makePolyline } from '../utils/mapGenerators'; + +import { useNavigation } from '@react-navigation/native'; + +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { makePolyline } from '@src/utils/mapGenerators'; +import { RNPolylineValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNPolyline, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNPolylineValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; export default function PolylinesScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/SnaptshotTestScreen.tsx b/example/src/screens/SnaptshotTestScreen.tsx index 7468c27..b07727f 100644 --- a/example/src/screens/SnaptshotTestScreen.tsx +++ b/example/src/screens/SnaptshotTestScreen.tsx @@ -1,10 +1,13 @@ import React, { useMemo, useRef, useState } from 'react'; + import { Image, Modal, Pressable, StyleSheet, Text, View } from 'react-native'; -import MapWrapper from '../components/MapWrapper'; -import ControlPanel from '../components/ControlPanel'; -import { useAppTheme } from '../hooks/useAppTheme'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapWrapper from '@src/components/MapWrapper'; +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; + import type { GoogleMapsViewRef } from 'react-native-google-maps-plus'; -import type { AppTheme } from '../theme'; export default function SnapshotTestScreen() { const mapRef = useRef(null); diff --git a/example/src/screens/StressTestScreen.tsx b/example/src/screens/StressTestScreen.tsx index 12a1fc2..c26fb69 100644 --- a/example/src/screens/StressTestScreen.tsx +++ b/example/src/screens/StressTestScreen.tsx @@ -1,7 +1,9 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import ControlPanel from '../components/ControlPanel'; -import { makeRandomMarkerForStressTest } from '../utils/mapGenerators'; + +import ControlPanel from '@src/components/ControlPanel'; +import MapWrapper from '@src/components/MapWrapper'; +import { makeRandomMarkerForStressTest } from '@src/utils/mapGenerators'; + import type { GoogleMapsViewRef, RNMarker, diff --git a/example/src/screens/SvgMarkersScreen.tsx b/example/src/screens/SvgMarkersScreen.tsx index 8daf6a6..fa7a302 100644 --- a/example/src/screens/SvgMarkersScreen.tsx +++ b/example/src/screens/SvgMarkersScreen.tsx @@ -1,6 +1,8 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; -import { randomCoordinates } from '../utils/mapGenerators'; + +import MapWrapper from '@src/components/MapWrapper'; +import { randomCoordinates } from '@src/utils/mapGenerators'; + import type { GoogleMapsViewRef, RNMarker, diff --git a/example/src/screens/UrlTileOverlay.tsx b/example/src/screens/UrlTileOverlay.tsx index 961ce49..782fee4 100644 --- a/example/src/screens/UrlTileOverlay.tsx +++ b/example/src/screens/UrlTileOverlay.tsx @@ -1,14 +1,17 @@ import React, { useRef, useState } from 'react'; -import MapWrapper from '../components/MapWrapper'; + +import { useNavigation } from '@react-navigation/native'; + +import MapConfigDialog from '@src/components/MapConfigDialog'; +import MapWrapper from '@src/components/MapWrapper'; +import { useHeaderButton } from '@src/hooks/useHeaderButton'; +import { makeUrlTileOverlay } from '@src/utils/mapGenerators'; +import { RNUrlTileOverlayValidator } from '@src/utils/validator'; + import type { GoogleMapsViewRef, RNUrlTileOverlay, } from 'react-native-google-maps-plus'; -import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog'; -import { useNavigation } from '@react-navigation/native'; -import { RNUrlTileOverlayValidator } from '../components/maptConfigDialog/validator'; -import { useHeaderButton } from '../hooks/useHeaderButton'; -import { makeUrlTileOverlay } from '../utils/mapGenerators'; export default function UrlTileOverlay() { const mapRef = useRef(null); diff --git a/example/src/utils/mapGenerators.ts b/example/src/utils/mapGenerators.ts index 79bd672..84bad73 100644 --- a/example/src/utils/mapGenerators.ts +++ b/example/src/utils/mapGenerators.ts @@ -1,3 +1,5 @@ +import { weightData } from '@src/data/heatMapWeightData'; + import type { RNCircle, RNHeatmap, @@ -6,7 +8,6 @@ import type { RNPolyline, RNUrlTileOverlay, } from 'react-native-google-maps-plus'; -import { weightData } from './heatMapWeightData'; export function randomColor() { return ( diff --git a/example/src/components/maptConfigDialog/validator.ts b/example/src/utils/validator.ts similarity index 99% rename from example/src/components/maptConfigDialog/validator.ts rename to example/src/utils/validator.ts index 2998da4..d741698 100644 --- a/example/src/components/maptConfigDialog/validator.ts +++ b/example/src/utils/validator.ts @@ -1,3 +1,12 @@ +import { + RNAndroidLocationPermissionResult, + RNAndroidLocationPriority, + RNIOSLocationAccuracy, + RNIOSLocationActivityType, + RNIOSPermissionResult, + RNLocationErrorCode, + RNMapErrorCode, +} from 'react-native-google-maps-plus'; import { array, boolean, @@ -11,16 +20,6 @@ import { union, } from 'superstruct'; -import { - RNAndroidLocationPermissionResult, - RNAndroidLocationPriority, - RNIOSLocationAccuracy, - RNIOSLocationActivityType, - RNIOSPermissionResult, - RNLocationErrorCode, - RNMapErrorCode, -} from 'react-native-google-maps-plus'; - const enumValues = (e: T): T[keyof T][] => Object.values(e).filter( (v): v is T[keyof T] => typeof v === 'number' || typeof v === 'string' diff --git a/example/src/components/maptConfigDialog/utils.ts b/example/src/utils/validatorUtils.ts similarity index 100% rename from example/src/components/maptConfigDialog/utils.ts rename to example/src/utils/validatorUtils.ts diff --git a/example/tsconfig.json b/example/tsconfig.json index 28026a9..3011e88 100644 --- a/example/tsconfig.json +++ b/example/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "baseUrl": ".", "paths": { + "@src/*": ["src/*"], "react-native-google-maps-plus": ["../src"] } }, diff --git a/expoConfig/src/android/withAndroidGoogleMapsPlus.ts b/expoConfig/src/android/withAndroidGoogleMapsPlus.ts index ecabae3..1ed68f2 100644 --- a/expoConfig/src/android/withAndroidGoogleMapsPlus.ts +++ b/expoConfig/src/android/withAndroidGoogleMapsPlus.ts @@ -1,11 +1,12 @@ import { withAndroidManifest } from '@expo/config-plugins'; -import type { ConfigPlugin } from '@expo/config-plugins'; import { addMetaDataItemToMainApplication, getMainApplicationOrThrow, removeMetaDataItemFromMainApplication, } from '@expo/config-plugins/build/android/Manifest'; + import type { RNGoogleMapsPlusExpoPluginProps } from '../types'; +import type { ConfigPlugin } from '@expo/config-plugins'; const withMapsAndroid: ConfigPlugin = ( config, diff --git a/expoConfig/src/index.ts b/expoConfig/src/index.ts index 17662f1..649e4aa 100644 --- a/expoConfig/src/index.ts +++ b/expoConfig/src/index.ts @@ -1,16 +1,18 @@ -import type { ConfigPlugin } from '@expo/config-plugins'; -import type { RNGoogleMapsPlusExpoPluginProps } from './types'; import fs from 'fs'; import path from 'path'; +import { createRunOncePlugin } from '@expo/config-plugins'; + +import withAndroidGoogleMapsPlus from './android/withAndroidGoogleMapsPlus'; +import withIosGoogleMapsPlus from './ios/withIosGoogleMapsPlus'; + +import type { RNGoogleMapsPlusExpoPluginProps } from './types'; +import type { ConfigPlugin } from '@expo/config-plugins'; + const pkg = JSON.parse( fs.readFileSync(path.resolve(__dirname, '../../package.json'), 'utf8') ); -import { createRunOncePlugin } from '@expo/config-plugins'; -import withIosGoogleMapsPlus from './ios/withIosGoogleMapsPlus'; -import withAndroidGoogleMapsPlus from './android/withAndroidGoogleMapsPlus'; - const withGoogleMapsPlus: ConfigPlugin = ( config, props diff --git a/expoConfig/src/ios/withIosGoogleMapsPlus.ts b/expoConfig/src/ios/withIosGoogleMapsPlus.ts index 3d1f4ec..d0a8d32 100644 --- a/expoConfig/src/ios/withIosGoogleMapsPlus.ts +++ b/expoConfig/src/ios/withIosGoogleMapsPlus.ts @@ -5,6 +5,7 @@ import { type ConfigPlugin, } from '@expo/config-plugins'; import { mergeContents } from '@expo/config-plugins/build/utils/generateCode'; + import type { RNGoogleMapsPlusExpoPluginProps } from '../types'; const withIosGoogleMapsPlus: ConfigPlugin = ( diff --git a/package.json b/package.json index 1eb72c8..241c573 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "lint:android": "cd android && ktlint -F ./**/*.kt*", "lint:ios": "cd ios && swiftlint --quiet && swiftformat . --lint", "format": "yarn format:js && yarn format:ios && yarn format:android", - "format:js": "prettier --write .", + "format:js": "eslint . --fix && prettier --write .", "format:android": "cd android && ktlint --format ./**/*.kt*", "format:ios": "cd ios && swiftformat .", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", @@ -95,8 +95,10 @@ "del-cli": "7.0.0", "eslint": "9.39.1", "eslint-config-prettier": "10.1.8", - "eslint-plugin-ft-flow": "3.0.11", + "eslint-import-resolver-typescript": "4.4.4", + "eslint-plugin-import": "2.32.0", "eslint-plugin-prettier": "5.5.4", + "eslint-plugin-unused-imports": "4.3.0", "jest": "30.2.0", "lefthook": "2.0.3", "nitrogen": "0.31.6", diff --git a/scripts/nitrogen-patch.js b/scripts/nitrogen-patch.js index 7d5404d..0dea063 100644 --- a/scripts/nitrogen-patch.js +++ b/scripts/nitrogen-patch.js @@ -12,11 +12,11 @@ * - Inserts `+ (BOOL)shouldBeRecycled` * nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm */ -import { fileURLToPath } from 'url'; -import { basename } from 'path'; -import path from 'node:path'; import { readdir, readFile, writeFile } from 'node:fs/promises'; import { mkdir, copyFile } from 'node:fs/promises'; +import path from 'node:path'; +import { basename } from 'path'; +import { fileURLToPath } from 'url'; const ROOT_ANDROID = path.join( process.cwd(), diff --git a/src/GoogleMapsPlus.tsx b/src/GoogleMapsPlus.tsx index 9d194f9..71b6eed 100644 --- a/src/GoogleMapsPlus.tsx +++ b/src/GoogleMapsPlus.tsx @@ -2,13 +2,12 @@ import { getHostComponent, NitroModules } from 'react-native-nitro-modules'; import ViewConfig from '../nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json' with { type: 'json' }; +import type { RNGoogleMapsPlusModule } from './RNGoogleMapsPlusModule.nitro.js'; import type { RNGoogleMapsPlusViewMethods, RNGoogleMapsPlusViewProps, } from './RNGoogleMapsPlusView.nitro.js'; -import type { RNGoogleMapsPlusModule } from './RNGoogleMapsPlusModule.nitro.js'; - export const GoogleMapsView = getHostComponent< RNGoogleMapsPlusViewProps, RNGoogleMapsPlusViewMethods diff --git a/src/RNGoogleMapsPlusModule.nitro.ts b/src/RNGoogleMapsPlusModule.nitro.ts index 641323c..131e80a 100644 --- a/src/RNGoogleMapsPlusModule.nitro.ts +++ b/src/RNGoogleMapsPlusModule.nitro.ts @@ -1,4 +1,5 @@ import { type HybridObject } from 'react-native-nitro-modules'; + import type { RNLocationPermissionResult } from './types'; export interface RNGoogleMapsPlusModule diff --git a/src/RNGoogleMapsPlusView.nitro.ts b/src/RNGoogleMapsPlusView.nitro.ts index 0effa07..0d12b58 100644 --- a/src/RNGoogleMapsPlusView.nitro.ts +++ b/src/RNGoogleMapsPlusView.nitro.ts @@ -1,8 +1,3 @@ -import type { - HybridView, - HybridViewMethods, - HybridViewProps, -} from 'react-native-nitro-modules'; import type { RNCamera, RNCameraUpdate, @@ -31,6 +26,11 @@ import type { RNSnapshotOptions, RNUrlTileOverlay, } from './types'; +import type { + HybridView, + HybridViewMethods, + HybridViewProps, +} from 'react-native-nitro-modules'; export interface RNGoogleMapsPlusViewProps extends HybridViewProps { initialProps?: RNInitialProps; diff --git a/src/index.tsx b/src/index.tsx index 2a24f2c..c3741e2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,10 @@ import { GoogleMapsView, GoogleMapsModule } from './GoogleMapsPlus'; + +import type { RNGoogleMapsPlusModule } from './RNGoogleMapsPlusModule.nitro'; import type { RNGoogleMapsPlusViewMethods, RNGoogleMapsPlusViewProps, } from './RNGoogleMapsPlusView.nitro'; -import type { RNGoogleMapsPlusModule } from './RNGoogleMapsPlusModule.nitro'; export * from './types'; diff --git a/yarn.lock b/yarn.lock index 0eef235..ec9686e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,12 +41,12 @@ __metadata: languageName: node linkType: hard -"@ark/schema@npm:0.53.0": - version: 0.53.0 - resolution: "@ark/schema@npm:0.53.0" +"@ark/schema@npm:0.54.0": + version: 0.54.0 + resolution: "@ark/schema@npm:0.54.0" dependencies: - "@ark/util": 0.53.0 - checksum: bea15e638bf63f56dee9a2bdeaf746232dd2c4b25663e47538376aa14d25a45b519f84271af9155b2618529cb4ad6701399e1f01153e3386cd3c38629ffc4c88 + "@ark/util": 0.54.0 + checksum: e77bcb66774d0cb1a648d5b7ba5885358de3c12d6dcbec3b8f6861e92ee330d9cb8732f61afef7c88a1fd8e227eb8dec62d56e2040859cef13c0f023536830f4 languageName: node linkType: hard @@ -57,6 +57,13 @@ __metadata: languageName: node linkType: hard +"@ark/util@npm:0.54.0": + version: 0.54.0 + resolution: "@ark/util@npm:0.54.0" + checksum: 76f648b2eb42c0bf7c45d8792f4459bd560067681d26fc55e887ef26d8a04a5b4e548d38be36c9f09d21a76a3838836e6342be04f26b0b91943724782b10503c + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.24.7, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.27.1": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" @@ -2674,18 +2681,18 @@ __metadata: linkType: hard "@npmcli/git@npm:^7.0.0": - version: 7.0.0 - resolution: "@npmcli/git@npm:7.0.0" + version: 7.0.1 + resolution: "@npmcli/git@npm:7.0.1" dependencies: - "@npmcli/promise-spawn": ^8.0.0 - ini: ^5.0.0 + "@npmcli/promise-spawn": ^9.0.0 + ini: ^6.0.0 lru-cache: ^11.2.1 npm-pick-manifest: ^11.0.1 - proc-log: ^5.0.0 + proc-log: ^6.0.0 promise-retry: ^2.0.1 semver: ^7.3.5 - which: ^5.0.0 - checksum: 9ff9d79a8d719755b0f713ec619720c1f29d7a0737a9b871103dd608055d297ade46bb8a100428a81ccb8c4f1ca6964eb9450a6389e175849e922297afeb58ed + which: ^6.0.0 + checksum: 7874ebf952c35b33d9719924996bf033897c63b21fc4ec8b039a852d724048b5f417a5d1ac6a623a6d40e05c56b27f4a3dfe47d5774e9ce88a924903d34f76cd languageName: node linkType: hard @@ -2701,6 +2708,18 @@ __metadata: languageName: node linkType: hard +"@npmcli/installed-package-contents@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/installed-package-contents@npm:4.0.0" + dependencies: + npm-bundled: ^5.0.0 + npm-normalize-package-bin: ^5.0.0 + bin: + installed-package-contents: bin/index.js + checksum: c94aa13d9f80849221b2bd4eb06f9b7db65dac74ac6176f2dbcba6810c4083240dacddb293a38cfcd5d8c09932aef983b7e01ef434e53d63416a5e8471804fdd + languageName: node + linkType: hard + "@npmcli/map-workspaces@npm:^5.0.0": version: 5.0.1 resolution: "@npmcli/map-workspaces@npm:5.0.1" @@ -2769,7 +2788,7 @@ __metadata: languageName: node linkType: hard -"@npmcli/promise-spawn@npm:^8.0.0, @npmcli/promise-spawn@npm:^8.0.3": +"@npmcli/promise-spawn@npm:^8.0.3": version: 8.0.3 resolution: "@npmcli/promise-spawn@npm:8.0.3" dependencies: @@ -2779,11 +2798,11 @@ __metadata: linkType: hard "@npmcli/promise-spawn@npm:^9.0.0": - version: 9.0.0 - resolution: "@npmcli/promise-spawn@npm:9.0.0" + version: 9.0.1 + resolution: "@npmcli/promise-spawn@npm:9.0.1" dependencies: - which: ^5.0.0 - checksum: 79e9838abf57391e0345253cf0b3d2b1f22ac48bb86a8b542486f41c5b52e2d6f48dd5944775542c90f9da33f0b06868023c1b37ca9f9336a265858a546757c9 + which: ^6.0.0 + checksum: 0b193c58408421b5eb07808efde4a6674a977f7d9ced63b28e90d9a6e238522f1776ed4a9f4b6b5455eb2c497eccf8ab82ea94f3cd41140fceca794763bb3e35 languageName: node linkType: hard @@ -2803,17 +2822,24 @@ __metadata: languageName: node linkType: hard +"@npmcli/redact@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/redact@npm:4.0.0" + checksum: 4e029c44a8593304bb1aa5a8f1559cb8f37b4dc3880c589ce546da0b8cfa741d16a054db38ee309e81c2120c148ba33edbb3252f97a78b3234ba9ab3fa3e176c + languageName: node + linkType: hard + "@npmcli/run-script@npm:^10.0.0": - version: 10.0.2 - resolution: "@npmcli/run-script@npm:10.0.2" + version: 10.0.3 + resolution: "@npmcli/run-script@npm:10.0.3" dependencies: "@npmcli/node-gyp": ^5.0.0 "@npmcli/package-json": ^7.0.0 "@npmcli/promise-spawn": ^9.0.0 - node-gyp: ^11.0.0 + node-gyp: ^12.1.0 proc-log: ^6.0.0 - which: ^5.0.0 - checksum: 4f5aacc872974422be5d79f68f298d97c52a985b9e200c7b8df05da072080bcf3c1519e92321e88e21131175c13404f6acc5d4e8c42510a1041da61be56bb17d + which: ^6.0.0 + checksum: 309c1e3caadd66cbae0f255adf05afde3e49f073e6fd316e0709ba378862ca18737c6ced52444ff2f242683cc41ec8fe26af5571d217c378c0247e1e5f2d2ba8 languageName: node linkType: hard @@ -2904,24 +2930,24 @@ __metadata: linkType: hard "@octokit/request-error@npm:^7.0.2": - version: 7.0.2 - resolution: "@octokit/request-error@npm:7.0.2" + version: 7.1.0 + resolution: "@octokit/request-error@npm:7.1.0" dependencies: "@octokit/types": ^16.0.0 - checksum: 8edfaca9f5271115b090f470ebfe1006841ee152dd52cb39786e026236e2c13545aa3cf3187b7b1de717167696a42f91d8fa2f870bf9be0832fb2b11d11a741d + checksum: c1d447ff7482382c69f7a4b2eaa44c672906dd111d8a9196a5d07f2adc4ae0f0e12ec4ce0063f14f9b2fb5f0cef4451c95ec961a7a711bd900e5d6441d546570 languageName: node linkType: hard "@octokit/request@npm:^10.0.6": - version: 10.0.6 - resolution: "@octokit/request@npm:10.0.6" + version: 10.0.7 + resolution: "@octokit/request@npm:10.0.7" dependencies: "@octokit/endpoint": ^11.0.2 "@octokit/request-error": ^7.0.2 "@octokit/types": ^16.0.0 fast-content-type-parse: ^3.0.0 universal-user-agent: ^7.0.2 - checksum: bdb164dad47f27fceb49ee117b21bb845c0f61a2e00918008f097135c84951e7af1d85871b2c3de08239f6372dddaea759366bf306de85f0f8e158a26bebf450 + checksum: 5fc482dfea7c90bdb3c598dda26c410e776fd399328e5b355be07e1a8faef35eff5c23711e583e2420dd44561934a2efbd4a5b2bebe61b52accfb4762d6bb21a languageName: node linkType: hard @@ -3501,6 +3527,13 @@ __metadata: languageName: node linkType: hard +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + "@sec-ant/readable-stream@npm:^0.4.1": version: 0.4.1 resolution: "@sec-ant/readable-stream@npm:0.4.1" @@ -3955,12 +3988,19 @@ __metadata: languageName: node linkType: hard +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: e60b153664572116dfea673c5bda7778dbff150498f44f998e34b5886d8afc47f16799280e4b6e241c0472aef1bc36add771c569c68fc5125fc2ae519a3eb9ac + languageName: node + linkType: hard + "@types/node@npm:*": - version: 24.10.0 - resolution: "@types/node@npm:24.10.0" + version: 24.10.1 + resolution: "@types/node@npm:24.10.1" dependencies: undici-types: ~7.16.0 - checksum: 268c843faae02ba88be2441759c26e73038583a7e221fa3000f2c1d7fdc1d06b28cb514fc5367f7cb147c3519cd25ddafdfa1f8566829b91fb096262ebe3f7bb + checksum: c2f370ae7a97c04991e0eee6b57e588a2abef0814a5f6e41fda5a9200cf02ae6654fad51c8372ee203ae4134bab80f5bf441c586f7f50e0fda3ba422f35eb3c0 languageName: node linkType: hard @@ -4004,105 +4044,105 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^8.36.0": - version: 8.46.3 - resolution: "@typescript-eslint/eslint-plugin@npm:8.46.3" + version: 8.46.4 + resolution: "@typescript-eslint/eslint-plugin@npm:8.46.4" dependencies: "@eslint-community/regexpp": ^4.10.0 - "@typescript-eslint/scope-manager": 8.46.3 - "@typescript-eslint/type-utils": 8.46.3 - "@typescript-eslint/utils": 8.46.3 - "@typescript-eslint/visitor-keys": 8.46.3 + "@typescript-eslint/scope-manager": 8.46.4 + "@typescript-eslint/type-utils": 8.46.4 + "@typescript-eslint/utils": 8.46.4 + "@typescript-eslint/visitor-keys": 8.46.4 graphemer: ^1.4.0 ignore: ^7.0.0 natural-compare: ^1.4.0 ts-api-utils: ^2.1.0 peerDependencies: - "@typescript-eslint/parser": ^8.46.3 + "@typescript-eslint/parser": ^8.46.4 eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: b464d7ea356fc2ecec4aa64fdb760726548e309a16e317efe78950df95b28cacb1ebd739bbd3a94c2818bef472cfa39d18b7bb584785c8b62a72a21a730b84fd + checksum: 8a7a6b39e5511ab74f7eedbd6bd85f838f7e1ee413faf218ad7645b99ac90b0935fbb91450a97dfc5d9fbed1dd659605e64fc4a7f8a667869c7cef00fde7f7e2 languageName: node linkType: hard "@typescript-eslint/parser@npm:^8.36.0": - version: 8.46.3 - resolution: "@typescript-eslint/parser@npm:8.46.3" + version: 8.46.4 + resolution: "@typescript-eslint/parser@npm:8.46.4" dependencies: - "@typescript-eslint/scope-manager": 8.46.3 - "@typescript-eslint/types": 8.46.3 - "@typescript-eslint/typescript-estree": 8.46.3 - "@typescript-eslint/visitor-keys": 8.46.3 + "@typescript-eslint/scope-manager": 8.46.4 + "@typescript-eslint/types": 8.46.4 + "@typescript-eslint/typescript-estree": 8.46.4 + "@typescript-eslint/visitor-keys": 8.46.4 debug: ^4.3.4 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 8451da0dec15f65dec4a10f07a78639af3b1389e553fb307b2cf3080fdb70a2950d6da9990f71db2d4560e04f5a656044fd3dd610199b340cb6c9319f766ff44 + checksum: 43d6f7a3e38ca12fdc260ed78c70f0070f0cb12790046791528d6bced08bc4ad9c8e48e99eaf6771b884237fda0e00b277c32f97b3846d9205dec6ad4808c59e languageName: node linkType: hard -"@typescript-eslint/project-service@npm:8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/project-service@npm:8.46.3" +"@typescript-eslint/project-service@npm:8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/project-service@npm:8.46.4" dependencies: - "@typescript-eslint/tsconfig-utils": ^8.46.3 - "@typescript-eslint/types": ^8.46.3 + "@typescript-eslint/tsconfig-utils": ^8.46.4 + "@typescript-eslint/types": ^8.46.4 debug: ^4.3.4 peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: c7f15e96d53d9c0150eb2cfe42f3439724e81ceaee5de3a038679cd2874e8adaa37bd716432fe7e5c84704e63cb0a853f2984575416d1f86fd7edb933677ddcb + checksum: ff1324e681c96959b0ff2fc4093b645f7b8969eeaa2a4147e22f5695a0faed45094a67c007c2095d233455a8bb1e8212ecb5aa1470ebdb7ad5983ea0d0c4ab44 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/scope-manager@npm:8.46.3" +"@typescript-eslint/scope-manager@npm:8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/scope-manager@npm:8.46.4" dependencies: - "@typescript-eslint/types": 8.46.3 - "@typescript-eslint/visitor-keys": 8.46.3 - checksum: 1fa6f32258b906158308609a3e50581bec7546b8d933f5930bd1e753a924959c203f7255b4db0c8bc356d8729bad0ae63e4ec542e2b42dda3631fc25ca6fef96 + "@typescript-eslint/types": 8.46.4 + "@typescript-eslint/visitor-keys": 8.46.4 + checksum: 5ab0db0642b95a1dc4b72a804624ad5d173b8db980b3739122af466173c22391655e2f5eec6ca786a378d09bf1c6f894e3237517301268a57076b3bba7ddf9dd languageName: node linkType: hard -"@typescript-eslint/tsconfig-utils@npm:8.46.3, @typescript-eslint/tsconfig-utils@npm:^8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.3" +"@typescript-eslint/tsconfig-utils@npm:8.46.4, @typescript-eslint/tsconfig-utils@npm:^8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.4" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: a8076bad7045e0bfd6f56f5c038d9ec75354d2ac17976d75b03193994732ca1b9dddac9cd5ca647a6cd9f2c67ff1fbfe2227f63cec2fc62adcdc5f33383dbcc2 + checksum: 201332a6daf7d3cff78210e56630b18bc42d2ebbb3c7e8eec42b60fb6b0b82b27995f271b6fcef5d9af5a27686a7204d3f083cdacdba2605ddd3969281909d27 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/type-utils@npm:8.46.3" +"@typescript-eslint/type-utils@npm:8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/type-utils@npm:8.46.4" dependencies: - "@typescript-eslint/types": 8.46.3 - "@typescript-eslint/typescript-estree": 8.46.3 - "@typescript-eslint/utils": 8.46.3 + "@typescript-eslint/types": 8.46.4 + "@typescript-eslint/typescript-estree": 8.46.4 + "@typescript-eslint/utils": 8.46.4 debug: ^4.3.4 ts-api-utils: ^2.1.0 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 1a4e75cf162785a346c77e15475430c29b36c99ddcaff4678bf12069d4a8bcf61baf220d092cb8af1996139e6ee8967925930489976f6748379b9053f93ae269 + checksum: ff358a26d40d4c6532a4a3d5a56037178ebbd20b43b5e21bdf8c3f4c87045ecb451b8c2c3f0da9a048c3c4c11d734e3633b928f18452bbcb888b2d7d88dfa444 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.46.3, @typescript-eslint/types@npm:^8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/types@npm:8.46.3" - checksum: 58785c8aad20f616b0108f7ab61bd62c1581516b14b80559d954e2bafdc33912048e4ba626474cf367bd842803bb101e8df3e7f84747070ba522758ec58ae2e2 +"@typescript-eslint/types@npm:8.46.4, @typescript-eslint/types@npm:^8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/types@npm:8.46.4" + checksum: 561f76b77542c00cdf54cc5fdabd1fc405274b78586af1078691e836baa8402b758d0c7c62874ca0417d3afd32e01656a412c96b345106ca9ee6f9bbb527a36e languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/typescript-estree@npm:8.46.3" +"@typescript-eslint/typescript-estree@npm:8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/typescript-estree@npm:8.46.4" dependencies: - "@typescript-eslint/project-service": 8.46.3 - "@typescript-eslint/tsconfig-utils": 8.46.3 - "@typescript-eslint/types": 8.46.3 - "@typescript-eslint/visitor-keys": 8.46.3 + "@typescript-eslint/project-service": 8.46.4 + "@typescript-eslint/tsconfig-utils": 8.46.4 + "@typescript-eslint/types": 8.46.4 + "@typescript-eslint/visitor-keys": 8.46.4 debug: ^4.3.4 fast-glob: ^3.3.2 is-glob: ^4.0.3 @@ -4111,32 +4151,32 @@ __metadata: ts-api-utils: ^2.1.0 peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 2866d22819032967680b00549446a608866058ccce1c6caadb1865be3b746b657dcc6d16141340092ed385dd32b7b284ab7ef19108278097b5a1d04d387522ec + checksum: 159a0c220fb94424ec4ae48bf5cc95f69b86c0a68124bbff88d91c6a8783adb8193f98f4bbd1577901a2d347edd5a35307f6b381b7a2d76cdddbf43a90d4ae89 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.46.3, @typescript-eslint/utils@npm:^8.0.0": - version: 8.46.3 - resolution: "@typescript-eslint/utils@npm:8.46.3" +"@typescript-eslint/utils@npm:8.46.4, @typescript-eslint/utils@npm:^8.0.0": + version: 8.46.4 + resolution: "@typescript-eslint/utils@npm:8.46.4" dependencies: "@eslint-community/eslint-utils": ^4.7.0 - "@typescript-eslint/scope-manager": 8.46.3 - "@typescript-eslint/types": 8.46.3 - "@typescript-eslint/typescript-estree": 8.46.3 + "@typescript-eslint/scope-manager": 8.46.4 + "@typescript-eslint/types": 8.46.4 + "@typescript-eslint/typescript-estree": 8.46.4 peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 02fbb9960fa9de6069deba0d9e8d9acaf7a808f23988c09d11faba933813c4ec5d63aab01cbca0647325bd165d840da8d3f30f5ce0666bcc84d6f69f98a2caed + checksum: b1b3d448b9abdcee88cb3fa1ede36d517c0bd9a6dfeb2427a34222c0befc930ea39cd6513f2e4eda56295ccff8dee527dae4a11976e73805ef1fe68ee696db12 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.46.3": - version: 8.46.3 - resolution: "@typescript-eslint/visitor-keys@npm:8.46.3" +"@typescript-eslint/visitor-keys@npm:8.46.4": + version: 8.46.4 + resolution: "@typescript-eslint/visitor-keys@npm:8.46.4" dependencies: - "@typescript-eslint/types": 8.46.3 + "@typescript-eslint/types": 8.46.4 eslint-visitor-keys: ^4.2.1 - checksum: 9de0c4874cc91c53f23b90774e641718344cb47548389b751305c626a700f207c9563495fedbcbf5ac6eadf93baa3fa593b29c523bfe688b202922f6a16d21c2 + checksum: 76f9afa0c3166b87857793a48072ee4180df4ee6ab5302322e7adbfeb6a18d0a119f4fbb099f4072b59aa9958990de01cfc81c9d46b5f2ab0e7c113e04bf63d0 languageName: node linkType: hard @@ -4315,6 +4355,13 @@ __metadata: languageName: node linkType: hard +"abbrev@npm:^4.0.0": + version: 4.0.0 + resolution: "abbrev@npm:4.0.0" + checksum: d0344b63d28e763f259b4898c41bdc92c08e9d06d0da5617d0bbe4d78244e46daea88c510a2f9472af59b031d9060ec1a999653144e793fd029a59dae2f56dc8 + languageName: node + linkType: hard + "abort-controller@npm:^3.0.0": version: 3.0.0 resolution: "abort-controller@npm:3.0.0" @@ -4563,13 +4610,13 @@ __metadata: linkType: hard "arktype@npm:^2.1.15": - version: 2.1.25 - resolution: "arktype@npm:2.1.25" + version: 2.1.26 + resolution: "arktype@npm:2.1.26" dependencies: - "@ark/schema": 0.53.0 - "@ark/util": 0.53.0 + "@ark/schema": 0.54.0 + "@ark/util": 0.54.0 arkregex: 0.0.2 - checksum: f06ee4792cfb7eb991b523e4e88d4fbfb4329b36311cc761337dab46c59392dececd8584905327290cd6926ec748313b8479ccadd435fa5b70966e316b4e6c05 + checksum: 5862069b85cf0ac2f3f5436fe880c04fbd62a8fd840505bccb8e2042952a708f8d56959bd7c5dfc7915588453e40dbd48fbf466a52f1635a99038f17ccbeecf1 languageName: node linkType: hard @@ -4590,7 +4637,7 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": version: 3.1.9 resolution: "array-includes@npm:3.1.9" dependencies: @@ -4627,7 +4674,22 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.3.1": +"array.prototype.findlastindex@npm:^1.2.6": + version: 1.2.6 + resolution: "array.prototype.findlastindex@npm:1.2.6" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.4 + define-properties: ^1.2.1 + es-abstract: ^1.23.9 + es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 + es-shim-unscopables: ^1.1.0 + checksum: bd2665bd51f674d4e1588ce5d5848a8adb255f414070e8e652585598b801480516df2c6cef2c60b6ea1a9189140411c49157a3f112d52e9eabb4e9fc80936ea6 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.3": version: 1.3.3 resolution: "array.prototype.flat@npm:1.3.3" dependencies: @@ -4804,6 +4866,19 @@ __metadata: languageName: node linkType: hard +"babel-plugin-module-resolver@npm:^5.0.2": + version: 5.0.2 + resolution: "babel-plugin-module-resolver@npm:5.0.2" + dependencies: + find-babel-config: ^2.1.1 + glob: ^9.3.3 + pkg-up: ^3.1.0 + reselect: ^4.1.7 + resolve: ^1.22.8 + checksum: f1d198acbbbd0b76c9c0c4aacbf9f1ef90f8d36b3d5209d9e7a75cadee2113a73711550ebddeb9464d143b71df19adc75e165dff99ada2614d7ea333affe3b5a + languageName: node + linkType: hard + "babel-plugin-polyfill-corejs2@npm:^0.4.14": version: 0.4.14 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.14" @@ -4930,12 +5005,12 @@ __metadata: languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.8.19": - version: 2.8.25 - resolution: "baseline-browser-mapping@npm:2.8.25" +"baseline-browser-mapping@npm:^2.8.25": + version: 2.8.28 + resolution: "baseline-browser-mapping@npm:2.8.28" bin: baseline-browser-mapping: dist/cli.js - checksum: d11bdd2cce30ad96d65f6fdf92cf485152beaf7b1dfc81ad028a94022d702b439dee942984f62c2328c0b6ff468629eb42c2e62ad0ab7d8586b33837b738e560 + checksum: d9b54c55edea84902709ae2163d607cbe32f55de755efc4c26a88e269bcc7e1bafba82142e692e08e94bff20fade966d8d9b820612ffe63b6fed16a7bbc344fd languageName: node linkType: hard @@ -5058,17 +5133,17 @@ __metadata: linkType: hard "browserslist@npm:^4.20.4, browserslist@npm:^4.24.0, browserslist@npm:^4.26.3": - version: 4.27.0 - resolution: "browserslist@npm:4.27.0" + version: 4.28.0 + resolution: "browserslist@npm:4.28.0" dependencies: - baseline-browser-mapping: ^2.8.19 - caniuse-lite: ^1.0.30001751 - electron-to-chromium: ^1.5.238 - node-releases: ^2.0.26 + baseline-browser-mapping: ^2.8.25 + caniuse-lite: ^1.0.30001754 + electron-to-chromium: ^1.5.249 + node-releases: ^2.0.27 update-browserslist-db: ^1.1.4 bin: browserslist: cli.js - checksum: 01dc8428f5deb018bf99d3d8da1dd41bb0ca8a65af0b371e3b5386f5eef11f0c15ec741fc0686ca0d85aafc8f20036c4330e37bcc6b448a7424012128ded8c96 + checksum: c19fe2c6f123851d899d5b207f76de93064e247931e32ca0adcaceb3b48aec65c7c3310c0dc969de96922d488af7de0a0b77b41505e7dfa0a8d3736500748e11 languageName: node linkType: hard @@ -5197,7 +5272,7 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001751": +"caniuse-lite@npm:^1.0.30001754": version: 1.0.30001754 resolution: "caniuse-lite@npm:1.0.30001754" checksum: f5a956d820c6a4de16d0c22eb6bbbbaec346f502f324523311bbbfe4dd8ed0d69ae6034dd96a2f901156f3e4571606670be01f74c8234ac56ea7820383b6aca0 @@ -5881,6 +5956,15 @@ __metadata: languageName: node linkType: hard +"debug@npm:^3.2.7": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: ^2.1.1 + checksum: b3d8c5940799914d30314b7c3304a43305fd0715581a919dacb8b3176d024a782062368405b47491516d2091d6462d4d11f2f4974a405048094f8bfebfa3071c + languageName: node + linkType: hard + "decamelize@npm:^1.2.0": version: 1.2.0 resolution: "decamelize@npm:1.2.0" @@ -6100,10 +6184,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.238": - version: 1.5.249 - resolution: "electron-to-chromium@npm:1.5.249" - checksum: 495a8bf12a3c7bad017f0082b9581ae3a0b6cbe860cc8b89f749aa0ff9f22fd95af765b8e891507c101f5a6d56c404a4e94c4cafd9db0a2784f769fdf0184037 +"electron-to-chromium@npm:^1.5.249": + version: 1.5.250 + resolution: "electron-to-chromium@npm:1.5.250" + checksum: 4f32d0e176fb1dcf334dc8943a6a2636a305e7c30d86381321f259010f56d23ab0645d6550aa1a6b4a3ba7e6d5f713c58a4c1027b5399ce09786899886444a40 languageName: node linkType: hard @@ -6363,7 +6447,7 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.2": +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": version: 1.1.0 resolution: "es-shim-unscopables@npm:1.1.0" dependencies: @@ -6447,6 +6531,68 @@ __metadata: languageName: node linkType: hard +"eslint-import-context@npm:^0.1.8": + version: 0.1.9 + resolution: "eslint-import-context@npm:0.1.9" + dependencies: + get-tsconfig: ^4.10.1 + stable-hash-x: ^0.2.0 + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + checksum: f0778126bb3aae57c8c68946c71c4418927e9d39f72099b799d9c47a3b5712d6c9166b63ee8be58a020961dcc9216df09c856b825336af375ccbbdeedfc82a99 + languageName: node + linkType: hard + +"eslint-import-resolver-node@npm:^0.3.9": + version: 0.3.9 + resolution: "eslint-import-resolver-node@npm:0.3.9" + dependencies: + debug: ^3.2.7 + is-core-module: ^2.13.0 + resolve: ^1.22.4 + checksum: 439b91271236b452d478d0522a44482e8c8540bf9df9bd744062ebb89ab45727a3acd03366a6ba2bdbcde8f9f718bab7fe8db64688aca75acf37e04eafd25e22 + languageName: node + linkType: hard + +"eslint-import-resolver-typescript@npm:4.4.4": + version: 4.4.4 + resolution: "eslint-import-resolver-typescript@npm:4.4.4" + dependencies: + debug: ^4.4.1 + eslint-import-context: ^0.1.8 + get-tsconfig: ^4.10.1 + is-bun-module: ^2.0.0 + stable-hash-x: ^0.2.0 + tinyglobby: ^0.2.14 + unrs-resolver: ^1.7.11 + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + eslint-plugin-import-x: "*" + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + checksum: c6286f8b3464a1dddbba3dbbe1d7d5261f5728ad69364e02b69ad493fc0962ea354f8c8ccaea242b6e4109177a96ebd581405bbf3ee1d7b3263e2d540b7e00a8 + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.12.1": + version: 2.12.1 + resolution: "eslint-module-utils@npm:2.12.1" + dependencies: + debug: ^3.2.7 + peerDependenciesMeta: + eslint: + optional: true + checksum: 2f074670d8c934687820a83140048776b28bbaf35fc37f35623f63cc9c438d496d11f0683b4feabb9a120435435d4a69604b1c6c567f118be2c9a0aba6760fc1 + languageName: node + linkType: hard + "eslint-plugin-eslint-comments@npm:^3.2.0": version: 3.2.0 resolution: "eslint-plugin-eslint-comments@npm:3.2.0" @@ -6459,19 +6605,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-ft-flow@npm:3.0.11": - version: 3.0.11 - resolution: "eslint-plugin-ft-flow@npm:3.0.11" - dependencies: - lodash: ^4.17.21 - string-natural-compare: ^3.0.1 - peerDependencies: - eslint: ^8.56.0 || ^9.0.0 - hermes-eslint: ">=0.15.0" - checksum: eba55022633424b7c5e491d4939eeba5525f5b1345a9fa0846a47f508885b91a0ee2a008276e4031260d0f9c1d971903b7469d8915ebc668cce67a01cdb808d0 - languageName: node - linkType: hard - "eslint-plugin-ft-flow@npm:^2.0.1": version: 2.0.3 resolution: "eslint-plugin-ft-flow@npm:2.0.3" @@ -6485,9 +6618,38 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-import@npm:2.32.0": + version: 2.32.0 + resolution: "eslint-plugin-import@npm:2.32.0" + dependencies: + "@rtsao/scc": ^1.1.0 + array-includes: ^3.1.9 + array.prototype.findlastindex: ^1.2.6 + array.prototype.flat: ^1.3.3 + array.prototype.flatmap: ^1.3.3 + debug: ^3.2.7 + doctrine: ^2.1.0 + eslint-import-resolver-node: ^0.3.9 + eslint-module-utils: ^2.12.1 + hasown: ^2.0.2 + is-core-module: ^2.16.1 + is-glob: ^4.0.3 + minimatch: ^3.1.2 + object.fromentries: ^2.0.8 + object.groupby: ^1.0.3 + object.values: ^1.2.1 + semver: ^6.3.1 + string.prototype.trimend: ^1.0.9 + tsconfig-paths: ^3.15.0 + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: 8cd40595b5e4346d3698eb577014b4b6d0ba57b7b9edf975be4f052a89330ec202d0cc5c3861d37ebeafa151b6264821410243889b0c31710911a6b625bcf76b + languageName: node + linkType: hard + "eslint-plugin-jest@npm:^29.0.1": - version: 29.0.1 - resolution: "eslint-plugin-jest@npm:29.0.1" + version: 29.1.0 + resolution: "eslint-plugin-jest@npm:29.1.0" dependencies: "@typescript-eslint/utils": ^8.0.0 peerDependencies: @@ -6499,7 +6661,7 @@ __metadata: optional: true jest: optional: true - checksum: 329604c479280ed6345cd9f18c971a885ae74d4bd06edb4ae11bd60603f1897070dda8625444012c84d8c1fb8cee4d5d6817ed8beefd3106e917756518ed69ef + checksum: e66e7e52a35c50307de366166e1e2979cb12356e6033e426008b1bd9b37a466c0856552a6b6c188b3cc6a20790fcd8ea16071f0147fbaed0f68ee3737290c7e0 languageName: node linkType: hard @@ -6578,6 +6740,19 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-unused-imports@npm:4.3.0": + version: 4.3.0 + resolution: "eslint-plugin-unused-imports@npm:4.3.0" + peerDependencies: + "@typescript-eslint/eslint-plugin": ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + checksum: e03d2399f429a865c156a2f76de40060f8b290f4e2626a6102a1bac22ccea5ac42eb63280b3b1abe5c32eccc8e90dd2ce27f8066f62bb4ffb0fe6754612eceb1 + languageName: node + linkType: hard + "eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" @@ -7011,6 +7186,15 @@ __metadata: languageName: node linkType: hard +"find-babel-config@npm:^2.1.1": + version: 2.1.2 + resolution: "find-babel-config@npm:2.1.2" + dependencies: + json5: ^2.2.3 + checksum: 268f29cb38ee086b0f953c89f762dcea30b5b0e14abee2b39516410c00b49baa6821f598bd50346c93584e5625c5740f5c8b7e34993f568787a068f84dacc8c2 + languageName: node + linkType: hard + "find-up-simple@npm:^1.0.0, find-up-simple@npm:^1.0.1": version: 1.0.1 resolution: "find-up-simple@npm:1.0.1" @@ -7027,6 +7211,15 @@ __metadata: languageName: node linkType: hard +"find-up@npm:^3.0.0": + version: 3.0.0 + resolution: "find-up@npm:3.0.0" + dependencies: + locate-path: ^3.0.0 + checksum: 38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9 + languageName: node + linkType: hard + "find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -7348,6 +7541,15 @@ __metadata: languageName: node linkType: hard +"get-tsconfig@npm:^4.10.1": + version: 4.13.0 + resolution: "get-tsconfig@npm:4.13.0" + dependencies: + resolve-pkg-maps: ^1.0.0 + checksum: b3cfa1316dd8842e038f6a3dc02ae87d9f3a227f14b79ac4b1c81bf6fc75de4dfc3355c4117612e183f5147dad49c8132841c7fdd7a4508531d820a9b90acc51 + languageName: node + linkType: hard + "getenv@npm:^2.0.0": version: 2.0.0 resolution: "getenv@npm:2.0.0" @@ -7459,6 +7661,18 @@ __metadata: languageName: node linkType: hard +"glob@npm:^9.3.3": + version: 9.3.5 + resolution: "glob@npm:9.3.5" + dependencies: + fs.realpath: ^1.0.0 + minimatch: ^8.0.2 + minipass: ^4.2.4 + path-scurry: ^1.6.1 + checksum: 94b093adbc591bc36b582f77927d1fb0dbf3ccc231828512b017601408be98d1fe798fc8c0b19c6f2d1a7660339c3502ce698de475e9d938ccbb69b47b647c84 + languageName: node + linkType: hard + "global-directory@npm:^4.0.1": version: 4.0.1 resolution: "global-directory@npm:4.0.1" @@ -7942,6 +8156,13 @@ __metadata: languageName: node linkType: hard +"ini@npm:^6.0.0": + version: 6.0.0 + resolution: "ini@npm:6.0.0" + checksum: 82640ea788fac082fdf0a4d901654b0d4a32a62524cb9116206d2d66370fb12468af8bcdec0cafc2ceec71eb095919bf07410ce023e205383d3ae4d6c25b3626 + languageName: node + linkType: hard + "init-package-json@npm:^8.2.2": version: 8.2.2 resolution: "init-package-json@npm:8.2.2" @@ -8068,6 +8289,15 @@ __metadata: languageName: node linkType: hard +"is-bun-module@npm:^2.0.0": + version: 2.0.0 + resolution: "is-bun-module@npm:2.0.0" + dependencies: + semver: ^7.7.1 + checksum: e75bd87cb1aaff7c97cf085509669559a713f741a43b4fd5979cb44c5c0c16c05670ce5f23fc22337d1379211fac118c525c5ed73544076ddaf181c1c21ace35 + languageName: node + linkType: hard + "is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" @@ -9199,13 +9429,13 @@ __metadata: linkType: hard "js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" + version: 4.1.1 + resolution: "js-yaml@npm:4.1.1" dependencies: argparse: ^2.0.1 bin: js-yaml: bin/js-yaml.js - checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a + checksum: ea2339c6930fe048ec31b007b3c90be2714ab3e7defcc2c27ebf30c74fd940358f29070b4345af0019ef151875bf3bc3f8644bea1bab0372652b5044813ac02d languageName: node linkType: hard @@ -9288,6 +9518,17 @@ __metadata: languageName: node linkType: hard +"json5@npm:^1.0.2": + version: 1.0.2 + resolution: "json5@npm:1.0.2" + dependencies: + minimist: ^1.2.0 + bin: + json5: lib/cli.js + checksum: 866458a8c58a95a49bef3adba929c625e82532bcff1fe93f01d29cb02cac7c3fe1f4b79951b7792c2da9de0b32871a8401a6e3c5b36778ad852bf5b8a61165d7 + languageName: node + linkType: hard + "json5@npm:^2.2.1, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" @@ -9680,6 +9921,16 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^3.0.0": + version: 3.0.0 + resolution: "locate-path@npm:3.0.0" + dependencies: + p-locate: ^3.0.0 + path-exists: ^3.0.0 + checksum: 53db3996672f21f8b0bf2a2c645ae2c13ffdae1eeecfcd399a583bce8516c0b88dcb4222ca6efbbbeb6949df7e46860895be2c02e8d3219abd373ace3bfb4e11 + languageName: node + linkType: hard + "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -9923,21 +10174,21 @@ __metadata: linkType: hard "make-fetch-happen@npm:^15.0.0, make-fetch-happen@npm:^15.0.2": - version: 15.0.2 - resolution: "make-fetch-happen@npm:15.0.2" + version: 15.0.3 + resolution: "make-fetch-happen@npm:15.0.3" dependencies: "@npmcli/agent": ^4.0.0 cacache: ^20.0.1 http-cache-semantics: ^4.1.1 minipass: ^7.0.2 - minipass-fetch: ^4.0.0 + minipass-fetch: ^5.0.0 minipass-flush: ^1.0.5 minipass-pipeline: ^1.2.4 negotiator: ^1.0.0 - proc-log: ^5.0.0 + proc-log: ^6.0.0 promise-retry: ^2.0.1 - ssri: ^12.0.0 - checksum: 27413f3d69e4cc9277417d279941476ef099c86a551256500918c3adfcfc32fc8a940766991143675ddf7754c9a9ac3753b445da7d675eb46b9880e7253feb55 + ssri: ^13.0.0 + checksum: 4fb9dbb739b33565c85dacdcff7eb9388d8f36f326a59dc13375f01af809c42c48aa5d1f4840ee36623b2461a15476e1e79e4548ca1af30b42e1e324705ac8b3 languageName: node linkType: hard @@ -10365,6 +10616,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^8.0.2": + version: 8.0.4 + resolution: "minimatch@npm:8.0.4" + dependencies: + brace-expansion: ^2.0.1 + checksum: 2e46cffb86bacbc524ad45a6426f338920c529dd13f3a732cc2cf7618988ee1aae88df4ca28983285aca9e0f45222019ac2d14ebd17c1edadd2ee12221ab801a + languageName: node + linkType: hard + "minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -10374,7 +10634,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.8": +"minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -10405,6 +10665,21 @@ __metadata: languageName: node linkType: hard +"minipass-fetch@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass-fetch@npm:5.0.0" + dependencies: + encoding: ^0.1.13 + minipass: ^7.0.3 + minipass-sized: ^1.0.3 + minizlib: ^3.0.1 + dependenciesMeta: + encoding: + optional: true + checksum: 416645d1e54c09fdfe64ec1676541ac2f6f2af3abc7ad25f2f22c4518535997c1ecd2c0c586ea8a5c6499ad7d8f97671f50ff38488ada54bf61fde309f731379 + languageName: node + linkType: hard + "minipass-flush@npm:^1.0.5": version: 1.0.5 resolution: "minipass-flush@npm:1.0.5" @@ -10441,6 +10716,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^4.2.4": + version: 4.2.8 + resolution: "minipass@npm:4.2.8" + checksum: 7f4914d5295a9a30807cae5227a37a926e6d910c03f315930fde52332cf0575dfbc20295318f91f0baf0e6bb11a6f668e30cde8027dea7a11b9d159867a3c830 + languageName: node + linkType: hard + "minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.1, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" @@ -10473,7 +10755,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.1.2, ms@npm:^2.1.3": +"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.2, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d @@ -10592,7 +10874,7 @@ __metadata: languageName: node linkType: hard -"node-gyp@npm:^11.0.0, node-gyp@npm:^11.4.2, node-gyp@npm:latest": +"node-gyp@npm:^11.4.2": version: 11.5.0 resolution: "node-gyp@npm:11.5.0" dependencies: @@ -10612,6 +10894,26 @@ __metadata: languageName: node linkType: hard +"node-gyp@npm:^12.1.0, node-gyp@npm:latest": + version: 12.1.0 + resolution: "node-gyp@npm:12.1.0" + dependencies: + env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 + graceful-fs: ^4.2.6 + make-fetch-happen: ^15.0.0 + nopt: ^9.0.0 + proc-log: ^6.0.0 + semver: ^7.3.5 + tar: ^7.5.2 + tinyglobby: ^0.2.12 + which: ^6.0.0 + bin: + node-gyp: bin/node-gyp.js + checksum: 198d91c535fe9940bcdc0db4e578f94cf9872e0d068e88ef2f4656924248bb67245b270b48eded6634c7513841c0cd42f3da3ac9d77c8e16437fcd90703b9ef3 + languageName: node + linkType: hard + "node-int64@npm:^0.4.0": version: 0.4.0 resolution: "node-int64@npm:0.4.0" @@ -10619,7 +10921,7 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.26": +"node-releases@npm:^2.0.27": version: 2.0.27 resolution: "node-releases@npm:2.0.27" checksum: a9a54079d894704c2ec728a690b41fbc779a710f5d47b46fa3e460acff08a3e7dfa7108e5599b2db390aa31dac062c47c5118317201f12784188dc5b415f692d @@ -10644,6 +10946,17 @@ __metadata: languageName: node linkType: hard +"nopt@npm:^9.0.0": + version: 9.0.0 + resolution: "nopt@npm:9.0.0" + dependencies: + abbrev: ^4.0.0 + bin: + nopt: bin/nopt.js + checksum: 7a5d9ab0629eaec1944a95438cc4efa6418ed2834aa8eb21a1bea579a7d8ac3e30120131855376a96ef59ab0e23ad8e0bc94d3349770a95e5cb7119339f7c7fb + languageName: node + linkType: hard + "normalize-package-data@npm:^6.0.0": version: 6.0.2 resolution: "normalize-package-data@npm:6.0.2" @@ -10696,6 +11009,15 @@ __metadata: languageName: node linkType: hard +"npm-bundled@npm:^5.0.0": + version: 5.0.0 + resolution: "npm-bundled@npm:5.0.0" + dependencies: + npm-normalize-package-bin: ^5.0.0 + checksum: dd2e7535d6463bb4e65a1126564d0db9a54f6c9c47fee08e9583a611e3c6205626a4fa6ecc6fe7aea178e72787e5e236fdedb318f0defd4355bf5d5534640fca + languageName: node + linkType: hard + "npm-install-checks@npm:^7.1.0, npm-install-checks@npm:^7.1.2": version: 7.1.2 resolution: "npm-install-checks@npm:7.1.2" @@ -10729,14 +11051,14 @@ __metadata: linkType: hard "npm-package-arg@npm:^13.0.0, npm-package-arg@npm:^13.0.1": - version: 13.0.1 - resolution: "npm-package-arg@npm:13.0.1" + version: 13.0.2 + resolution: "npm-package-arg@npm:13.0.2" dependencies: hosted-git-info: ^9.0.0 - proc-log: ^5.0.0 + proc-log: ^6.0.0 semver: ^7.3.5 - validate-npm-package-name: ^6.0.0 - checksum: aba57acfaa0f18c42e3fe432cafd5e316b4dffa8c2c3ddaa36c2af3186968eb9cd89fcd5dfb18410fbbcb4ffc3b2b0cf02b2c0630d5642b33ab2f3fb500aa2b5 + validate-npm-package-name: ^7.0.0 + checksum: 2b84c322975403f20716a1e89ee6287edb1122fb1ef95b6840738f46db11d6fd511d1caedb33d64146a146b64aacc3d30596646db298f7e8f99fc6ccd4251f79 languageName: node linkType: hard @@ -10773,18 +11095,18 @@ __metadata: linkType: hard "npm-registry-fetch@npm:^19.0.0": - version: 19.1.0 - resolution: "npm-registry-fetch@npm:19.1.0" + version: 19.1.1 + resolution: "npm-registry-fetch@npm:19.1.1" dependencies: - "@npmcli/redact": ^3.0.0 + "@npmcli/redact": ^4.0.0 jsonparse: ^1.3.1 make-fetch-happen: ^15.0.0 minipass: ^7.0.2 - minipass-fetch: ^4.0.0 + minipass-fetch: ^5.0.0 minizlib: ^3.0.1 npm-package-arg: ^13.0.0 - proc-log: ^5.0.0 - checksum: f3fe6ad73fee41feaca8c03ca9ef6cfc1c46e3471dd2914f3a914ecbbd2fdb59eee0afc81f16cb3e870343e2c12324e50bd574d8d75296461a12e3f8e7d7b09c + proc-log: ^6.0.0 + checksum: a8a9ccfabb6ec561ca0c4e24f5a7897c84f674fe9b298356bf822f13f3ecda1e8988dedce0e8d566c4ec970be172faebfa73e8c18cdf75d1f2ac160783d0c6f4 languageName: node linkType: hard @@ -10974,6 +11296,17 @@ __metadata: languageName: node linkType: hard +"object.groupby@npm:^1.0.3": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + checksum: 0d30693ca3ace29720bffd20b3130451dca7a56c612e1926c0a1a15e4306061d84410bdb1456be2656c5aca53c81b7a3661eceaa362db1bba6669c2c9b6d1982 + languageName: node + linkType: hard + "object.values@npm:^1.1.6, object.values@npm:^1.2.1": version: 1.2.1 resolution: "object.values@npm:1.2.1" @@ -11140,7 +11473,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^2.2.0": +"p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" dependencies: @@ -11176,6 +11509,15 @@ __metadata: languageName: node linkType: hard +"p-locate@npm:^3.0.0": + version: 3.0.0 + resolution: "p-locate@npm:3.0.0" + dependencies: + p-limit: ^2.0.0 + checksum: 83991734a9854a05fe9dbb29f707ea8a0599391f52daac32b86f08e21415e857ffa60f0e120bfe7ce0cc4faf9274a50239c7895fc0d0579d08411e513b83a4ae + languageName: node + linkType: hard + "p-locate@npm:^4.1.0": version: 4.1.0 resolution: "p-locate@npm:4.1.0" @@ -11213,9 +11555,9 @@ __metadata: linkType: hard "p-map@npm:^7.0.1, p-map@npm:^7.0.2, p-map@npm:^7.0.3": - version: 7.0.3 - resolution: "p-map@npm:7.0.3" - checksum: 8c92d533acf82f0d12f7e196edccff773f384098bbb048acdd55a08778ce4fc8889d8f1bde72969487bd96f9c63212698d79744c20bedfce36c5b00b46d369f8 + version: 7.0.4 + resolution: "p-map@npm:7.0.4" + checksum: 4be2097e942f2fd3a4f4b0c6585c721f23851de8ad6484d20c472b3ea4937d5cd9a59914c832b1bceac7bf9d149001938036b82a52de0bc381f61ff2d35d26a5 languageName: node linkType: hard @@ -11262,13 +11604,13 @@ __metadata: linkType: hard "pacote@npm:^21.0.0, pacote@npm:^21.0.2, pacote@npm:^21.0.3": - version: 21.0.3 - resolution: "pacote@npm:21.0.3" + version: 21.0.4 + resolution: "pacote@npm:21.0.4" dependencies: "@npmcli/git": ^7.0.0 - "@npmcli/installed-package-contents": ^3.0.0 + "@npmcli/installed-package-contents": ^4.0.0 "@npmcli/package-json": ^7.0.0 - "@npmcli/promise-spawn": ^8.0.0 + "@npmcli/promise-spawn": ^9.0.0 "@npmcli/run-script": ^10.0.0 cacache: ^20.0.0 fs-minipass: ^3.0.0 @@ -11277,14 +11619,14 @@ __metadata: npm-packlist: ^10.0.1 npm-pick-manifest: ^11.0.1 npm-registry-fetch: ^19.0.0 - proc-log: ^5.0.0 + proc-log: ^6.0.0 promise-retry: ^2.0.1 sigstore: ^4.0.0 - ssri: ^12.0.0 + ssri: ^13.0.0 tar: ^7.4.3 bin: pacote: bin/index.js - checksum: 44a82906e480ee5b6e69c4d9c6bbdc0b6bc025f3c6f44f6aece06140d8aae073a601de3ea9eba50b1ac31d9793f78598e1972dc23fff03c9dbc99adfc26cc6dc + checksum: 09e86b71376cbc2d8089e3028d52b6ba41cb034f7f1d2a0a7f8958376eba36426ec75424b94d04672dcfb2fa2fe2120e0ac1dd6c61d64a2b8fd438a0346cc67a languageName: node linkType: hard @@ -11434,7 +11776,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.11.1": +"path-scurry@npm:^1.11.1, path-scurry@npm:^1.6.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" dependencies: @@ -11522,6 +11864,15 @@ __metadata: languageName: node linkType: hard +"pkg-up@npm:^3.1.0": + version: 3.1.0 + resolution: "pkg-up@npm:3.1.0" + dependencies: + find-up: ^3.0.0 + checksum: 5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8 + languageName: node + linkType: hard + "plist@npm:^3.0.5": version: 3.1.0 resolution: "plist@npm:3.1.0" @@ -11939,6 +12290,7 @@ __metadata: "@react-navigation/native-stack": 7.6.2 "@react-navigation/stack": 7.6.3 "@types/react": 19.1.1 + babel-plugin-module-resolver: ^5.0.2 react: 19.1.1 react-hook-form: 7.66.0 react-native: 0.82.1 @@ -11980,8 +12332,10 @@ __metadata: del-cli: 7.0.0 eslint: 9.39.1 eslint-config-prettier: 10.1.8 - eslint-plugin-ft-flow: 3.0.11 + eslint-import-resolver-typescript: 4.4.4 + eslint-plugin-import: 2.32.0 eslint-plugin-prettier: 5.5.4 + eslint-plugin-unused-imports: 4.3.0 jest: 30.2.0 lefthook: 2.0.3 nitrogen: 0.31.6 @@ -12374,6 +12728,13 @@ __metadata: languageName: node linkType: hard +"reselect@npm:^4.1.7": + version: 4.1.8 + resolution: "reselect@npm:4.1.8" + checksum: a4ac87cedab198769a29be92bc221c32da76cfdad6911eda67b4d3e7136dca86208c3b210e31632eae31ebd2cded18596f0dd230d3ccc9e978df22f233b5583e + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -12397,7 +12758,14 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.22.10": +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 1012afc566b3fdb190a6309cc37ef3b2dcc35dff5fa6683a9d00cd25c3247edfbc4691b91078c97adc82a29b77a2660c30d791d65dab4fc78bfc473f60289977 + languageName: node + linkType: hard + +"resolve@npm:^1.22.10, resolve@npm:^1.22.4, resolve@npm:^1.22.8": version: 1.22.11 resolution: "resolve@npm:1.22.11" dependencies: @@ -12423,7 +12791,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.22.10#~builtin": +"resolve@patch:resolve@^1.22.10#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin": version: 1.22.11 resolution: "resolve@patch:resolve@npm%3A1.22.11#~builtin::version=1.22.11&hash=c3c19d" dependencies: @@ -12635,7 +13003,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.2, semver@npm:^7.7.3": +"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" bin: @@ -13072,6 +13440,22 @@ __metadata: languageName: node linkType: hard +"ssri@npm:^13.0.0": + version: 13.0.0 + resolution: "ssri@npm:13.0.0" + dependencies: + minipass: ^7.0.3 + checksum: 9705dff9e686b11f3035fb4c3d44ce690359a15a54adcd6a18951f2763f670877321178dc72c37a2b804dba3287ecaa48726dbd0cff79b2715b1cc24521b3af3 + languageName: node + linkType: hard + +"stable-hash-x@npm:^0.2.0": + version: 0.2.0 + resolution: "stable-hash-x@npm:0.2.0" + checksum: ed5d814ff4d74e7873d4672584a8c136cc452995459fede2ee897784b658ba4bc338c9b7cf7cca4c5cc43a84dcf1ebac60c4aa01345e9b8609d0265e95837a6c + languageName: node + linkType: hard + "stack-utils@npm:^2.0.3, stack-utils@npm:^2.0.6": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" @@ -13450,7 +13834,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^7.4.3, tar@npm:^7.5.1": +"tar@npm:^7.4.3, tar@npm:^7.5.1, tar@npm:^7.5.2": version: 7.5.2 resolution: "tar@npm:7.5.2" dependencies: @@ -13652,6 +14036,18 @@ __metadata: languageName: node linkType: hard +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": ^0.0.29 + json5: ^1.0.2 + minimist: ^1.2.6 + strip-bom: ^3.0.0 + checksum: 59f35407a390d9482b320451f52a411a256a130ff0e7543d18c6f20afab29ac19fbe55c360a93d6476213cc335a4d76ce90f67df54c4e9037f7d240920832201 + languageName: node + linkType: hard + "tslib@npm:^2.4.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -14137,13 +14533,20 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-name@npm:^6.0.0, validate-npm-package-name@npm:^6.0.2": +"validate-npm-package-name@npm:^6.0.2": version: 6.0.2 resolution: "validate-npm-package-name@npm:6.0.2" checksum: f0e022b0a7f11345a92b64121b059b720204cd64406a0d65d81526181dcb70aef551c7c6bf9ca37b91607a7c6ff4d62e1f63a86c8d9b7346d722a641a4bd8789 languageName: node linkType: hard +"validate-npm-package-name@npm:^7.0.0": + version: 7.0.0 + resolution: "validate-npm-package-name@npm:7.0.0" + checksum: e0c686bb57cd574928d696d6b784cff51999bf3a0db194658616e3e7dc4d0a2ad2c89a13f74b715322b6355dafd68453e6ac6ad0d64a5fb26fbfb9e1ca607fc5 + languageName: node + linkType: hard + "vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" @@ -14294,6 +14697,17 @@ __metadata: languageName: node linkType: hard +"which@npm:^6.0.0": + version: 6.0.0 + resolution: "which@npm:6.0.0" + dependencies: + isexe: ^3.1.1 + bin: + node-which: bin/which.js + checksum: df19b2cd8aac94b333fa29b42e8e371a21e634a742a3b156716f7752a5afe1d73fb5d8bce9b89326f453d96879e8fe626eb421e0117eb1a3ce9fd8c97f6b7db9 + languageName: node + linkType: hard + "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -14600,9 +15014,9 @@ __metadata: linkType: hard "yocto-queue@npm:^1.0.0": - version: 1.2.1 - resolution: "yocto-queue@npm:1.2.1" - checksum: 0843d6c2c0558e5c06e98edf9c17942f25c769e21b519303a5c2adefd5b738c9b2054204dc856ac0cd9d134b1bc27d928ce84fd23c9e2423b7e013d5a6f50577 + version: 1.2.2 + resolution: "yocto-queue@npm:1.2.2" + checksum: 92dd9880c324dbc94ff4b677b7d350ba8d835619062b7102f577add7a59ab4d87f40edc5a03d77d369dfa9d11175b1b2ec4a06a6f8a5d8ce5d1306713f66ee41 languageName: node linkType: hard From e951abeaa427924ca0536a4651423da27ff788ee Mon Sep 17 00:00:00 2001 From: pinpong Date: Fri, 14 Nov 2025 11:53:40 +0700 Subject: [PATCH 21/40] chore: update yarn.lock --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index ec9686e..563a629 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4866,7 +4866,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-module-resolver@npm:^5.0.2": +"babel-plugin-module-resolver@npm:5.0.2": version: 5.0.2 resolution: "babel-plugin-module-resolver@npm:5.0.2" dependencies: @@ -12290,7 +12290,7 @@ __metadata: "@react-navigation/native-stack": 7.6.2 "@react-navigation/stack": 7.6.3 "@types/react": 19.1.1 - babel-plugin-module-resolver: ^5.0.2 + babel-plugin-module-resolver: 5.0.2 react: 19.1.1 react-hook-form: 7.66.0 react-native: 0.82.1 From 813dca27db45b038ae12512dcb5badefe39c0d93 Mon Sep 17 00:00:00 2001 From: pinpong Date: Sat, 15 Nov 2025 09:41:01 +0700 Subject: [PATCH 22/40] chore: remove unused dependencies --- package.json | 2 -- yarn.lock | 23 +---------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/package.json b/package.json index 241c573..d0bc6ad 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,6 @@ "@eslint/eslintrc": "3.3.1", "@eslint/js": "9.39.1", "@expo/config-plugins": "54.0.2", - "@jamesacarr/eslint-formatter-github-actions": "0.2.0", "@react-native/babel-preset": "0.82.1", "@react-native/eslint-config": "0.82.1", "@semantic-release/changelog": "6.0.3", @@ -90,7 +89,6 @@ "@semantic-release/npm": "13.1.1", "@types/jest": "30.0.0", "@types/react": "19.1.1", - "clang-format-node": "2.0.4", "conventional-changelog-conventionalcommits": "9.1.0", "del-cli": "7.0.0", "eslint": "9.39.1", diff --git a/yarn.lock b/yarn.lock index 563a629..2836e55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,7 +5,7 @@ __metadata: version: 6 cacheKey: 8 -"@actions/core@npm:^1.10.0, @actions/core@npm:^1.11.1": +"@actions/core@npm:^1.11.1": version: 1.11.1 resolution: "@actions/core@npm:1.11.1" dependencies: @@ -2108,15 +2108,6 @@ __metadata: languageName: node linkType: hard -"@jamesacarr/eslint-formatter-github-actions@npm:0.2.0": - version: 0.2.0 - resolution: "@jamesacarr/eslint-formatter-github-actions@npm:0.2.0" - dependencies: - "@actions/core": ^1.10.0 - checksum: 022ba2fd4a51dbc6b9ad381190f196bbdc9f94743a268b19cd42d4e311783c2727d3ade4a3c2b5123f4af67a6f4e2920d9b8ca591a7c61626128bfd8423e18d4 - languageName: node - linkType: hard - "@jest/console@npm:30.2.0": version: 30.2.0 resolution: "@jest/console@npm:30.2.0" @@ -5386,16 +5377,6 @@ __metadata: languageName: node linkType: hard -"clang-format-node@npm:2.0.4": - version: 2.0.4 - resolution: "clang-format-node@npm:2.0.4" - bin: - clang-format: build/cli.js - clang-format-node: build/cli.js - checksum: b660c807579d6cc867afbeec9cec118ea2fe43233f2b5fa0c335b175125795b184fd0935185b6c08d6057a3994843c89eb5c544edc8615a710a6175c3514e43b - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -12318,7 +12299,6 @@ __metadata: "@eslint/eslintrc": 3.3.1 "@eslint/js": 9.39.1 "@expo/config-plugins": 54.0.2 - "@jamesacarr/eslint-formatter-github-actions": 0.2.0 "@react-native/babel-preset": 0.82.1 "@react-native/eslint-config": 0.82.1 "@semantic-release/changelog": 6.0.3 @@ -12327,7 +12307,6 @@ __metadata: "@semantic-release/npm": 13.1.1 "@types/jest": 30.0.0 "@types/react": 19.1.1 - clang-format-node: 2.0.4 conventional-changelog-conventionalcommits: 9.1.0 del-cli: 7.0.0 eslint: 9.39.1 From 4e20d8a376fe237daddb5c5b7b11df9a127082ea Mon Sep 17 00:00:00 2001 From: pinpong Date: Sun, 16 Nov 2025 11:52:53 +0700 Subject: [PATCH 23/40] fix(example): statusbar --- example/src/App.tsx | 15 +++++++++++---- example/src/screens/HomeScreen.tsx | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/example/src/App.tsx b/example/src/App.tsx index 39dd603..5d56c29 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { useColorScheme } from 'react-native'; +import { StatusBar } from 'react-native'; import { DarkTheme, @@ -10,6 +10,7 @@ import { import { createStackNavigator } from '@react-navigation/stack'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; +import { useAppTheme } from '@src/hooks/useAppTheme'; import BasicMapScreen from '@src/screens/BasicMapScreen'; import BlankScreen from '@src/screens/BlankScreen'; import CameraTestScreen from '@src/screens/CameraTestScreen'; @@ -33,10 +34,17 @@ import type { RootStackParamList } from '@src/types/navigation'; const Stack = createStackNavigator(); export default function App() { - const scheme = useColorScheme(); + const appTheme = useAppTheme(); + const isDark = appTheme.theme === 'dark'; + return ( - + + ({ @@ -44,7 +52,6 @@ export default function App() { headerTitleAlign: 'center', headerStyle: { backgroundColor: theme.colors.card }, headerTintColor: theme.colors.text, - contentStyle: { backgroundColor: theme.colors.background }, })} > - React Native Google Maps Plus Examples {screens.map((s) => ( flexGrow: 1, alignItems: 'center', justifyContent: 'center', - paddingVertical: layout.bottom + 8, + paddingTop: 8, + paddingBottom: layout.bottom + 8, backgroundColor: theme.bgPrimary, }, title: { From e758ac8be10015223fcef24560932f9715dfc733 Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 17 Nov 2025 19:51:24 +0700 Subject: [PATCH 24/40] chore(example): add modules example --- example/src/App.tsx | 10 ++- example/src/components/ActionButton.tsx | 57 +++++++++++++++++ .../src/screens/GoogleMapPlusModuleScreen.tsx | 64 +++++++++++++++++++ example/src/screens/HomeScreen.tsx | 40 ++---------- ...leOverlay.tsx => UrlTileOverlayScreen.tsx} | 2 +- example/src/types/navigation.ts | 1 + 6 files changed, 137 insertions(+), 37 deletions(-) create mode 100644 example/src/components/ActionButton.tsx create mode 100644 example/src/screens/GoogleMapPlusModuleScreen.tsx rename example/src/screens/{UrlTileOverlay.tsx => UrlTileOverlayScreen.tsx} (96%) diff --git a/example/src/App.tsx b/example/src/App.tsx index 5d56c29..9d52413 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -17,6 +17,7 @@ import CameraTestScreen from '@src/screens/CameraTestScreen'; import CirclesScreen from '@src/screens/CirclesScreen'; import ClusteringScreen from '@src/screens/ClsuteringScreen'; import CustomStyleScreen from '@src/screens/CustomStyleScreen'; +import GoogleMapPlusModuleScreen from '@src/screens/GoogleMapPlusModuleScreen'; import HeatmapScreen from '@src/screens/HeatmapScreen'; import HomeScreen from '@src/screens/HomeScreen'; import IndoorLevelMapScreen from '@src/screens/IndoorLevelMapScreen'; @@ -28,7 +29,7 @@ import PolylinesScreen from '@src/screens/PolylinesScreen'; import SnapshotTestScreen from '@src/screens/SnaptshotTestScreen'; import StressTestScreen from '@src/screens/StressTestScreen'; import SvgMarkersScreen from '@src/screens/SvgMarkersScreen'; -import UrlTileOverlay from '@src/screens/UrlTileOverlay'; +import UrlTileOverlayScreen from '@src/screens/UrlTileOverlayScreen'; import type { RootStackParamList } from '@src/types/navigation'; const Stack = createStackNavigator(); @@ -106,7 +107,7 @@ export default function App() { /> + diff --git a/example/src/components/ActionButton.tsx b/example/src/components/ActionButton.tsx new file mode 100644 index 0000000..c86a44e --- /dev/null +++ b/example/src/components/ActionButton.tsx @@ -0,0 +1,57 @@ +import React, { useMemo } from 'react'; + +import { TouchableOpacity, Text, StyleSheet } from 'react-native'; + +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; + +type Props = { + label: string; + onPress: () => void; +}; + +export default function ActionButton({ label, onPress }: Props) { + const theme = useAppTheme(); + const styles = useMemo(() => getThemedStyles(theme), [theme]); + + return ( + + {label} + + ); +} + +const getThemedStyles = (theme: AppTheme) => + StyleSheet.create({ + title: { + fontSize: 18, + fontWeight: '600', + marginBottom: 24, + color: theme.textPrimary, + textAlign: 'center', + }, + button: { + backgroundColor: theme.bgAccent, + paddingVertical: 14, + paddingHorizontal: 24, + borderRadius: 10, + marginVertical: 6, + width: '80%', + alignItems: 'center', + justifyContent: 'center', + shadowColor: theme.shadow, + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.25, + shadowRadius: 4, + elevation: 2, + }, + buttonText: { + fontSize: 16, + fontWeight: '600', + color: theme.textOnAccent, + }, + }); diff --git a/example/src/screens/GoogleMapPlusModuleScreen.tsx b/example/src/screens/GoogleMapPlusModuleScreen.tsx new file mode 100644 index 0000000..944355f --- /dev/null +++ b/example/src/screens/GoogleMapPlusModuleScreen.tsx @@ -0,0 +1,64 @@ +import React, { useMemo } from 'react'; + +import { Alert, StyleSheet, View } from 'react-native'; + +import { GoogleMapsModule } from 'react-native-google-maps-plus'; +import { + type EdgeInsets, + useSafeAreaInsets, +} from 'react-native-safe-area-context'; + +import ActionButton from '@src/components/ActionButton'; +import { useAppTheme } from '@src/hooks/useAppTheme'; +import type { AppTheme } from '@src/theme'; + +export default function GoogleMapPlusModuleScreen() { + const theme = useAppTheme(); + const layout = useSafeAreaInsets(); + const styles = useMemo(() => getThemedStyles(theme, layout), [theme, layout]); + + const actions = useMemo( + () => [ + { + label: 'Check google play available', + onPress: () => + Alert.alert( + `Available ${GoogleMapsModule.isGooglePlayServicesAvailable()}` + ), + }, + { + label: 'Open location settings', + onPress: () => GoogleMapsModule.openLocationSettings(), + }, + { + label: 'Request location permission', + onPress: () => GoogleMapsModule.requestLocationPermission(), + }, + { + label: 'Show location enable dialog', + onPress: () => GoogleMapsModule.showLocationDialog(), + }, + ], + [] + ); + + return ( + + {actions.map(({ label, onPress }) => ( + + ))} + + ); +} + +const getThemedStyles = (theme: AppTheme, layout: EdgeInsets) => + StyleSheet.create({ + container: { + flexGrow: 1, + alignItems: 'center', + justifyContent: 'center', + paddingTop: 8, + paddingBottom: layout.bottom + 8, + backgroundColor: theme.bgPrimary, + }, + }); diff --git a/example/src/screens/HomeScreen.tsx b/example/src/screens/HomeScreen.tsx index 40a026d..fa26f0a 100644 --- a/example/src/screens/HomeScreen.tsx +++ b/example/src/screens/HomeScreen.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; -import { ScrollView, StyleSheet, Text, TouchableOpacity } from 'react-native'; +import { ScrollView, StyleSheet } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { @@ -8,6 +8,7 @@ import { useSafeAreaInsets, } from 'react-native-safe-area-context'; +import ActionButton from '@src/components/ActionButton'; import { useAppTheme } from '@src/hooks/useAppTheme'; import type { AppTheme } from '@src/theme'; import type { @@ -32,6 +33,7 @@ const screens = [ { name: 'Snapshot', title: 'Snapshot Test' }, { name: 'Clustering', title: 'Clustering' }, { name: 'Stress', title: 'Stress Test' }, + { name: 'Module', title: 'Module Test' }, ]; export default function HomeScreen() { @@ -43,16 +45,13 @@ export default function HomeScreen() { return ( {screens.map((s) => ( - navigation.navigate(s.name as keyof RootStackParamList) } - activeOpacity={0.85} - > - {s.title} - + /> ))} ); @@ -68,31 +67,4 @@ const getThemedStyles = (theme: AppTheme, layout: EdgeInsets) => paddingBottom: layout.bottom + 8, backgroundColor: theme.bgPrimary, }, - title: { - fontSize: 18, - fontWeight: '600', - marginBottom: 24, - color: theme.textPrimary, - textAlign: 'center', - }, - button: { - backgroundColor: theme.bgAccent, - paddingVertical: 14, - paddingHorizontal: 24, - borderRadius: 10, - marginVertical: 6, - width: '80%', - alignItems: 'center', - justifyContent: 'center', - shadowColor: theme.shadow, - shadowOffset: { width: 0, height: 2 }, - shadowOpacity: 0.25, - shadowRadius: 4, - elevation: 2, - }, - buttonText: { - fontSize: 16, - fontWeight: '600', - color: theme.textOnAccent, - }, }); diff --git a/example/src/screens/UrlTileOverlay.tsx b/example/src/screens/UrlTileOverlayScreen.tsx similarity index 96% rename from example/src/screens/UrlTileOverlay.tsx rename to example/src/screens/UrlTileOverlayScreen.tsx index 782fee4..8c82bbb 100644 --- a/example/src/screens/UrlTileOverlay.tsx +++ b/example/src/screens/UrlTileOverlayScreen.tsx @@ -13,7 +13,7 @@ import type { RNUrlTileOverlay, } from 'react-native-google-maps-plus'; -export default function UrlTileOverlay() { +export default function UrlTileOverlayScreen() { const mapRef = useRef(null); const navigation = useNavigation(); const [urlTileOverlays, setUrlTileOverlays] = useState< diff --git a/example/src/types/navigation.ts b/example/src/types/navigation.ts index 5778d54..f8a2553 100644 --- a/example/src/types/navigation.ts +++ b/example/src/types/navigation.ts @@ -19,6 +19,7 @@ export type RootStackParamList = { Snapshot: undefined; Clustering: undefined; Stress: undefined; + Module: undefined; }; export type RootNavigationProp = StackNavigationProp; From fd8b8da87f8d9acdd6e29301218bc8721d82cd2c Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 17 Nov 2025 20:21:56 +0700 Subject: [PATCH 25/40] refactor(ios): lifecycle --- ios/GoogleMapViewImpl.swift | 29 ++++++++++++++++++++--------- ios/RNGoogleMapsPlusView.swift | 24 ++++++++---------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/ios/GoogleMapViewImpl.swift b/ios/GoogleMapViewImpl.swift index 2358f81..a0702ec 100644 --- a/ios/GoogleMapViewImpl.swift +++ b/ios/GoogleMapViewImpl.swift @@ -40,14 +40,18 @@ GMSIndoorDisplayDelegate { self.locationHandler = locationHandler self.markerBuilder = markerBuilder super.init(frame: frame) - setupAppLifecycleObservers() } + @MainActor + private var lifecycleAttached = false + @MainActor private var lifecycleTasks = [Task]() @MainActor - private func setupAppLifecycleObservers() { + private func attachLifecycleObservers() { + if lifecycleAttached { return } + lifecycleAttached = true lifecycleTasks.append( Task { @MainActor in for await _ in NotificationCenter.default.notifications( @@ -79,12 +83,20 @@ GMSIndoorDisplayDelegate { ) } + @MainActor + private func detachLifecycleObservers() { + if !lifecycleAttached { return } + lifecycleAttached = false + lifecycleTasks.forEach { $0.cancel() } + lifecycleTasks.removeAll() + } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @MainActor - func initMapView(googleMapOptions: GMSMapViewOptions) { + func initMapView() { if initialized { return } initialized = true googleMapOptions.frame = bounds @@ -108,7 +120,6 @@ GMSIndoorDisplayDelegate { locationHandler.onError = { [weak self] error in self?.onLocationError?(error) } - locationHandler.start() } @MainActor @@ -171,9 +182,7 @@ GMSIndoorDisplayDelegate { } @MainActor - var initialProps: RNInitialProps? { - didSet {} - } + var googleMapOptions: GMSMapViewOptions = GMSMapViewOptions() @MainActor var uiSettings: RNMapUiSettings? { @@ -693,6 +702,7 @@ GMSIndoorDisplayDelegate { func deinitInternal() { guard !deInitialized else { return } deInitialized = true + detachLifecycleObservers() onMain { self.locationHandler.stop() self.markerBuilder.cancelAllIconTasks() @@ -728,16 +738,17 @@ GMSIndoorDisplayDelegate { override func didMoveToWindow() { super.didMoveToWindow() if window != nil { + attachLifecycleObservers() locationHandler.start() + initMapView() } else { locationHandler.stop() + detachLifecycleObservers() } } deinit { deinitInternal() - lifecycleTasks.forEach { $0.cancel() } - lifecycleTasks.removeAll() } func mapViewDidFinishTileRendering(_ mapView: GMSMapView) { diff --git a/ios/RNGoogleMapsPlusView.swift b/ios/RNGoogleMapsPlusView.swift index 160192b..a3673ac 100644 --- a/ios/RNGoogleMapsPlusView.swift +++ b/ios/RNGoogleMapsPlusView.swift @@ -8,7 +8,6 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec { private let permissionHandler: PermissionHandler private let locationHandler: LocationHandler - private var propsInitialized = false private let markerBuilder = MapMarkerBuilder() private let polylineBuilder = MapPolylineBuilder() private let polygonBuilder = MapPolygonBuilder() @@ -32,9 +31,13 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec { } @MainActor - func afterUpdate() { - if !propsInitialized { - propsInitialized = true + func dispose() { + impl.deinitInternal() + } + + @MainActor + var initialProps: RNInitialProps? { + didSet { let options = GMSMapViewOptions() initialProps?.mapId.map { options.mapID = GMSMapID(identifier: $0) } initialProps?.liteMode.map { _ in /* not supported */ } @@ -44,19 +47,8 @@ final class RNGoogleMapsPlusView: HybridRNGoogleMapsPlusViewSpec { initialProps?.backgroundColor.map { options.backgroundColor = $0.toUIColor() } - impl.initMapView(googleMapOptions: options) - } - } - @MainActor - func dispose() { - impl.deinitInternal() - } - - @MainActor - var initialProps: RNInitialProps? { - didSet { - impl.initialProps = initialProps + impl.googleMapOptions = options } } From 0f4cec0dacb5b4bb9b76280ee08a41ef931109dc Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 17 Nov 2025 20:24:40 +0700 Subject: [PATCH 26/40] refactor(android): lifecycle --- .../rngooglemapsplus/GoogleMapsViewImpl.kt | 144 ++++++++---------- .../MapLifecycleEventObserver.kt | 78 ++++++++++ .../rngooglemapsplus/RNGoogleMapsPlusView.kt | 19 +-- 3 files changed, 148 insertions(+), 93 deletions(-) create mode 100644 android/src/main/java/com/rngooglemapsplus/MapLifecycleEventObserver.kt diff --git a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt index 3114ba6..7769d06 100644 --- a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +++ b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt @@ -12,7 +12,8 @@ import android.location.Location import android.util.Size import android.view.View import android.widget.FrameLayout -import com.facebook.react.bridge.LifecycleEventListener +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.findViewTreeLifecycleOwner import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.ThemedReactContext import com.google.android.gms.maps.CameraUpdateFactory @@ -81,10 +82,12 @@ class GoogleMapsViewImpl( GoogleMap.OnInfoWindowLongClickListener, GoogleMap.OnMyLocationClickListener, GoogleMap.OnMyLocationButtonClickListener, - GoogleMap.InfoWindowAdapter, - LifecycleEventListener { - private var initialized = false - private var loaded = false + GoogleMap.InfoWindowAdapter { + private var lifecycleObserver: MapLifecycleEventObserver? = null + private var lifecycle: Lifecycle? = null + + private var mapViewInitialized = false + private var mapViewLoaded = false private var destroyed = false private var googleMap: GoogleMap? = null private var mapView: MapView? = null @@ -125,13 +128,12 @@ class GoogleMapsViewImpl( init { MapsInitializer.initialize(reactContext) reactContext.registerComponentCallbacks(componentCallbacks) - reactContext.addLifecycleEventListener(this) } - fun initMapView(googleMapsOptions: GoogleMapOptions) = + fun initMapView() = onUi { - if (initialized) return@onUi - initialized = true + if (mapViewInitialized) return@onUi + mapViewInitialized = true val result = playServiceHandler.playServicesAvailability() val errorCode = result.toRNMapErrorCodeOrNull() @@ -144,45 +146,46 @@ class GoogleMapsViewImpl( } } - mapView = MapView(reactContext, googleMapsOptions) - super.addView(mapView) - - mapView?.onCreate(null) - mapView?.getMapAsync { map -> - googleMap = map - googleMap?.setOnMapLoadedCallback { - googleMap?.setOnCameraMoveStartedListener(this@GoogleMapsViewImpl) - googleMap?.setOnCameraMoveListener(this@GoogleMapsViewImpl) - googleMap?.setOnCameraIdleListener(this@GoogleMapsViewImpl) - googleMap?.setOnMarkerClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnPolylineClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnPolygonClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnCircleClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnMapClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnMapLongClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnPoiClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnMarkerDragListener(this@GoogleMapsViewImpl) - googleMap?.setOnInfoWindowClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnInfoWindowCloseListener(this@GoogleMapsViewImpl) - googleMap?.setOnInfoWindowLongClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnMyLocationClickListener(this@GoogleMapsViewImpl) - googleMap?.setOnMyLocationButtonClickListener(this@GoogleMapsViewImpl) - googleMap?.setInfoWindowAdapter(this@GoogleMapsViewImpl) - loaded = true - onMapLoaded?.invoke( - map.projection.visibleRegion.toRnRegion(), - map.cameraPosition.toRnCamera(), - ) + mapView = + MapView(reactContext, googleMapsOptions).also { + lifecycleObserver = MapLifecycleEventObserver(it, locationHandler) + super.addView(it) + it.getMapAsync { map -> + googleMap = map + googleMap?.setOnMapLoadedCallback { + googleMap?.setOnCameraMoveStartedListener(this@GoogleMapsViewImpl) + googleMap?.setOnCameraMoveListener(this@GoogleMapsViewImpl) + googleMap?.setOnCameraIdleListener(this@GoogleMapsViewImpl) + googleMap?.setOnMarkerClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnPolylineClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnPolygonClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnCircleClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnMapClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnMapLongClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnPoiClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnMarkerDragListener(this@GoogleMapsViewImpl) + googleMap?.setOnInfoWindowClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnInfoWindowCloseListener(this@GoogleMapsViewImpl) + googleMap?.setOnInfoWindowLongClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnMyLocationClickListener(this@GoogleMapsViewImpl) + googleMap?.setOnMyLocationButtonClickListener(this@GoogleMapsViewImpl) + googleMap?.setInfoWindowAdapter(this@GoogleMapsViewImpl) + mapViewLoaded = true + onMapLoaded?.invoke( + map.projection.visibleRegion.toRnRegion(), + map.cameraPosition.toRnCamera(), + ) + } + applyProps() + initLocationCallbacks() + onMapReady?.invoke(true) + } } - applyProps() - initLocationCallbacks() - onMapReady?.invoke(true) - } } override fun onCameraMoveStarted(reason: Int) = onUi { - if (!loaded) return@onUi + if (!mapViewLoaded) return@onUi cameraMoveReason = reason val visibleRegion = googleMap?.projection?.visibleRegion ?: return@onUi val cameraPosition = googleMap?.cameraPosition ?: return@onUi @@ -195,7 +198,7 @@ class GoogleMapsViewImpl( override fun onCameraMove() = onUi { - if (!loaded) return@onUi + if (!mapViewLoaded) return@onUi val visibleRegion = googleMap?.projection?.visibleRegion ?: return@onUi val cameraPosition = googleMap?.cameraPosition ?: return@onUi val gesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason @@ -208,7 +211,7 @@ class GoogleMapsViewImpl( override fun onCameraIdle() = onUi { - if (!loaded) return@onUi + if (!mapViewLoaded) return@onUi val visibleRegion = googleMap?.projection?.visibleRegion ?: return@onUi val cameraPosition = googleMap?.cameraPosition ?: return@onUi val gesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason @@ -226,7 +229,6 @@ class GoogleMapsViewImpl( locationHandler.onError = { error -> onUi { onLocationError?.invoke(error) } } - locationHandler.start() } fun applyProps() { @@ -275,7 +277,7 @@ class GoogleMapsViewImpl( val currentCamera: CameraPosition? get() = onUiSync { googleMap?.cameraPosition } - var initialProps: RNInitialProps? = null + var googleMapsOptions: GoogleMapOptions = GoogleMapOptions() var uiSettings: RNMapUiSettings? = null set(value) { @@ -811,7 +813,7 @@ class GoogleMapsViewImpl( onUi { if (destroyed) return@onUi destroyed = true - locationHandler.stop() + lifecycleObserver?.toDestroyedState() markerBuilder.cancelAllJobs() clearMarkers() clearPolylines() @@ -840,16 +842,10 @@ class GoogleMapsViewImpl( setInfoWindowAdapter(null) } googleMap = null - mapView?.apply { - onPause() - onStop() - onDestroy() - removeAllViews() - } + mapView?.removeAllViews() super.removeAllViews() reactContext.unregisterComponentCallbacks(componentCallbacks) - reactContext.removeLifecycleEventListener(this) - initialized = false + mapViewInitialized = false } override fun requestLayout() { @@ -864,32 +860,20 @@ class GoogleMapsViewImpl( } } - override fun onAttachedToWindow() = - onUi { - super.onAttachedToWindow() - locationHandler.start() - } - - override fun onDetachedFromWindow() = - onUi { - super.onDetachedFromWindow() - locationHandler.stop() - } - - override fun onHostResume() = - onUi { - locationHandler.start() - mapView?.onResume() - } - - override fun onHostPause() = - onUi { - locationHandler.stop() - mapView?.onPause() + override fun onAttachedToWindow() { + super.onAttachedToWindow() + initMapView() + lifecycle = mapView?.findViewTreeLifecycleOwner()?.lifecycle + lifecycleObserver?.let { observer -> + lifecycle?.addObserver(observer) } + } - override fun onHostDestroy() { - destroyInternal() + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + lifecycleObserver?.let { lifecycle?.removeObserver(it) } + lifecycle = null + lifecycleObserver?.toCreatedState() } override fun onMarkerClick(marker: Marker): Boolean { diff --git a/android/src/main/java/com/rngooglemapsplus/MapLifecycleEventObserver.kt b/android/src/main/java/com/rngooglemapsplus/MapLifecycleEventObserver.kt new file mode 100644 index 0000000..79859fd --- /dev/null +++ b/android/src/main/java/com/rngooglemapsplus/MapLifecycleEventObserver.kt @@ -0,0 +1,78 @@ +package com.rngooglemapsplus + +import android.os.Bundle +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner +import com.google.android.gms.maps.MapView + +class MapLifecycleEventObserver( + private val mapView: MapView?, + private val locationHandler: LocationHandler, +) : LifecycleEventObserver { + private var currentState: Lifecycle.State = Lifecycle.State.INITIALIZED + + override fun onStateChanged( + source: LifecycleOwner, + event: Lifecycle.Event, + ) { + when (event) { + Lifecycle.Event.ON_DESTROY -> toCreatedState() + else -> toState(event.targetState) + } + } + + fun toCreatedState() { + if (currentState > Lifecycle.State.CREATED) { + toState(Lifecycle.State.CREATED) + } + } + + fun toDestroyedState() { + if (currentState > Lifecycle.State.INITIALIZED) { + toState(Lifecycle.State.DESTROYED) + } + } + + private fun toState(state: Lifecycle.State) { + while (currentState != state) { + when { + currentState < state -> upFromCurrentState() + currentState > state -> downFromCurrentState() + } + } + } + + private fun downFromCurrentState() { + Lifecycle.Event.downFrom(currentState)?.also { + invokeEvent(it) + } + } + + private fun upFromCurrentState() { + Lifecycle.Event.upFrom(currentState)?.also { + invokeEvent(it) + } + } + + private fun invokeEvent(event: Lifecycle.Event) { + when (event) { + Lifecycle.Event.ON_CREATE -> mapView?.onCreate(Bundle()) + Lifecycle.Event.ON_START -> mapView?.onStart() + Lifecycle.Event.ON_RESUME -> { + locationHandler.start() + mapView?.onResume() + } + + Lifecycle.Event.ON_PAUSE -> { + mapView?.onPause() + locationHandler.stop() + } + + Lifecycle.Event.ON_STOP -> mapView?.onStop() + Lifecycle.Event.ON_DESTROY -> mapView?.onDestroy() + Lifecycle.Event.ON_ANY -> {} + } + currentState = event.targetState + } +} diff --git a/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt b/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt index 45fda58..6589d5e 100644 --- a/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +++ b/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt @@ -24,7 +24,6 @@ import com.rngooglemapsplus.extensions.toSize class RNGoogleMapsPlusView( val context: ThemedReactContext, ) : HybridRNGoogleMapsPlusViewSpec() { - private var propsInitialized = false private var currentCustomMapStyle: String? = null private var permissionHandler = PermissionHandler(context) private var locationHandler = LocationHandler(context) @@ -40,10 +39,11 @@ class RNGoogleMapsPlusView( override val view = GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerBuilder) - override fun afterUpdate() { - super.afterUpdate() - if (!propsInitialized) { - propsInitialized = true + override var initialProps: RNInitialProps? = null + set(value) { + if (field == value) return + field = value + val options = GoogleMapOptions().apply { initialProps?.mapId?.let { mapId(it) } @@ -51,15 +51,8 @@ class RNGoogleMapsPlusView( initialProps?.camera?.let { camera(it.toCameraPosition(current = null)) } initialProps?.backgroundColor?.let { backgroundColor(it.toColor()) } } - view.initMapView(options) - } - } - override var initialProps: RNInitialProps? = null - set(value) { - if (field == value) return - field = value - view.initialProps = value + view.googleMapsOptions = options } override var uiSettings: RNMapUiSettings? = null From a1bfca144cdd431d2e241c0bc635a2113994cfd3 Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 17 Nov 2025 21:14:22 +0700 Subject: [PATCH 27/40] chore: update dependencies --- example/package.json | 6 +- package.json | 4 +- yarn.lock | 180 +++++++++++++++++++++++++------------------ 3 files changed, 108 insertions(+), 82 deletions(-) diff --git a/example/package.json b/example/package.json index b46e3db..d95aaf3 100644 --- a/example/package.json +++ b/example/package.json @@ -11,9 +11,9 @@ "build:ios": "react-native build-ios --mode Debug --extra-params 'CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO'" }, "dependencies": { - "@react-navigation/native": "7.1.19", - "@react-navigation/native-stack": "7.6.2", - "@react-navigation/stack": "7.6.3", + "@react-navigation/native": "7.1.20", + "@react-navigation/native-stack": "7.6.3", + "@react-navigation/stack": "7.6.4", "react": "19.1.1", "react-hook-form": "7.66.0", "react-native": "0.82.1", diff --git a/package.json b/package.json index d0bc6ad..3fccee2 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@semantic-release/changelog": "6.0.3", "@semantic-release/exec": "7.1.0", "@semantic-release/git": "10.0.1", - "@semantic-release/npm": "13.1.1", + "@semantic-release/npm": "13.1.2", "@types/jest": "30.0.0", "@types/react": "19.1.1", "conventional-changelog-conventionalcommits": "9.1.0", @@ -98,7 +98,7 @@ "eslint-plugin-prettier": "5.5.4", "eslint-plugin-unused-imports": "4.3.0", "jest": "30.2.0", - "lefthook": "2.0.3", + "lefthook": "2.0.4", "nitrogen": "0.31.6", "prettier": "3.6.2", "react": "19.1.1", diff --git a/yarn.lock b/yarn.lock index 2836e55..e030369 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3420,9 +3420,9 @@ __metadata: languageName: node linkType: hard -"@react-navigation/core@npm:^7.13.0": - version: 7.13.0 - resolution: "@react-navigation/core@npm:7.13.0" +"@react-navigation/core@npm:^7.13.1": + version: 7.13.1 + resolution: "@react-navigation/core@npm:7.13.1" dependencies: "@react-navigation/routers": ^7.5.1 escape-string-regexp: ^4.0.0 @@ -3434,53 +3434,53 @@ __metadata: use-sync-external-store: ^1.5.0 peerDependencies: react: ">= 18.2.0" - checksum: e6c99df003b274aacd9c39121ad5497574efb316af6b584b739ff134fc39726b59825245a6afdea62100fa51622af78c431907112d07f62e6e3a9c8d16332023 + checksum: 40b0113acdfd95f662852366b40fa8204c11fb43326c2fb3a39001408261b48b64138b69a5c363d41dca4ef8daa4a6940c7f58d7acb31abe8e9c22c4e77cf1c6 languageName: node linkType: hard -"@react-navigation/elements@npm:^2.8.1": - version: 2.8.1 - resolution: "@react-navigation/elements@npm:2.8.1" +"@react-navigation/elements@npm:^2.8.2": + version: 2.8.2 + resolution: "@react-navigation/elements@npm:2.8.2" dependencies: color: ^4.2.3 use-latest-callback: ^0.2.4 use-sync-external-store: ^1.5.0 peerDependencies: "@react-native-masked-view/masked-view": ">= 0.2.0" - "@react-navigation/native": ^7.1.19 + "@react-navigation/native": ^7.1.20 react: ">= 18.2.0" react-native: "*" react-native-safe-area-context: ">= 4.0.0" peerDependenciesMeta: "@react-native-masked-view/masked-view": optional: true - checksum: 82e2d4ae99ef0dad3f8a8a70fe8678d7ee41e4e216859ec78e720a0816efdb370940ccbfc7f75874fcd98207336b09cbc44e6a4d38192f7474ef330052bb9195 + checksum: 0077dad93be8be7bf3bfd78881386ee7c7d6c91ee440d7d9687e1feedbf12bdee317b31918d23868191fda83987b8784a7c08593b1a2e50a42289313bbb21ffe languageName: node linkType: hard -"@react-navigation/native-stack@npm:7.6.2": - version: 7.6.2 - resolution: "@react-navigation/native-stack@npm:7.6.2" +"@react-navigation/native-stack@npm:7.6.3": + version: 7.6.3 + resolution: "@react-navigation/native-stack@npm:7.6.3" dependencies: - "@react-navigation/elements": ^2.8.1 + "@react-navigation/elements": ^2.8.2 color: ^4.2.3 sf-symbols-typescript: ^2.1.0 warn-once: ^0.1.1 peerDependencies: - "@react-navigation/native": ^7.1.19 + "@react-navigation/native": ^7.1.20 react: ">= 18.2.0" react-native: "*" react-native-safe-area-context: ">= 4.0.0" react-native-screens: ">= 4.0.0" - checksum: dd3f12d60c3e9b970d91180f490a9632fefa947e6ccffae36a0c6f06abe0d66c1bf2e2982e0cae9327d075b74922afdbc415ca229792b42f8d24908fbedc86ee + checksum: be6bc86fb226681246d80749b44212d5a1a53a8fa81a5c09150383ce464f36350e1d297dc6d14f10b0c60e96af975b54c532c9dd3445f60454724199ac8c75e5 languageName: node linkType: hard -"@react-navigation/native@npm:7.1.19": - version: 7.1.19 - resolution: "@react-navigation/native@npm:7.1.19" +"@react-navigation/native@npm:7.1.20": + version: 7.1.20 + resolution: "@react-navigation/native@npm:7.1.20" dependencies: - "@react-navigation/core": ^7.13.0 + "@react-navigation/core": ^7.13.1 escape-string-regexp: ^4.0.0 fast-deep-equal: ^3.1.3 nanoid: ^3.3.11 @@ -3488,7 +3488,7 @@ __metadata: peerDependencies: react: ">= 18.2.0" react-native: "*" - checksum: 3215388017fef5ec6ecca19a128ef11d8b535f7534bfff15f931773b6849b2ee4ed0914c69eb264132e597700368df97d8991cf19d84f7d18ef1a0abd3ec6db6 + checksum: dc005928ca887468774d5a912d93c35ff029b787871d7a22969f1b8a2263befd14780658e0da186c6ce6993a3fc55c0947d702117a80c614802d45873c8ac5c5 languageName: node linkType: hard @@ -3501,20 +3501,21 @@ __metadata: languageName: node linkType: hard -"@react-navigation/stack@npm:7.6.3": - version: 7.6.3 - resolution: "@react-navigation/stack@npm:7.6.3" +"@react-navigation/stack@npm:7.6.4": + version: 7.6.4 + resolution: "@react-navigation/stack@npm:7.6.4" dependencies: - "@react-navigation/elements": ^2.8.1 + "@react-navigation/elements": ^2.8.2 color: ^4.2.3 + use-latest-callback: ^0.2.4 peerDependencies: - "@react-navigation/native": ^7.1.19 + "@react-navigation/native": ^7.1.20 react: ">= 18.2.0" react-native: "*" react-native-gesture-handler: ">= 2.0.0" react-native-safe-area-context: ">= 4.0.0" react-native-screens: ">= 4.0.0" - checksum: 6e74a8bda940abcdeb303b259acaa601749fbfdc35245f5f31f82c06680178710e58db62ca895fd3b9f2cfed39e652e01b01db32e529fbefd60adc576bd9d197 + checksum: 693a662451ff492b2b6aad8d398414722cd23e4d5c76110269f2eb016fda881a7d6aba003fd483723be58c5f5f50e9553fa8cd02d95d798e331008c0e997e1ef languageName: node linkType: hard @@ -3639,7 +3640,32 @@ __metadata: languageName: node linkType: hard -"@semantic-release/npm@npm:13.1.1, @semantic-release/npm@npm:^13.1.1": +"@semantic-release/npm@npm:13.1.2": + version: 13.1.2 + resolution: "@semantic-release/npm@npm:13.1.2" + dependencies: + "@actions/core": ^1.11.1 + "@semantic-release/error": ^4.0.0 + aggregate-error: ^5.0.0 + env-ci: ^11.2.0 + execa: ^9.0.0 + fs-extra: ^11.0.0 + lodash-es: ^4.17.21 + nerf-dart: ^1.0.0 + normalize-url: ^8.0.0 + npm: ^11.6.2 + rc: ^1.2.8 + read-pkg: ^10.0.0 + registry-auth-token: ^5.0.0 + semver: ^7.1.2 + tempy: ^3.0.0 + peerDependencies: + semantic-release: ">=20.1.0" + checksum: 6d916dc0cf01022c91e916dca6a16c2fada25bdabbcb7c6a6a8371120c7d0710368b1cc858cc95e574adc011d20839a49ccebbbacc38e689c32073f49604a91e + languageName: node + linkType: hard + +"@semantic-release/npm@npm:^13.1.1": version: 13.1.1 resolution: "@semantic-release/npm@npm:13.1.1" dependencies: @@ -9610,90 +9636,90 @@ __metadata: languageName: node linkType: hard -"lefthook-darwin-arm64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-darwin-arm64@npm:2.0.3" +"lefthook-darwin-arm64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-darwin-arm64@npm:2.0.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lefthook-darwin-x64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-darwin-x64@npm:2.0.3" +"lefthook-darwin-x64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-darwin-x64@npm:2.0.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lefthook-freebsd-arm64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-freebsd-arm64@npm:2.0.3" +"lefthook-freebsd-arm64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-freebsd-arm64@npm:2.0.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"lefthook-freebsd-x64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-freebsd-x64@npm:2.0.3" +"lefthook-freebsd-x64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-freebsd-x64@npm:2.0.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lefthook-linux-arm64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-linux-arm64@npm:2.0.3" +"lefthook-linux-arm64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-linux-arm64@npm:2.0.4" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"lefthook-linux-x64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-linux-x64@npm:2.0.3" +"lefthook-linux-x64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-linux-x64@npm:2.0.4" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"lefthook-openbsd-arm64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-openbsd-arm64@npm:2.0.3" +"lefthook-openbsd-arm64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-openbsd-arm64@npm:2.0.4" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"lefthook-openbsd-x64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-openbsd-x64@npm:2.0.3" +"lefthook-openbsd-x64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-openbsd-x64@npm:2.0.4" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"lefthook-windows-arm64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-windows-arm64@npm:2.0.3" +"lefthook-windows-arm64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-windows-arm64@npm:2.0.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lefthook-windows-x64@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook-windows-x64@npm:2.0.3" +"lefthook-windows-x64@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook-windows-x64@npm:2.0.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"lefthook@npm:2.0.3": - version: 2.0.3 - resolution: "lefthook@npm:2.0.3" - dependencies: - lefthook-darwin-arm64: 2.0.3 - lefthook-darwin-x64: 2.0.3 - lefthook-freebsd-arm64: 2.0.3 - lefthook-freebsd-x64: 2.0.3 - lefthook-linux-arm64: 2.0.3 - lefthook-linux-x64: 2.0.3 - lefthook-openbsd-arm64: 2.0.3 - lefthook-openbsd-x64: 2.0.3 - lefthook-windows-arm64: 2.0.3 - lefthook-windows-x64: 2.0.3 +"lefthook@npm:2.0.4": + version: 2.0.4 + resolution: "lefthook@npm:2.0.4" + dependencies: + lefthook-darwin-arm64: 2.0.4 + lefthook-darwin-x64: 2.0.4 + lefthook-freebsd-arm64: 2.0.4 + lefthook-freebsd-x64: 2.0.4 + lefthook-linux-arm64: 2.0.4 + lefthook-linux-x64: 2.0.4 + lefthook-openbsd-arm64: 2.0.4 + lefthook-openbsd-x64: 2.0.4 + lefthook-windows-arm64: 2.0.4 + lefthook-windows-x64: 2.0.4 dependenciesMeta: lefthook-darwin-arm64: optional: true @@ -9717,7 +9743,7 @@ __metadata: optional: true bin: lefthook: bin/index.js - checksum: 647e13826c3eed30453734eb8d932f196c7f1334559bd8ef01dce4a07b0ce64e356eddfbb552b827d6dc25e4be15fb564ee6b2f7483de70890b8fb131468a677 + checksum: 9d509469703d318df716a1c3f667059840d823809aabccec5239b6a2e0e5ede1cb1f6be539e258a8908a4dc7a38d554c036d08880d28021f827c1c3140dc9a6f languageName: node linkType: hard @@ -12267,9 +12293,9 @@ __metadata: "@react-native/babel-preset": 0.82.1 "@react-native/metro-config": 0.82.1 "@react-native/typescript-config": 0.82.1 - "@react-navigation/native": 7.1.19 - "@react-navigation/native-stack": 7.6.2 - "@react-navigation/stack": 7.6.3 + "@react-navigation/native": 7.1.20 + "@react-navigation/native-stack": 7.6.3 + "@react-navigation/stack": 7.6.4 "@types/react": 19.1.1 babel-plugin-module-resolver: 5.0.2 react: 19.1.1 @@ -12304,7 +12330,7 @@ __metadata: "@semantic-release/changelog": 6.0.3 "@semantic-release/exec": 7.1.0 "@semantic-release/git": 10.0.1 - "@semantic-release/npm": 13.1.1 + "@semantic-release/npm": 13.1.2 "@types/jest": 30.0.0 "@types/react": 19.1.1 conventional-changelog-conventionalcommits: 9.1.0 @@ -12316,7 +12342,7 @@ __metadata: eslint-plugin-prettier: 5.5.4 eslint-plugin-unused-imports: 4.3.0 jest: 30.2.0 - lefthook: 2.0.3 + lefthook: 2.0.4 nitrogen: 0.31.6 prettier: 3.6.2 react: 19.1.1 From 0f3fa22978bb77cacbccb7d143f7c516c0627cec Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 17 Nov 2025 22:04:12 +0700 Subject: [PATCH 28/40] chore: update PR template --- .github/pull_request_template.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index cc491ce..f0deeac 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ ## Pull request -Please ensure this PR targets the **`dev` branch** and follows the project conventions. +Please ensure this PR targets the **`dev` branch** and follows the project conventions. CI already runs linting, formatting, and build checks automatically. --- @@ -33,7 +33,7 @@ Short description of what this PR changes or adds. - [ ] Android - [ ] iOS -- [ ] Core +- [ ] JS - [ ] Example App - [ ] Docs @@ -41,8 +41,8 @@ Short description of what this PR changes or adds. ### Related -List any related issues, pull requests, or discussions. -Use the format: +List any related issues, pull requests, or discussions. +Use the format: `Fixes #123`, `Refs #456`, `Close #789` --- From bb7d196480e6891d1276dc65f4e79eb59d2e1e45 Mon Sep 17 00:00:00 2001 From: pinpong Date: Mon, 17 Nov 2025 22:14:53 +0700 Subject: [PATCH 29/40] fix: trigger release From f5358b72f7b2db93d02339b8580355b66ce79b05 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 09:15:48 +0700 Subject: [PATCH 30/40] fix(ios): traffic enabled --- ios/GoogleMapViewImpl.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/GoogleMapViewImpl.swift b/ios/GoogleMapViewImpl.swift index a0702ec..041311c 100644 --- a/ios/GoogleMapViewImpl.swift +++ b/ios/GoogleMapViewImpl.swift @@ -221,7 +221,7 @@ GMSIndoorDisplayDelegate { @MainActor var trafficEnabled: Bool? { didSet { - mapView?.isTrafficEnabled = false + mapView?.isTrafficEnabled = trafficEnabled ?? false } } From 2761229db7badbcfc7c4914fe998b2fa92cb2762 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 09:23:21 +0700 Subject: [PATCH 31/40] fix(android): location updates now fully controlled by lifecycle --- .../src/main/java/com/rngooglemapsplus/LocationHandler.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt index ce9fa7a..095ade0 100644 --- a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +++ b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt @@ -56,6 +56,8 @@ class LocationHandler( this.interval = interval ?: INTERVAL_DEFAULT this.minUpdateInterval = minUpdateInterval ?: MIN_UPDATE_INTERVAL buildLocationRequest(this.priority, this.interval, this.minUpdateInterval) + + if (!isActive) return stop() start() } @@ -173,7 +175,7 @@ class LocationHandler( val error = e.toLocationErrorCode(context) onError?.invoke(error) } - } catch (se: SecurityException) { + } catch (_: SecurityException) { onError?.invoke(RNLocationErrorCode.PERMISSION_DENIED) } catch (ex: Exception) { val error = ex.toLocationErrorCode(context) @@ -193,11 +195,9 @@ class LocationHandler( override fun activate(listener: LocationSource.OnLocationChangedListener) { this.listener = listener - start() } override fun deactivate() { listener = null - stop() } } From 3df1eed30a21300abc4238658225b229c7b6e879 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 09:24:40 +0700 Subject: [PATCH 32/40] fix(ios): mapview deinit --- ios/GoogleMapViewImpl.swift | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/ios/GoogleMapViewImpl.swift b/ios/GoogleMapViewImpl.swift index 041311c..6f77f7a 100644 --- a/ios/GoogleMapViewImpl.swift +++ b/ios/GoogleMapViewImpl.swift @@ -10,8 +10,8 @@ GMSIndoorDisplayDelegate { private let locationHandler: LocationHandler private let markerBuilder: MapMarkerBuilder private var mapView: GMSMapView? - private var initialized = false - private var loaded = false + private var mapViewInitialized = false + private var mapViewLoaded = false private var deInitialized = false private var pendingMarkers: [(id: String, marker: GMSMarker)] = [] @@ -97,8 +97,8 @@ GMSIndoorDisplayDelegate { @MainActor func initMapView() { - if initialized { return } - initialized = true + if mapViewInitialized { return } + mapViewInitialized = true googleMapOptions.frame = bounds mapView = GMSMapView.init(options: googleMapOptions) @@ -717,7 +717,6 @@ GMSIndoorDisplayDelegate { self.mapView?.indoorDisplay.delegate = nil self.mapView?.delegate = nil self.mapView = nil - self.initialized = false } } @@ -752,8 +751,8 @@ GMSIndoorDisplayDelegate { } func mapViewDidFinishTileRendering(_ mapView: GMSMapView) { - guard !loaded else { return } - loaded = true + guard !mapViewLoaded else { return } + mapViewLoaded = true let visibleRegion = mapView.projection.visibleRegion().toRNRegion() let camera = mapView.camera.toRNCamera() @@ -761,7 +760,7 @@ GMSIndoorDisplayDelegate { } func mapView(_ mapView: GMSMapView, willMove gesture: Bool) { - if !loaded { return } + if !mapViewLoaded { return } onMain { self.cameraMoveReasonIsGesture = gesture @@ -773,7 +772,7 @@ GMSIndoorDisplayDelegate { } func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) { - if !loaded { return } + if !mapViewLoaded { return } onMain { let visibleRegion = mapView.projection.visibleRegion().toRNRegion() let camera = mapView.camera.toRNCamera() @@ -784,7 +783,7 @@ GMSIndoorDisplayDelegate { } func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) { - if !loaded { return } + if !mapViewLoaded { return } onMain { let visibleRegion = mapView.projection.visibleRegion().toRNRegion() let camera = mapView.camera.toRNCamera() From 5afeb22daa6493ef73a902ef2f43a7966b7d954d Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 09:25:13 +0700 Subject: [PATCH 33/40] fix(android): mapview onDestroy --- android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt index 7769d06..83c58ad 100644 --- a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +++ b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt @@ -845,7 +845,6 @@ class GoogleMapsViewImpl( mapView?.removeAllViews() super.removeAllViews() reactContext.unregisterComponentCallbacks(componentCallbacks) - mapViewInitialized = false } override fun requestLayout() { From 89884db59766021a1a6525a611f08ba5f2f97f56 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 15:41:14 +0700 Subject: [PATCH 34/40] fix(android): forward last known location to LocationSource listener --- .../com/rngooglemapsplus/LocationHandler.kt | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt index 095ade0..4eae1df 100644 --- a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +++ b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt @@ -19,7 +19,6 @@ import com.google.android.gms.location.LocationServices import com.google.android.gms.location.LocationSettingsRequest import com.google.android.gms.location.Priority import com.google.android.gms.maps.LocationSource -import com.google.android.gms.tasks.OnSuccessListener import com.rngooglemapsplus.extensions.toLocationErrorCode private const val REQ_LOCATION_SETTINGS = 2001 @@ -144,13 +143,12 @@ class LocationHandler( } try { fusedLocationClientProviderClient.lastLocation - .addOnSuccessListener( - OnSuccessListener { location -> - if (location != null) { - onUpdate?.invoke(location) - } - }, - ).addOnFailureListener { e -> + .addOnSuccessListener { location -> + if (location != null) { + listener?.onLocationChanged(location) + onUpdate?.invoke(location) + } + }.addOnFailureListener { e -> val error = e.toLocationErrorCode(context) onError?.invoke(error) } @@ -166,14 +164,14 @@ class LocationHandler( } } } + + val req = locationRequest ?: return + val callback = locationCallback ?: return + fusedLocationClientProviderClient - .requestLocationUpdates( - locationRequest!!, - locationCallback!!, - Looper.getMainLooper(), - ).addOnFailureListener { e -> - val error = e.toLocationErrorCode(context) - onError?.invoke(error) + .requestLocationUpdates(req, callback, Looper.getMainLooper()) + .addOnFailureListener { e -> + onError?.invoke(e.toLocationErrorCode(context)) } } catch (_: SecurityException) { onError?.invoke(RNLocationErrorCode.PERMISSION_DENIED) @@ -186,11 +184,10 @@ class LocationHandler( fun stop() { if (!isActive) return isActive = false - if (locationCallback != null) { - fusedLocationClientProviderClient.removeLocationUpdates(locationCallback!!) - fusedLocationClientProviderClient.flushLocations() - locationCallback = null - } + val callback = locationCallback ?: return + fusedLocationClientProviderClient.removeLocationUpdates(callback) + fusedLocationClientProviderClient.flushLocations() + locationCallback = null } override fun activate(listener: LocationSource.OnLocationChangedListener) { From cec18d7cc8fe7e5f26ad911deab93a86e8a6b490 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 18:04:31 +0700 Subject: [PATCH 35/40] chore(example): remove log --- example/src/hooks/useNitroCallback.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/example/src/hooks/useNitroCallback.ts b/example/src/hooks/useNitroCallback.ts index 947e947..674338f 100644 --- a/example/src/hooks/useNitroCallback.ts +++ b/example/src/hooks/useNitroCallback.ts @@ -7,7 +7,6 @@ export function useNitroCallback void>( fallback?: (...args: Parameters) => void ) { return useMemo(() => { - console.log('useNitroCallback'); const fn = (...args: Parameters) => { propCallback?.(...args); fallback?.(...args); From 73c065996fb06940d0a65ebe7ebf4ca9fdf95ef7 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 18:06:58 +0700 Subject: [PATCH 36/40] fix(android): isMyLocationButtonEnabled and use always custom LocationSource --- .../main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt index 83c58ad..09d4a31 100644 --- a/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +++ b/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt @@ -152,6 +152,7 @@ class GoogleMapsViewImpl( super.addView(it) it.getMapAsync { map -> googleMap = map + googleMap?.setLocationSource(locationHandler) googleMap?.setOnMapLoadedCallback { googleMap?.setOnCameraMoveStartedListener(this@GoogleMapsViewImpl) googleMap?.setOnCameraMoveListener(this@GoogleMapsViewImpl) @@ -288,11 +289,7 @@ class GoogleMapsViewImpl( isCompassEnabled = value?.compassEnabled ?: false isIndoorLevelPickerEnabled = value?.indoorLevelPickerEnabled ?: false isMapToolbarEnabled = value?.mapToolbarEnabled ?: false - - val myLocationEnabled = value?.myLocationButtonEnabled ?: false - googleMap?.setLocationSource(if (myLocationEnabled) locationHandler else null) - isMyLocationButtonEnabled = myLocationEnabled - + isMyLocationButtonEnabled = value?.myLocationButtonEnabled ?: false isRotateGesturesEnabled = value?.rotateEnabled ?: true isScrollGesturesEnabled = value?.scrollEnabled ?: true isScrollGesturesEnabledDuringRotateOrZoom = From 6d15e4c2304a2b0c686e95e00ef781dad4c2c17e Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 18:45:07 +0700 Subject: [PATCH 37/40] fix(ios): request immediate location update instead of using last known --- ios/LocationHandler.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ios/LocationHandler.swift b/ios/LocationHandler.swift index 50468a1..dca4a3e 100644 --- a/ios/LocationHandler.swift +++ b/ios/LocationHandler.swift @@ -85,10 +85,7 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate { guard !isActive else { return } isActive = true - manager.location.map { - onUpdate?($0) - } - + manager.requestLocation() manager.startUpdatingLocation() } From 873c034a8eda9557ecfc543b437710881770bf0d Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 18:45:41 +0700 Subject: [PATCH 38/40] fix(android): request immediate location update instead of using last known --- .../java/com/rngooglemapsplus/LocationHandler.kt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt index 4eae1df..5e03ffb 100644 --- a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +++ b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt @@ -34,10 +34,12 @@ class LocationHandler( private var listener: LocationSource.OnLocationChangedListener? = null private var locationRequest: LocationRequest? = null private var locationCallback: LocationCallback? = null + private var lastLocation: Location? = null + private var isActive = false + private var priority: Int = PRIORITY_DEFAULT private var interval: Long = INTERVAL_DEFAULT private var minUpdateInterval: Long = MIN_UPDATE_INTERVAL - private var isActive = false var onUpdate: ((Location) -> Unit)? = null var onError: ((RNLocationErrorCode) -> Unit)? = null @@ -142,21 +144,23 @@ class LocationHandler( return } try { - fusedLocationClientProviderClient.lastLocation + fusedLocationClientProviderClient + .getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null) .addOnSuccessListener { location -> if (location != null) { + lastLocation = location listener?.onLocationChanged(location) onUpdate?.invoke(location) } }.addOnFailureListener { e -> - val error = e.toLocationErrorCode(context) - onError?.invoke(error) + onError?.invoke(e.toLocationErrorCode(context)) } locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { val location = locationResult.lastLocation if (location != null) { + lastLocation = location listener?.onLocationChanged(location) onUpdate?.invoke(location) } else { @@ -192,6 +196,9 @@ class LocationHandler( override fun activate(listener: LocationSource.OnLocationChangedListener) { this.listener = listener + lastLocation?.let { + listener.onLocationChanged(it) + } } override fun deactivate() { From dbd13a102d04c623edac7706b8b161bec5976f35 Mon Sep 17 00:00:00 2001 From: pinpong Date: Tue, 18 Nov 2025 20:16:56 +0700 Subject: [PATCH 39/40] fix(android): prevent same location update --- .../com/rngooglemapsplus/LocationHandler.kt | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt index 5e03ffb..fd7d517 100644 --- a/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +++ b/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt @@ -130,6 +130,17 @@ class LocationHandler( } } + private fun isNewerLocation(location: Location): Boolean { + val prev = lastLocation ?: return true + return location.elapsedRealtimeNanos > prev.elapsedRealtimeNanos + } + + private fun notifyListener(location: Location) { + lastLocation = location + listener?.onLocationChanged(location) + onUpdate?.invoke(location) + } + @SuppressLint("MissingPermission") fun start() { if (isActive) return @@ -147,11 +158,9 @@ class LocationHandler( fusedLocationClientProviderClient .getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null) .addOnSuccessListener { location -> - if (location != null) { - lastLocation = location - listener?.onLocationChanged(location) - onUpdate?.invoke(location) - } + if (location == null) return@addOnSuccessListener + if (!isNewerLocation(location)) return@addOnSuccessListener + notifyListener(location) }.addOnFailureListener { e -> onError?.invoke(e.toLocationErrorCode(context)) } @@ -160,9 +169,8 @@ class LocationHandler( override fun onLocationResult(locationResult: LocationResult) { val location = locationResult.lastLocation if (location != null) { - lastLocation = location - listener?.onLocationChanged(location) - onUpdate?.invoke(location) + if (!isNewerLocation(location)) return + notifyListener(location) } else { onError?.invoke(RNLocationErrorCode.POSITION_UNAVAILABLE) } From 94f62e73644a7d2e3a23f8bfb0730c270a381a4d Mon Sep 17 00:00:00 2001 From: pinpong Date: Wed, 19 Nov 2025 16:32:18 +0700 Subject: [PATCH 40/40] ci: set xcode version to 26.0.1 --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 86b42da..a1c93cb 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -95,7 +95,7 @@ jobs: runs-on: macos-latest needs: [lint, test] env: - XCODE_VERSION: latest-stable + XCODE_VERSION: '26.0.1' steps: - name: Checkout uses: actions/checkout@v5.0.0