From ac9e2aedee942816591254a8e5cd9c50bc3a1831 Mon Sep 17 00:00:00 2001
From: Zhun Han
Date: Thu, 6 Feb 2025 20:37:59 +0000
Subject: [PATCH 1/3] chore:add InternalUsageAttributionIds
---
README.md | 11 +++++
src/components/api-provider.tsx | 59 +++++++++++++++++---------
src/components/map/use-map-instance.ts | 2 +
3 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/README.md b/README.md
index 077039f5..246832db 100644
--- a/README.md
+++ b/README.md
@@ -104,6 +104,17 @@ const App = () => {
);
};
```
+### Internal usage attribution ID
+
+This library uses [`internalUsageAttributionIds`](https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.internalUsageAttributionIds), which helps Google understand which libraries and
+samples are helpful to developers and is optional.
+
+To opt-out, use
+```
+
+
+
+```
## Examples
diff --git a/src/components/api-provider.tsx b/src/components/api-provider.tsx
index 90a28f7f..a1f3e1ab 100644
--- a/src/components/api-provider.tsx
+++ b/src/components/api-provider.tsx
@@ -5,14 +5,14 @@ import React, {
useEffect,
useMemo,
useReducer,
- useState
+ useState,
} from 'react';
+import {APILoadingStatus} from '../libraries/api-loading-status';
import {
ApiParams,
- GoogleMapsApiLoader
+ GoogleMapsApiLoader,
} from '../libraries/google-maps-api-loader';
-import {APILoadingStatus} from '../libraries/api-loading-status';
type ImportLibraryFunction = typeof google.maps.importLibrary;
type GoogleMapsLibrary = Awaited>;
@@ -29,6 +29,9 @@ export interface APIProviderContextValue {
}
const DEFAULT_SOLUTION_CHANNEL = 'GMP_visgl_rgmlibrary_v1_default';
+const DEFAULT_INTERNAL_USAGE_ATTRIBUTION_IDS = [
+ 'GMP_LIB_VISGL_REACT_GOOGLE_MAPS',
+];
export const APIProviderContext =
React.createContext(null);
@@ -81,6 +84,12 @@ export type APIProviderProps = PropsWithChildren<{
* [documentation](https://developers.google.com/maps/reporting-and-monitoring/reporting#usage-tracking-per-channel)
*/
solutionChannel?: string;
+ /**
+ * To help Google understand which libraries and samples are helpful to developers, such as usage of this library. To opt out of sending the usage attribution ID, it is safe to set this to `false`.
+ * Read more in the
+ * [documentation](https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.internalUsageAttributionIds)
+ */
+ useInternalUsageAttributionIds?: boolean;
/**
* A function that can be used to execute code after the Google Maps JavaScript API has been loaded.
*/
@@ -100,7 +109,7 @@ function useMapInstances() {
>({});
const addMapInstance = (mapInstance: google.maps.Map, id = 'default') => {
- setMapInstances(instances => ({...instances, [id]: mapInstance}));
+ setMapInstances((instances) => ({...instances, [id]: mapInstance}));
};
const removeMapInstance = (id = 'default') => {
@@ -126,28 +135,29 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
apiKey,
version,
libraries = [],
+ useInternalUsageAttributionIds = true,
...otherApiParams
} = props;
const [status, setStatus] = useState(
- GoogleMapsApiLoader.loadingStatus
+ GoogleMapsApiLoader.loadingStatus,
);
const [loadedLibraries, addLoadedLibrary] = useReducer(
(
loadedLibraries: LoadedLibraries,
- action: {name: keyof LoadedLibraries; value: LoadedLibraries[string]}
+ action: {name: keyof LoadedLibraries; value: LoadedLibraries[string]},
) => {
return loadedLibraries[action.name]
? loadedLibraries
: {...loadedLibraries, [action.name]: action.value};
},
- {}
+ {},
);
const librariesString = useMemo(() => libraries?.join(','), [libraries]);
const serializedParams = useMemo(
() => JSON.stringify({apiKey, version, ...otherApiParams}),
- [apiKey, version, otherApiParams]
+ [apiKey, version, otherApiParams],
);
const importLibrary: typeof google.maps.importLibrary = useCallback(
@@ -159,7 +169,7 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
if (!google?.maps?.importLibrary) {
throw new Error(
'[api-provider-internal] importLibrary was called before ' +
- 'google.maps.importLibrary was defined.'
+ 'google.maps.importLibrary was defined.',
);
}
@@ -168,7 +178,15 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
return res;
},
- [loadedLibraries]
+ [loadedLibraries],
+ );
+
+ const internalUsageAttributionIds = useMemo(
+ () =>
+ useInternalUsageAttributionIds
+ ? DEFAULT_INTERNAL_USAGE_ATTRIBUTION_IDS
+ : [],
+ [useInternalUsageAttributionIds],
);
useEffect(
@@ -190,7 +208,7 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
params.solutionChannel = DEFAULT_SOLUTION_CHANNEL;
else if (params.solutionChannel === '') delete params.solutionChannel;
- await GoogleMapsApiLoader.load(params, status => setStatus(status));
+ await GoogleMapsApiLoader.load(params, (status) => setStatus(status));
for (const name of ['core', 'maps', ...libraries]) {
await importLibrary(name);
@@ -205,32 +223,33 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
} else {
console.error(
' failed to load the Google Maps JavaScript API',
- error
+ error,
);
}
}
})();
},
// eslint-disable-next-line react-hooks/exhaustive-deps
- [apiKey, librariesString, serializedParams]
+ [apiKey, librariesString, serializedParams],
);
return {
status,
loadedLibraries,
- importLibrary
+ importLibrary,
+ internalUsageAttributionIds,
};
}
/**
* Component to wrap the components from this library and load the Google Maps JavaScript API
*/
-export const APIProvider: FunctionComponent = props => {
+export const APIProvider: FunctionComponent = (props) => {
const {children, ...loaderProps} = props;
const {mapInstances, addMapInstance, removeMapInstance, clearMapInstances} =
useMapInstances();
- const {status, loadedLibraries, importLibrary} =
+ const {status, loadedLibraries, importLibrary, internalUsageAttributionIds} =
useGoogleMapsApiLoader(loaderProps);
const contextValue: APIProviderContextValue = useMemo(
@@ -241,7 +260,8 @@ export const APIProvider: FunctionComponent = props => {
clearMapInstances,
status,
loadedLibraries,
- importLibrary
+ importLibrary,
+ internalUsageAttributionIds
}),
[
mapInstances,
@@ -250,8 +270,9 @@ export const APIProvider: FunctionComponent = props => {
clearMapInstances,
status,
loadedLibraries,
- importLibrary
- ]
+ importLibrary,
+ internalUsageAttributionIds
+ ],
);
return (
diff --git a/src/components/map/use-map-instance.ts b/src/components/map/use-map-instance.ts
index ffd27cfe..7cbd52ae 100644
--- a/src/components/map/use-map-instance.ts
+++ b/src/components/map/use-map-instance.ts
@@ -101,6 +101,8 @@ export function useMapInstance(
if (!mapOptions.tilt && Number.isFinite(defaultTilt))
mapOptions.tilt = defaultTilt;
+ mapOptions.internalUsageAttributionIds = context.internalUsageAttributionIds;
+
for (const key of Object.keys(mapOptions) as (keyof typeof mapOptions)[])
if (mapOptions[key] === undefined) delete mapOptions[key];
From 4bb5b2bbbe77d028fb5658d0fef1e31150465ddc Mon Sep 17 00:00:00 2001
From: Zhun Han
Date: Thu, 6 Feb 2025 20:53:12 +0000
Subject: [PATCH 2/3] fix: format.
---
README.md | 2 +-
src/components/api-provider.tsx | 30 +++++++++++++++---------------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
index 246832db..52f44a4e 100644
--- a/README.md
+++ b/README.md
@@ -111,7 +111,7 @@ samples are helpful to developers and is optional.
To opt-out, use
```
-
+
```
diff --git a/src/components/api-provider.tsx b/src/components/api-provider.tsx
index a1f3e1ab..6765ae8b 100644
--- a/src/components/api-provider.tsx
+++ b/src/components/api-provider.tsx
@@ -5,14 +5,14 @@ import React, {
useEffect,
useMemo,
useReducer,
- useState,
+ useState
} from 'react';
-import {APILoadingStatus} from '../libraries/api-loading-status';
import {
ApiParams,
- GoogleMapsApiLoader,
+ GoogleMapsApiLoader
} from '../libraries/google-maps-api-loader';
+import {APILoadingStatus} from '../libraries/api-loading-status';
type ImportLibraryFunction = typeof google.maps.importLibrary;
type GoogleMapsLibrary = Awaited>;
@@ -109,7 +109,7 @@ function useMapInstances() {
>({});
const addMapInstance = (mapInstance: google.maps.Map, id = 'default') => {
- setMapInstances((instances) => ({...instances, [id]: mapInstance}));
+ setMapInstances(instances => ({...instances, [id]: mapInstance}));
};
const removeMapInstance = (id = 'default') => {
@@ -140,24 +140,24 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
} = props;
const [status, setStatus] = useState(
- GoogleMapsApiLoader.loadingStatus,
+ GoogleMapsApiLoader.loadingStatus
);
const [loadedLibraries, addLoadedLibrary] = useReducer(
(
loadedLibraries: LoadedLibraries,
- action: {name: keyof LoadedLibraries; value: LoadedLibraries[string]},
+ action: {name: keyof LoadedLibraries; value: LoadedLibraries[string]}
) => {
return loadedLibraries[action.name]
? loadedLibraries
: {...loadedLibraries, [action.name]: action.value};
},
- {},
+ {}
);
const librariesString = useMemo(() => libraries?.join(','), [libraries]);
const serializedParams = useMemo(
() => JSON.stringify({apiKey, version, ...otherApiParams}),
- [apiKey, version, otherApiParams],
+ [apiKey, version, otherApiParams]
);
const importLibrary: typeof google.maps.importLibrary = useCallback(
@@ -169,7 +169,7 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
if (!google?.maps?.importLibrary) {
throw new Error(
'[api-provider-internal] importLibrary was called before ' +
- 'google.maps.importLibrary was defined.',
+ 'google.maps.importLibrary was defined.'
);
}
@@ -178,7 +178,7 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
return res;
},
- [loadedLibraries],
+ [loadedLibraries]
);
const internalUsageAttributionIds = useMemo(
@@ -208,7 +208,7 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
params.solutionChannel = DEFAULT_SOLUTION_CHANNEL;
else if (params.solutionChannel === '') delete params.solutionChannel;
- await GoogleMapsApiLoader.load(params, (status) => setStatus(status));
+ await GoogleMapsApiLoader.load(params, status => setStatus(status));
for (const name of ['core', 'maps', ...libraries]) {
await importLibrary(name);
@@ -223,28 +223,28 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
} else {
console.error(
' failed to load the Google Maps JavaScript API',
- error,
+ error
);
}
}
})();
},
// eslint-disable-next-line react-hooks/exhaustive-deps
- [apiKey, librariesString, serializedParams],
+ [apiKey, librariesString, serializedParams]
);
return {
status,
loadedLibraries,
importLibrary,
- internalUsageAttributionIds,
+ internalUsageAttributionIds
};
}
/**
* Component to wrap the components from this library and load the Google Maps JavaScript API
*/
-export const APIProvider: FunctionComponent = (props) => {
+export const APIProvider: FunctionComponent = props => {
const {children, ...loaderProps} = props;
const {mapInstances, addMapInstance, removeMapInstance, clearMapInstances} =
useMapInstances();
From e265e4617bf56d2763e83c6f8f0662e0955fc126 Mon Sep 17 00:00:00 2001
From: Zhun Han
Date: Fri, 7 Feb 2025 01:15:31 +0000
Subject: [PATCH 3/3] fix: use null as internalUsageAttributionIds' default
value instead of an empty array.
---
src/components/api-provider.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/api-provider.tsx b/src/components/api-provider.tsx
index 6765ae8b..7d90668a 100644
--- a/src/components/api-provider.tsx
+++ b/src/components/api-provider.tsx
@@ -185,7 +185,7 @@ function useGoogleMapsApiLoader(props: APIProviderProps) {
() =>
useInternalUsageAttributionIds
? DEFAULT_INTERNAL_USAGE_ATTRIBUTION_IDS
- : [],
+ : null,
[useInternalUsageAttributionIds],
);