terriajs
Version:
Geospatial data visualization platform.
206 lines • 9.28 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import classNames from "classnames";
import { runInAction } from "mobx";
import { observer } from "mobx-react";
import { Component, createRef } from "react";
import { withTranslation } from "react-i18next";
import { useSwipeable } from "react-swipeable";
import { withTheme } from "styled-components";
import { Category, StoryAction } from "../../../Core/AnalyticEvents/analyticEvents";
import { animateEnd } from "../../../Core/animation";
import getPath from "../../../Core/getPath";
import TerriaError from "../../../Core/TerriaError";
import Box from "../../../Styled/Box";
import { withViewState } from "../../Context";
import { onStoryButtonClick } from "../../Map/MenuBar/StoryButton/StoryButton";
import Styles from "../story-panel.scss";
import StoryBody from "./StoryBody";
import FooterBar from "./StoryFooterBar";
import TitleBar from "./TitleBar";
import DragWrapper from "../../Drag/DragWrapper";
/**
*
* @param scene The story scene to activate
* @param terria The Terria instance
*/
export async function activateStory(scene, terria) {
terria.analytics?.logEvent(Category.story, StoryAction.viewScene, JSON.stringify(scene));
if (scene.shareData) {
const errors = [];
await Promise.all(scene.shareData.initSources.map(async (initSource) => {
try {
await terria.applyInitData({
initData: initSource,
replaceStratum: true,
canUnsetFeaturePickingState: true
});
}
catch (e) {
errors.push(TerriaError.from(e));
}
}));
if (errors.length > 0) {
terria.raiseErrorToUser(TerriaError.combine(errors, {
title: { key: "story.loadSceneErrorTitle" },
message: {
key: "story.loadSceneErrorMessage",
parameters: { title: scene.title ?? scene.id }
}
}));
}
}
terria.workbench.items.forEach((item) => {
terria.analytics?.logEvent(Category.story, StoryAction.datasetView, getPath(item));
});
}
const Swipeable = ({ children, ...props }) => {
const handlers = useSwipeable(props);
return _jsx("div", { ...handlers, children: children });
};
let StoryPanel = class StoryPanel extends Component {
keydownListener;
slideRef;
constructor(props) {
super(props);
this.state = {
isCollapsed: false,
inView: false
};
this.slideRef = createRef();
}
componentDidMount() {
const stories = this.props.viewState.terria.stories || [];
if (this.props.viewState.currentStoryId > stories.length - 1 ||
this.props.viewState.currentStoryId < 0) {
this.props.viewState.currentStoryId = 0;
}
this.activateStory(stories[this.props.viewState.currentStoryId]);
this.slideIn();
this.keydownListener = (e) => {
// Use else if for keydown events so only first one is recognised in case of multiple key presses
if (e.key === "Escape") {
this.exitStory();
}
else if (e.key === "ArrowRight" ||
e.key === "ArrowDown") {
if (this.props.viewState.currentStoryId + 1 !== stories.length) {
this.goToNextStory();
}
}
else if (e.key === "ArrowLeft" ||
e.key === "ArrowUp") {
if (this.props.viewState.currentStoryId !== 0) {
this.goToPrevStory();
}
}
};
window.addEventListener("keydown", this.keydownListener, true);
}
slideIn() {
this.setState({
inView: true
});
}
slideOut() {
this.setState({
inView: false
});
}
toggleCollapse() {
this.setState({
isCollapsed: !this.state.isCollapsed
});
}
onClickContainer() {
runInAction(() => {
this.props.viewState.topElement = "StoryPanel";
});
}
componentWillUnmount() {
if (this.keydownListener) {
window.removeEventListener("keydown", this.keydownListener, true);
}
}
navigateStory(index) {
if (index < 0) {
index = this.props.viewState.terria.stories.length - 1;
}
else if (index >= this.props.viewState.terria.stories.length) {
index = 0;
}
if (index !== this.props.viewState.currentStoryId) {
runInAction(() => {
this.props.viewState.currentStoryId = index;
});
if (index < (this.props.viewState.terria.stories || []).length) {
this.activateStory(this.props.viewState.terria.stories[index]);
}
}
}
// This is in StoryPanel and StoryBuilder
activateStory(_story) {
const story = _story ? _story : this.props.viewState.terria.stories[0];
activateStory(story, this.props.viewState.terria);
}
onCenterScene(story) {
activateStory(story, this.props.viewState.terria);
}
goToPrevStory() {
this.navigateStory(this.props.viewState.currentStoryId - 1);
}
goToNextStory() {
this.navigateStory(this.props.viewState.currentStoryId + 1);
}
exitStory() {
animateEnd(this.slideRef.current).finally(() => {
runInAction(() => {
this.props.viewState.storyShown = false;
});
this.props.viewState.terria.currentViewer.notifyRepaintRequired();
});
this.slideOut();
}
render() {
const stories = this.props.viewState.terria.stories || [];
const story = stories[this.props.viewState.currentStoryId];
if (!story) {
return null;
}
return (_jsx(DragWrapper, { handleSelector: ".drag-handle", style: {
bottom: this.props.viewState.terria.timelineStack.top !== undefined
? "146px"
: "80px",
left: "calc(50% - min(40%, 350px))",
width: "min(80%, 700px)"
}, children: _jsx(Box, { onClick: () => this.onClickContainer(), children: _jsxs(Box, { column: true, rounded: true, className: classNames(Styles.storyContainer, {
[Styles.isMounted]: this.state.inView
}), ref: this.slideRef, css: `
border-radius: 6px;
overflow: hidden;
`, children: [_jsx(Box, { backgroundColor: this.props.theme.dark, css: { color: "white", cursor: "move" }, paddedRatio: 3, column: true, className: "drag-handle", children: _jsx(TitleBar, { title: story.title, isCollapsed: this.state.isCollapsed, collapseHandler: () => this.toggleCollapse(), closeHandler: () => this.exitStory() }) }), _jsxs(Swipeable, { onSwipedLeft: () => this.goToNextStory(), onSwipedRight: () => this.goToPrevStory(), children: [_jsx(Box, { css: {
backgroundColor: "rgba(255, 255, 255, 0.85)",
backdropFilter: this.props.theme.blur
}, children: _jsx(StoryBody, { isCollapsed: this.state.isCollapsed, story: story }) }), _jsx(Box, { backgroundColor: this.props.theme.dark, css: { color: "white" }, paddedHorizontally: 3, fullWidth: true, children: _jsx(FooterBar, { goPrev: () => this.goToPrevStory(), goNext: () => this.goToNextStory(), jumpToStory: (index) => this.navigateStory(index), zoomTo: () => this.onCenterScene(story), currentHumanIndex: this.props.viewState.currentStoryId + 1, totalStories: stories.length, listStories: () => {
runInAction(() => {
this.props.viewState.storyShown = false;
});
onStoryButtonClick({
terria: this.props.viewState.terria,
theme: this.props.theme,
viewState: this.props.viewState,
animationDuration: 250
})();
} }) })] })] }, story.id) }) }));
}
};
StoryPanel = __decorate([
observer
], StoryPanel);
export default withTranslation()(withViewState(withTheme(StoryPanel)));
//# sourceMappingURL=StoryPanel.js.map