Skip to content

Commit

Permalink
feat(story-layer): add layer to story slide
Browse files Browse the repository at this point in the history
  • Loading branch information
KatvonRivia committed Dec 2, 2019
1 parent cdd2006 commit 77e3017
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 15 deletions.
17 changes: 17 additions & 0 deletions src/scripts/actions/set-story-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {StoryLayer} from '../types/story-layer';

export const SET_STORY_LAYER = 'SET_STORY_LAYER';

export interface SetStoryLayerAction {
type: typeof SET_STORY_LAYER;
storyLayer: StoryLayer | null;
}

const setStoryLayerAction = (
storyLayer: StoryLayer | null
): SetStoryLayerAction => ({
type: SET_STORY_LAYER,
storyLayer
});

export default setStoryLayerAction;
2 changes: 1 addition & 1 deletion src/scripts/components/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const TranslatedApp: FunctionComponent = () => {
<ProjectionMenu />
<LayerSelector />
</div>
<LayerLoader />
</Route>

<Route path="/present" exact>
Expand Down Expand Up @@ -96,6 +95,7 @@ const TranslatedApp: FunctionComponent = () => {
</div>
</IntlProvider>
<UrlSync />
<LayerLoader />
<Init />
</Router>
);
Expand Down
18 changes: 13 additions & 5 deletions src/scripts/components/globes/globes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ import {layerListItemSelector} from '../../selectors/layers/list-item';
import {globeViewSelector} from '../../selectors/globe/view';
import {timeSelector} from '../../selectors/globe/time';
import {projectionSelector} from '../../selectors/globe/projection';
import {flyToSelector} from '../../selectors/fly-to';
import {storyLayerSelector} from '../../selectors/story-layer';
import setGlobeViewAction from '../../actions/set-globe-view';
import Globe from '../globe/globe';
import {getLayerTileUrl} from '../../libs/get-layer-tile-url';
import {flyToSelector} from '../../selectors/fly-to';
import {State} from '../../reducers';
import {layerDetailsSelector} from '../../selectors/layers/layer-details';

import {GlobeView} from '../../types/globe-view';

import styles from './globes.styl';
import {layerDetailsSelector} from '../../selectors/layers/layer-details';

const Globes: FunctionComponent = () => {
const location = useLocation();
Expand All @@ -34,13 +35,15 @@ const Globes: FunctionComponent = () => {
const dispatch = useDispatch();
const projection = useSelector(projectionSelector);
const globalGlobeView = useSelector(globeViewSelector);

const storyLayer = useSelector(storyLayerSelector);
const mainLayerId = match?.params.mainLayerId;
const main = useSelector((state: State) =>
layerListItemSelector(state, mainLayerId)
);
const layerId = mainLayerId ? mainLayerId : storyLayer?.id;

const mainLayerDetails = useSelector((state: State) =>
layerDetailsSelector(state, mainLayerId)
layerDetailsSelector(state, layerId)
);

const compareLayerId = match?.params.compareLayerId;
Expand All @@ -51,7 +54,12 @@ const Globes: FunctionComponent = () => {
layerDetailsSelector(state, compareLayerId)
);

const time = useSelector(timeSelector);
let time = useSelector(timeSelector);

if (storyLayer) {
time = storyLayer.timestamp;
}

const [currentView, setCurrentView] = useState(globalGlobeView);
const [isMainActive, setIsMainActive] = useState(true);
const flyTo = useSelector(flyToSelector);
Expand Down
24 changes: 18 additions & 6 deletions src/scripts/components/layer-loader/layer-loader.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
import {FunctionComponent, useEffect} from 'react';
import {useSelector, useDispatch} from 'react-redux';
import {useParams} from 'react-router';
import {matchPath, useLocation} from 'react-router';

import fetchLayers from '../../actions/fetch-layers';
import fetchLayerAction from '../../actions/fetch-layer';
import {State} from '../../reducers';
import {layerDetailsSelector} from '../../selectors/layers/layer-details';
import {storyLayerSelector} from '../../selectors/story-layer';

/**
* Handles loading of layer list and layer details data
*/
const LayerLoader: FunctionComponent = () => {
const dispatch = useDispatch();
const {mainLayerId, compareLayerId} = useParams();
const location = useLocation();
const match = matchPath<{mainLayerId?: string; compareLayerId?: string}>(
location.pathname,
{
path: ['/layers/:mainLayerId?/:compareLayerId?', '/'],
exact: true
}
);
const mainLayerId = match?.params.mainLayerId;
const compareLayerId = match?.params.compareLayerId;
const storyLayer = useSelector(storyLayerSelector);
const layerId = mainLayerId ? mainLayerId : storyLayer?.id;
const mainLayerDetails = useSelector((state: State) =>
layerDetailsSelector(state, mainLayerId)
layerDetailsSelector(state, layerId)
);
const compareLayerDetails = useSelector((state: State) =>
layerDetailsSelector(state, compareLayerId)
Expand All @@ -27,16 +39,16 @@ const LayerLoader: FunctionComponent = () => {

// fetch layer if it is selected and not already downloaded
useEffect(() => {
if (mainLayerId && !mainLayerDetails) {
dispatch(fetchLayerAction(mainLayerId));
if (layerId && !mainLayerDetails) {
dispatch(fetchLayerAction(layerId));
}

if (compareLayerId && !compareLayerDetails) {
dispatch(fetchLayerAction(compareLayerId));
}
}, [
dispatch,
mainLayerId,
layerId,
mainLayerDetails,
compareLayerId,
compareLayerDetails
Expand Down
4 changes: 4 additions & 0 deletions src/scripts/components/story/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import fetchStory from '../../actions/fetch-story';
import {selectedStorySelector} from '../../selectors/story/selected';
import {storyListSelector} from '../../selectors/story/list';
import setFlyToAction from '../../actions/set-fly-to';
import setStoryLayerAction from '../../actions/set-story-layer';
import Slide from '../slide/slide';
import {State} from '../../reducers';
import config from '../../config/main';
Expand Down Expand Up @@ -69,9 +70,11 @@ const Story: FunctionComponent<Props> = ({mode}) => {
}, [dispatch, storyId]);

// fly to position given in a slide, if none given set to default
// set layer given by story slide
useEffect(() => {
if (slide) {
dispatch(setFlyToAction(slide.flyTo || defaultView));
dispatch(setStoryLayerAction(slide.layer || null));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch, slide]);
Expand All @@ -80,6 +83,7 @@ const Story: FunctionComponent<Props> = ({mode}) => {
useEffect(
() => () => {
dispatch(setFlyToAction(null));
dispatch(setStoryLayerAction(null));
},
[dispatch]
);
Expand Down
4 changes: 3 additions & 1 deletion src/scripts/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import layersReducer from './layers/index';
import storiesReducer from './story/index';
import globeReducer from './globe';
import flyToReducer from './fly-to';
import storyLayerReducer from './story-layer';

const rootReducer = combineReducers({
language: languageReducer,
layers: layersReducer,
stories: storiesReducer,
globe: globeReducer,
flyTo: flyToReducer
flyTo: flyToReducer,
storyLayer: storyLayerReducer
});

export default rootReducer;
Expand Down
17 changes: 17 additions & 0 deletions src/scripts/reducers/story-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {SET_STORY_LAYER, SetStoryLayerAction} from '../actions/set-story-layer';

import {StoryLayer} from '../types/story-layer';

function storyLayerReducer(
state: StoryLayer | null = null,
action: SetStoryLayerAction
): StoryLayer | null {
switch (action.type) {
case SET_STORY_LAYER:
return action.storyLayer;
default:
return state;
}
}

export default storyLayerReducer;
7 changes: 7 additions & 0 deletions src/scripts/selectors/story-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {State} from '../reducers/index';

import {StoryLayer} from '../types/story-layer';

export function storyLayerSelector(state: State): StoryLayer | null {
return state.storyLayer;
}
4 changes: 4 additions & 0 deletions src/scripts/types/story-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface StoryLayer {
id: string;
timestamp: number; // ISO 8601 timestamp
}
4 changes: 3 additions & 1 deletion src/scripts/types/story.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {GlobeView} from './globe-view';
import {StoryLayer} from './story-layer';

export interface Story {
id: string;
Expand All @@ -10,6 +11,7 @@ export interface Slide {
shortText?: string;
images?: [];
videoId?: string;
flyTo: GlobeView;
layer?: StoryLayer;
fullscreenGallery?: boolean;
flyTo: GlobeView;
}
6 changes: 5 additions & 1 deletion storage/stories/story3/story3-de.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
"shortText": "- Lorem ipsum\n\n- Exercitationem\n\n- sapiente",
"images": [
"https://storage.googleapis.com/esa-cfs-storage/stories/story3/assets/story3.jpeg"
]
],
"layer": {
"id": "sst",
"timestamp": "2008-01-03"
}
},
{
"text": "# Story title\n\n## This is a subheader\n\nExercitationem, sapiente. Praesentium quidem mollitia explicabo voluptatem aperiam deleniti ut sunt atque eaque, voluptate commodi in.",
Expand Down

0 comments on commit 77e3017

Please sign in to comment.