-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
249 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
export const SET_GLOBE_PROJECTION = 'SET_GLOBE_PROJECTION'; | ||
|
||
export enum GlobeProjection { | ||
Sphere = 'Sphere', | ||
Mercator = 'Mercator', | ||
PlateCaree = 'PlateCaree' | ||
} | ||
|
||
export interface SetGlobeProjectionAction { | ||
type: typeof SET_GLOBE_PROJECTION; | ||
projection: GlobeProjection; | ||
} | ||
|
||
const setGlobeProjectionAction = ( | ||
projection: GlobeProjection | ||
): SetGlobeProjectionAction => ({ | ||
type: SET_GLOBE_PROJECTION, | ||
projection | ||
}); | ||
|
||
export default setGlobeProjectionAction; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import GlobeView from '../types/globe-view'; | ||
|
||
export const SET_GLOBE_VIEW = 'SET_GLOBE_VIEW'; | ||
|
||
export interface SetGlobeViewAction { | ||
type: typeof SET_GLOBE_VIEW; | ||
view: GlobeView; | ||
} | ||
|
||
const setGlobeViewAction = (view: GlobeView): SetGlobeViewAction => ({ | ||
type: SET_GLOBE_VIEW, | ||
view | ||
}); | ||
|
||
export default setGlobeViewAction; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {FunctionComponent, useEffect} from 'react'; | ||
import {useHistory, useLocation} from 'react-router-dom'; | ||
import {useSelector} from 'react-redux'; | ||
|
||
import {globeStateSelector} from '../../reducers/globe/index'; | ||
import {getParamString} from '../../libs/globe-url-parameter'; | ||
|
||
// syncs the query parameters of the url when values change in store | ||
const UrlSync: FunctionComponent<{}> = () => { | ||
const history = useHistory(); | ||
const location = useLocation(); | ||
const globeState = useSelector(globeStateSelector); | ||
|
||
// set globe query params in url when globe state changes | ||
useEffect(() => { | ||
const params = new URLSearchParams(location.search); | ||
const globeValue = getParamString(globeState); | ||
params.set('globe', globeValue); | ||
history.replace({search: params.toString()}); | ||
}, [globeState]); | ||
|
||
return null; | ||
}; | ||
|
||
export default UrlSync; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import {GlobeState} from '../reducers/globe/index'; | ||
import {GlobeProjection} from '../actions/set-globe-projection'; | ||
|
||
const char = 'l'; | ||
|
||
// parses window.location and generates a globe state from query params | ||
// | ||
// note: we do not use the location.search prop here because the HashRouter | ||
// stores the query parameters in the location.hash prop | ||
export function parseUrl(): GlobeState | null { | ||
const {hash} = location; | ||
// only take the query portion of the hash string | ||
const queryString = hash.substr(hash.indexOf('?')); | ||
const urlParams = new URLSearchParams(queryString); | ||
const globeParam = urlParams.get('globe'); | ||
|
||
if (!globeParam) { | ||
return null; | ||
} | ||
|
||
const splitted = globeParam.split(char); | ||
|
||
if (splitted.length !== 7) { | ||
return null; | ||
} | ||
|
||
// projection | ||
const projectionChar = splitted[0]; | ||
const projection = Object.values(GlobeProjection).find(proj => | ||
proj.startsWith(projectionChar) | ||
); | ||
|
||
if (!projection) { | ||
return null; | ||
} | ||
|
||
// globe view values | ||
const values = splitted.slice(1).map(str => parseFloat(str)); | ||
|
||
if (values.some(num => isNaN(num))) { | ||
return null; | ||
} | ||
|
||
return { | ||
view: { | ||
orientation: { | ||
heading: values[0], | ||
pitch: values[1], | ||
roll: values[2] | ||
}, | ||
destination: [values[3], values[4], values[5]] | ||
}, | ||
projection | ||
}; | ||
} | ||
|
||
export function getParamString(globeState: GlobeState): string { | ||
const {view, projection} = globeState; | ||
const {orientation, destination} = view; | ||
const {heading, pitch, roll} = orientation; | ||
|
||
const orientationString = [heading, pitch, roll] | ||
.map(num => num.toFixed(2)) | ||
.join(char); | ||
const destinationString = destination.map(num => Math.round(num)).join(char); | ||
|
||
return [projection[0], orientationString, destinationString].join(char); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import {combineReducers} from 'redux'; | ||
import projectionReducer from './projection'; | ||
import viewReducer from './view'; | ||
import {State} from '../index'; | ||
|
||
const globeReducer = combineReducers({ | ||
view: viewReducer, | ||
projection: projectionReducer | ||
}); | ||
|
||
export default globeReducer; | ||
|
||
export type GlobeState = ReturnType<typeof globeReducer>; | ||
|
||
export const globeStateSelector = (state: State): GlobeState => state.globe; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { | ||
SET_GLOBE_PROJECTION, | ||
GlobeProjection, | ||
SetGlobeProjectionAction | ||
} from '../../actions/set-globe-projection'; | ||
import {parseUrl} from '../../libs/globe-url-parameter'; | ||
import config from '../../config/main'; | ||
import {State} from '../index'; | ||
|
||
// get initial state from url or fallback to default state in config | ||
const globeState = parseUrl() || config.globe; | ||
const initialState = globeState.projection; | ||
|
||
function projectionReducer( | ||
state: GlobeProjection = initialState, | ||
action: SetGlobeProjectionAction | ||
): GlobeProjection { | ||
switch (action.type) { | ||
case SET_GLOBE_PROJECTION: | ||
return action.projection; | ||
default: | ||
return state; | ||
} | ||
} | ||
|
||
export function projectionSelector(state: State): GlobeProjection { | ||
return state.globe.projection; | ||
} | ||
|
||
export default projectionReducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {SET_GLOBE_VIEW, SetGlobeViewAction} from '../../actions/set-globe-view'; | ||
import GlobeView from '../../types/globe-view'; | ||
import {State} from '../index'; | ||
import {parseUrl} from '../../libs/globe-url-parameter'; | ||
import config from '../../config/main'; | ||
|
||
// get initial state from url or fallback to default state in config | ||
const globeState = parseUrl() || config.globe; | ||
const initialState = globeState.view; | ||
|
||
function globeViewReducer( | ||
state: GlobeView = initialState, | ||
action: SetGlobeViewAction | ||
): GlobeView { | ||
switch (action.type) { | ||
case SET_GLOBE_VIEW: | ||
return action.view; | ||
default: | ||
return state; | ||
} | ||
} | ||
|
||
export function globeViewSelector(state: State): GlobeView { | ||
return state.globe.view; | ||
} | ||
|
||
export default globeViewReducer; |