Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cloud tile fetching logic #2456

Merged
merged 4 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions examples/demo-app/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,13 @@ export function onExportFileSuccess({response = {}, provider, options}) {
};
}

export function onLoadCloudMapSuccess({response, provider, loadParams}) {
export function onLoadCloudMapSuccess({provider, loadParams}) {
return dispatch => {
if (provider.getMapUrl) {
const mapUrl = provider.getMapUrl(false, loadParams);
dispatch(push(mapUrl));
const mapUrl = provider?.getMapUrl(loadParams);
debugger;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove debugger;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course

if (mapUrl) {
const url = `demo/map/${provider.name}?path=${mapUrl}`;
dispatch(push(url));
}
};
}
Expand Down
10 changes: 9 additions & 1 deletion examples/demo-app/src/cloud-providers/carto/carto-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export default class CartoProvider extends Provider {
* Returns the access token. If it has expired returns null. The toolkit library loads it
* from localStorage automatically
*/
getAccessToken() {
async getAccessToken() {
let accessToken = null;
try {
accessToken = this._carto.oauth.expired ? null : this._carto.oauth.token;
Expand Down Expand Up @@ -194,6 +194,14 @@ export default class CartoProvider extends Provider {
return;
}

async getUser() {
return {
name: this.getUserName(),
abbreviated: '',
email: ''
}
}

async downloadMap(queryParams) {
try {
const {owner: username, mapId, privateMap} = queryParams;
Expand Down
27 changes: 8 additions & 19 deletions examples/demo-app/src/cloud-providers/dropbox/dropbox-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,39 +199,31 @@ export default class DropboxProvider extends Provider {
return await this._shareFile(metadata);
}

// save private map save map url
this._loadParam = {path: metadata.path_lower};

return this._loadParam;
return {id: metadata.id, path: metadata.path_lower};
}

/**
* download the map content
* @param loadParams
*/
async downloadMap(loadParams) {
const token = this.getAccessToken();
if (!token) {
this.login(() => this.downloadMap(loadParams));
}
const result = await this._dropbox.filesDownload(loadParams);
const {path} = loadParams;
const result = await this._dropbox.filesDownload({path});
const json = await this._readFile(result.fileBlob);

const response = {
map: json,
format: KEPLER_FORMAT
};

this._loadParam = loadParams;
return Promise.resolve(response);
}

getUserName() {
// load user from
if (window.localStorage) {
const jsonString = window.localStorage.getItem('dropbox');
const user = jsonString && JSON.parse(jsonString).user;
return user;
return jsonString && JSON.parse(jsonString).user;
}
return null;
}
Expand Down Expand Up @@ -269,14 +261,10 @@ export default class DropboxProvider extends Provider {

/**
* Get the map url of current map, this url can only be accessed by current logged in user
* @param {boolean} fullUrl
*/
getMapUrl(fullURL = true) {
const {path} = this._loadParam;
const mapLink = `demo/map/dropbox?path=${path}`;
return fullURL
? `${window.location.protocol}//${window.location.host}/${mapLink}`
: `/${mapLink}`;
getMapUrl(loadParams) {
const {path} = loadParams;
return path;
}

getManagementUrl() {
Expand Down Expand Up @@ -475,6 +463,7 @@ export default class DropboxProvider extends Provider {
id,
updatedAt: new Date(client_modified).getTime(),
loadParams: {
id,
path: path_lower
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import FSQIcon from './foursquare-icon';
import {Provider, KEPLER_FORMAT} from '@kepler.gl/cloud-providers';
import {Auth0Client} from '@auth0/auth0-spa-js';

const NAME = 'Foursquare';
const NAME = 'foursquare';
const DISPLAY_NAME = 'Foursquare';
const APP_NAME = 'Kepler.gl';

Expand All @@ -18,15 +18,16 @@ const FOURSQUARE_KEPLER_GL_IMPORT_SOURCE = 'kepler.gl-raw';
* @param model Foursquare Map
* @return {MapItem} Map
*/
function convertFSQModelToMapItem(model) {
function convertFSQModelToMapItem(model, baseApi) {
return {
id: model.id,
title: model.name,
thumbnail: model.previewReadPath,
updatedAt: model.updatedAt,
description: model.description,
loadParams: {
mapId: model.id
id: model.id,
path: `${baseApi}/${model.id}`
}
};
}
Expand All @@ -45,14 +46,12 @@ export default class FoursquareProvider extends Provider {
this.appName = APP_NAME;
this.apiURL = apiURL;

const redirect_uri = window.location.origin + window.location.pathname;

this._auth0 = new Auth0Client({
domain: authDomain,
clientId: clientId,
scope: FOURSQUARE_AUTH_SCOPE,
authorizationParams: {
redirect_uri,
redirect_uri: window.location.origin,
audience: FOURSQUARE_AUTH_AUDIENCE
},
cacheLocation: 'localstorage'
Expand Down Expand Up @@ -133,17 +132,17 @@ export default class FoursquareProvider extends Provider {
}
);
const data = await response.json();
return data.items.map(convertFSQModelToMapItem);
return data.items.map(map => convertFSQModelToMapItem(map, `${this.apiURL}/v1/maps`));
}

async downloadMap(loadParams) {
const {mapId} = loadParams;
if (!mapId) {
const {id} = loadParams;
if (!id) {
return Promise.reject('No Map is was provider as part of loadParams');
}
const headers = await this.getHeaders();

const response = await fetch(`${this.apiURL}/v1/maps/${mapId}`, {
const response = await fetch(`${this.apiURL}/v1/maps/${id}`, {
method: 'GET',
headers
});
Expand All @@ -156,6 +155,11 @@ export default class FoursquareProvider extends Provider {
});
}

getMapUrl(loadParams) {
const {id} = loadParams;
return `${this.apiURL}/v1/maps/${id}`;
}

getManagementUrl() {
return this._folderLink;
}
Expand Down
7 changes: 0 additions & 7 deletions examples/demo-app/src/cloud-providers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ const {
FOURSQUARE_USER_MAPS_URL
} = CLOUD_PROVIDERS_CONFIGURATION;

console.log('provider index', {
clientId: FOURSQUARE_CLIENT_ID,
authDomain: FOURSQUARE_DOMAIN,
apiURL: FOURSQUARE_API_URL,
userMapsURL: FOURSQUARE_USER_MAPS_URL
});

const DROPBOX_CLIENT_NAME = 'Kepler.gl Demo App';

export const DEFAULT_CLOUD_PROVIDER = 'dropbox';
Expand Down
2 changes: 1 addition & 1 deletion src/cloud-providers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@

export {default as Provider, FILE_CONFLICT_MSG, KEPLER_FORMAT} from './provider';
// eslint-disable-next-line prettier/prettier
export type {MapListItem, Thumbnail, ProviderProps, IconProps} from './provider';
export type {MapListItem, Thumbnail, ProviderProps, IconProps, CloudUser} from './provider';
export {default as Upload} from './upload';
12 changes: 8 additions & 4 deletions src/cloud-providers/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import Upload from './upload';
import {MapData, ExportFileOptions, Millisecond, SavedMap} from '@kepler.gl/types';
import {ComponentType} from 'react';

export type MapItemLoadParams = {
id: string;
path: string;
};

export type MapListItem = {
id: string;
title: string;
Expand Down Expand Up @@ -125,11 +130,10 @@ export default class Provider {

/**
* This method is called by kepler.gl demo app to pushes a new location to history, becoming the current location.
* @param fullURL - Whether to return the full url with domain, or just the location
* @returns mapUrl
* @public
*/
getMapUrl(fullURL: boolean = true): string {
getMapUrl(loadParams: MapItemLoadParams): string {
return '';
}

Expand All @@ -138,7 +142,7 @@ export default class Provider {
* @public
* @returns {Promise<string>} return the access token if a user already logged in
*/
getAccessToken(): Promise<string> {
async getAccessToken(): Promise<string | null> {
return Promise.reject('You must implement getAccessToken');
}

Expand All @@ -155,7 +159,7 @@ export default class Provider {
/**
* return a Promise with the user object
*/
getUser(): Promise<CloudUser> {
async getUser(): Promise<CloudUser | null> {
return Promise.reject('You must implement getUser');
}

Expand Down
46 changes: 30 additions & 16 deletions src/components/src/modals/cloud-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import React, {useCallback, useEffect, useState} from 'react';
import styled from 'styled-components';
import {Logout, Login} from '../common/icons';
import {CenterVerticalFlexbox, Button, CheckMark} from '../common/styled-components';
import {Provider} from '@kepler.gl/cloud-providers';
import {Provider, CloudUser} from '@kepler.gl/cloud-providers';
import {useCloudListProvider} from '../hooks/use-cloud-list-provider';
import {CloudUser} from '@kepler.gl/cloud-providers/src/provider';

interface StyledTileWrapperProps {
selected?: boolean;
Expand Down Expand Up @@ -93,7 +92,11 @@ const NewTag = styled.div`
z-index: 500;
font-size: 11px;
line-height: 10px;
;
`;

export const StyledWarning = styled.span`
color: ${props => props.theme.errorColor};
font-weight: ${props => props.theme.selectFontWeightBold};
`;

interface CloudTileProps {
Expand All @@ -116,16 +119,20 @@ const CloudTile: React.FC<CloudTileProps> = ({provider, actionName}) => {
const isSelected = provider === currentProvider;

useEffect(() => {
if (provider) {
setError(null);
setIsLoading(true);
setError(null);
provider
.getUser()
.then(user => setUser(user))
.catch(setError)
.finally(() => setIsLoading(false));
if (!provider) {
return;
}
setError(null);
setIsLoading(true);
setError(null);
provider
.getUser()
.then(setUser)
.catch(setError)
.finally(() => {
setError(null);
setIsLoading(false);
});
}, [provider]);

const onLogin = useCallback(async () => {
Expand All @@ -145,10 +152,17 @@ const CloudTile: React.FC<CloudTileProps> = ({provider, actionName}) => {
if (isLoading) {
return;
}
if (!user) {
if (user) {
setProvider(provider);
return;
}
try {
await onLogin();
setProvider(provider);
} catch (err) {
setError(err as Error);
setProvider(null);
}
setProvider(provider);
}, [setProvider, provider, user, isLoading]);

const onLogout = useCallback(async () => {
Expand Down Expand Up @@ -179,8 +193,8 @@ const CloudTile: React.FC<CloudTileProps> = ({provider, actionName}) => {
)}
{isSelected ? <CheckMark /> : null}
</StyledTileWrapper>
{user ? <LogoutButton onClick={onLogout} /> : <LoginButton onClick={onLogin} />}
{error ? <div>{error.message}</div> : null}
{user || error ? <LogoutButton onClick={onLogout} /> : <LoginButton onClick={onLogin} />}
{error ? <StyledWarning>{error.message}</StyledWarning> : null}
</StyledBox>
);
};
Expand Down