diff --git a/README.md b/README.md index f70f68a0..6ad288ad 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ }); Add the following script in your `html` file ```html - + ``` Then initialize the Radar SDK @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then ```html - - + + @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis ```html - - + + @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper ```html - - + + diff --git a/package-lock.json b/package-lock.json index 165a70bb..7d344cac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "radar-sdk-js", - "version": "4.1.12", + "version": "4.1.12-beta.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "radar-sdk-js", - "version": "4.1.9", + "version": "4.1.12", "license": "ISC", "dependencies": { "@types/geojson": "^7946.0.10" diff --git a/package.json b/package.json index 65657085..351306fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radar-sdk-js", - "version": "4.1.12", + "version": "4.1.12-beta.5", "description": "Web Javascript SDK for Radar, location infrastructure for mobile and web apps.", "homepage": "https://radar.com", "type": "module", diff --git a/src/api/search.ts b/src/api/search.ts index 86c2bdcc..8c31ce30 100644 --- a/src/api/search.ts +++ b/src/api/search.ts @@ -9,6 +9,7 @@ import type { RadarSearchPlacesResponse, RadarSearchGeofencesParams, RadarSearchGeofencesResponse, + RadarAutocompleteSessionSelectionParams, } from '../types'; class SearchAPI { @@ -22,6 +23,7 @@ class SearchAPI { layers, countryCode, expandUnits, + sessionToken, } = params; // near can be provided as a string or Location object @@ -42,6 +44,7 @@ class SearchAPI { layers, countryCode, expandUnits, + sessionToken, }, }); @@ -56,6 +59,16 @@ class SearchAPI { return autocompleteRes; } + static async autocompleteSelect(params: RadarAutocompleteSessionSelectionParams) { + await Http.request({ + method: 'POST', + path: 'search/autocomplete/selection', + data: { + ...params + }, + }); + } + static async searchGeofences(params: RadarSearchGeofencesParams): Promise { const options = Config.get(); diff --git a/src/types.ts b/src/types.ts index 41cf76d0..439ae14e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -342,6 +342,23 @@ export interface RadarAutocompleteParams { layers?: RadarGeocodeLayer[]; countryCode?: string; expandUnits?: boolean; + sessionToken?: string; +} + +export interface RadarAutocompleteSessionSelectionParams { + sessionToken: string; + selectedIndex: number; + radarSessionId?: string; + userId?: string; + deviceId?: string; + installId?: string; + + query?: string; + near?: Location | string; + limit?: number; + layers?: RadarGeocodeLayer[]; + countryCode?: string; + expandUnits?: boolean; } export interface RadarAutocompleteResponse extends RadarResponse { diff --git a/src/ui/autocomplete.ts b/src/ui/autocomplete.ts index 506cff24..16f93b9c 100644 --- a/src/ui/autocomplete.ts +++ b/src/ui/autocomplete.ts @@ -1,8 +1,11 @@ import Logger from '../logger'; import SearchAPI from '../api/search'; +import Device from '../device'; +import Session from '../session'; +import Storage from '../storage'; import { RadarAutocompleteContainerNotFound } from '../errors'; -import type { RadarAutocompleteUIOptions, RadarAutocompleteConfig, RadarAutocompleteParams, Location } from '../types'; +import type { RadarAutocompleteUIOptions, RadarAutocompleteConfig, RadarAutocompleteParams, Location, RadarAutocompleteSessionSelectionParams } from '../types'; const CLASSNAMES = { WRAPPER: 'radar-autocomplete-wrapper', @@ -86,6 +89,8 @@ class AutocompleteUI { resultsList: HTMLElement; wrapper: HTMLElement; poweredByLink?: HTMLElement; + sessionToken?: string; + autocompleteParams?: RadarAutocompleteParams; // create a new AutocompleteUI instance public static createAutocomplete(autocompleteOptions: RadarAutocompleteUIOptions): AutocompleteUI { @@ -238,12 +243,18 @@ class AutocompleteUI { public async fetchResults(query: string) { const { limit, layers, countryCode, expandUnits, onRequest } = this.config; + if (!this.sessionToken) { + this.sessionToken = this.generateUUID(); + } + const sessionToken = this.sessionToken; + const params: RadarAutocompleteParams = { query, limit, layers, countryCode, expandUnits, + sessionToken, } if (this.near) { @@ -254,6 +265,8 @@ class AutocompleteUI { onRequest(params); } + this.autocompleteParams = params; // set previous params for autocomplete session selections + const { addresses } = await SearchAPI.autocomplete(params); return addresses; } @@ -442,6 +455,28 @@ class AutocompleteUI { onSelection(result); } + // Radar Autocomplete Session + if (this.sessionToken) { + const userId = Storage.getItem(Storage.USER_ID) || undefined; + const deviceId = Device.getDeviceId() || undefined; + const installId = Device.getInstallId() || undefined; + const radarSessionId = Session.getSessionId() || undefined; + const params: RadarAutocompleteSessionSelectionParams = { + sessionToken: this.sessionToken, + selectedIndex: index, + userId, + deviceId, + installId, + radarSessionId, + ...this.autocompleteParams + } + SearchAPI.autocompleteSelect(params); + } + + // Close out session + this.sessionToken = undefined; + this.autocompleteParams = undefined; + // clear results list this.close(); } @@ -511,6 +546,16 @@ class AutocompleteUI { return this; } + public generateUUID = (): string => { + const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) => { + const r = Math.random() * 16 | 0; + const v = (char == 'x') ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + + return uuid; + } + public setShowMarkers(showMarkers: boolean) { this.config.showMarkers = showMarkers; if (showMarkers) { diff --git a/src/version.ts b/src/version.ts index 316fc28e..264bb1e2 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export default '4.1.12'; +export default '4.1.12-beta.5';